diff --git a/spring-boot-modules/spring-boot-microservices/README.md b/spring-boot-modules/spring-boot-microservices/README.md
new file mode 100644
index 0000000000..d2008c51fc
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/README.md
@@ -0,0 +1,13 @@
+--------------------------------- CustomerOrderApp installation steps----------------------------------
+
+1. Clone or download sample project from GitHub repo: https://github.com/eugenp/tutorials/tree/master/spring-boot-modules/customer-order-app
+2. Unzip project folder to local disk for example to: C:/baeldung-tutorials/customer-order-app
+3. Run `mvn clean install -DskipTests=true`
+4. Navigate to payment-service/payment-server module folder and type `mvn spring-boot:run`
+5. Open another CMD PROMPT window.
+ Navigate to order-service/order-server module folder and type `mvn spring-boot:run`
+6. Open another CMD PROMPT window.
+ Navigate to customer-service module folder and type `mvn spring-boot:run`
+
+7. Launch the Postman application from your machine and import the collection of POST requests located in the _postman_ folder
+
diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/.gitignore b/spring-boot-modules/spring-boot-microservices/customer-service/.gitignore
new file mode 100644
index 0000000000..0e9415ada6
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/customer-service/.gitignore
@@ -0,0 +1,41 @@
+#https://github.com/spring-projects/spring-boot/blob/master/.gitignore
+
+*#
+*.iml
+*.ipr
+*.iws
+*.jar
+*.sw?
+*~
+.#*
+.*.md.html
+.DS_Store
+.classpath
+.factorypath
+.gradle
+.idea
+.metadata
+.project
+.recommenders
+.settings
+.springBeans
+/build
+/code
+MANIFEST.MF
+_site/
+activemq-data
+bin
+build
+build.log
+dependency-reduced-pom.xml
+dump.rdb
+interpolated*.xml
+lib/
+manifest.yml
+overridedb.*
+target
+transaction-logs
+.flattened-pom.xml
+secrets.yml
+.gradletasknamecache
+.sts4-cache
diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/pom.xml b/spring-boot-modules/spring-boot-microservices/customer-service/pom.xml
new file mode 100644
index 0000000000..a02ce2e1d8
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/customer-service/pom.xml
@@ -0,0 +1,85 @@
+
+
+
+ CustomerOrderApp
+ com.baeldung
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ com.baeldung.customerservice
+ customer-service
+ jar
+
+
+ 1.8
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 2.3.0.RELEASE
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-json
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+
+
+ junit
+ junit
+ test
+
+
+ com.baeldung.orderservice
+ order-client
+ 1.0-SNAPSHOT
+ compile
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+ exec
+
+
+
+
+
+
+
+
diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/Customer.java b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/Customer.java
new file mode 100644
index 0000000000..7d10510cbc
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/Customer.java
@@ -0,0 +1,14 @@
+package com.baeldung.customerservice;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class Customer {
+
+ private int id;
+ private String firstName;
+ private String lastName;
+
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerApplication.java b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerApplication.java
new file mode 100644
index 0000000000..489129a3d2
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerApplication.java
@@ -0,0 +1,25 @@
+package com.baeldung.customerservice;
+
+import com.baeldung.orderservice.client.OrderClient;
+import com.baeldung.orderservice.client.OrderClientImpl;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * Spring Boot application starter class
+ */
+@SpringBootApplication
+public class CustomerApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(CustomerApplication.class, args);
+ }
+
+ @Bean
+ public OrderClient getOrderClient() {
+
+ return new OrderClientImpl(new RestTemplateBuilder());
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerService.java b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerService.java
new file mode 100644
index 0000000000..ab8872de1c
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/java/com/baeldung/customerservice/CustomerService.java
@@ -0,0 +1,56 @@
+package com.baeldung.customerservice;
+
+import com.baeldung.orderservice.client.OrderClient;
+import com.baeldung.orderservice.client.OrderDTO;
+import com.baeldung.orderservice.client.OrderResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+public class CustomerService {
+
+ @Autowired
+ private OrderClient orderClient;
+
+ private List customers = Arrays.asList(
+
+ new Customer(1, "John", "Smith"),
+ new Customer(2, "Deny", "Dominic"));
+
+
+ @GetMapping
+ public List getAllCustomers() {
+ return customers;
+ }
+
+ @GetMapping("/{id}")
+ public Customer getCustomerById(@PathVariable int id) {
+ return customers.stream()
+ .filter(customer -> customer.getId() == id)
+ .findFirst()
+ .orElseThrow(IllegalArgumentException::new);
+ }
+
+
+ @PostMapping(value = "/order")
+ public String sendOrder(@RequestBody Map body) {
+
+ OrderDTO dto = new OrderDTO();
+ dto.setCustomerId((Integer) body.get("customerId"));
+ dto.setItemId((String) body.get("itemId"));
+
+ OrderResponse response = orderClient.order(dto);
+
+ return response.getStatus();
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/resources/application.properties
new file mode 100644
index 0000000000..d439ae9b76
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+#Spring Boot server configuration
+server.servlet.context-path=/customer-service
+server.port=8001
+
diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/test/java/com/baeldung/customerservice/CustomerServiceTest.java b/spring-boot-modules/spring-boot-microservices/customer-service/src/test/java/com/baeldung/customerservice/CustomerServiceTest.java
new file mode 100644
index 0000000000..1c44146811
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/test/java/com/baeldung/customerservice/CustomerServiceTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.customerservice;
+
+import com.baeldung.orderservice.client.OrderClient;
+import com.baeldung.orderservice.client.OrderDTO;
+import com.baeldung.orderservice.client.OrderResponse;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = CustomerApplication.class)
+public class CustomerServiceTest {
+
+ @Autowired
+ private OrderClient orderClient;
+
+ @Test
+ public void testAddOrderSuccess(){
+
+
+ OrderDTO dto = new OrderDTO(2,"A152");
+
+ OrderResponse response = orderClient.order(dto);
+
+ Assert.assertNotNull("Order Id not generated", response.getOrderId());
+ Assert.assertEquals("A152", response.getProductId());
+ Assert.assertEquals("CREATED", response.getStatus());
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-microservices/customer-service/src/test/resources/application.properties b/spring-boot-modules/spring-boot-microservices/customer-service/src/test/resources/application.properties
new file mode 100644
index 0000000000..1d50559005
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/customer-service/src/test/resources/application.properties
@@ -0,0 +1,2 @@
+local.server.port=8001
+server.servlet.context-path=/customer-service
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/.gitignore b/spring-boot-modules/spring-boot-microservices/order-service/.gitignore
new file mode 100644
index 0000000000..0e9415ada6
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/.gitignore
@@ -0,0 +1,41 @@
+#https://github.com/spring-projects/spring-boot/blob/master/.gitignore
+
+*#
+*.iml
+*.ipr
+*.iws
+*.jar
+*.sw?
+*~
+.#*
+.*.md.html
+.DS_Store
+.classpath
+.factorypath
+.gradle
+.idea
+.metadata
+.project
+.recommenders
+.settings
+.springBeans
+/build
+/code
+MANIFEST.MF
+_site/
+activemq-data
+bin
+build
+build.log
+dependency-reduced-pom.xml
+dump.rdb
+interpolated*.xml
+lib/
+manifest.yml
+overridedb.*
+target
+transaction-logs
+.flattened-pom.xml
+secrets.yml
+.gradletasknamecache
+.sts4-cache
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/pom.xml b/spring-boot-modules/spring-boot-microservices/order-service/order-client/pom.xml
new file mode 100644
index 0000000000..22176bb85e
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+
+ com.baeldung.orderservice
+ order-service
+ 1.0-SNAPSHOT
+
+ order-client
+ com.baeldung.orderservice
+ order-client
+ Order service client module
+ http://projects.spring.io/spring-boot/
+
+
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClient.java b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClient.java
new file mode 100644
index 0000000000..2dd6b13248
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClient.java
@@ -0,0 +1,6 @@
+package com.baeldung.orderservice.client;
+
+public interface OrderClient {
+
+ OrderResponse order(OrderDTO orderDTO);
+}
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClientImpl.java b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClientImpl.java
new file mode 100644
index 0000000000..70ec77fab6
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderClientImpl.java
@@ -0,0 +1,35 @@
+package com.baeldung.orderservice.client;
+
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+
+@Component
+public class OrderClientImpl implements OrderClient {
+
+ private RestTemplate restTemplate;
+
+ public OrderClientImpl(RestTemplateBuilder builder) {
+
+ this.restTemplate = builder.build();
+ }
+
+ @Override
+ public OrderResponse order(OrderDTO orderDTO) {
+
+ String serviceUrl = "http://localhost:8002/order-service";
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+
+ HttpEntity request = new HttpEntity<>(orderDTO, headers);
+
+ OrderResponse orderResponse = restTemplate.postForObject(serviceUrl + "/create", request, OrderResponse.class);
+
+ return orderResponse;
+
+ }
+}
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderDTO.java b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderDTO.java
new file mode 100644
index 0000000000..c31c9f6bec
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderDTO.java
@@ -0,0 +1,16 @@
+package com.baeldung.orderservice.client;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderDTO {
+
+ private int customerId;
+ private String itemId;
+
+}
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderResponse.java b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderResponse.java
new file mode 100644
index 0000000000..e8d2059cbb
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/java/com/baeldung/orderservice/client/OrderResponse.java
@@ -0,0 +1,15 @@
+package com.baeldung.orderservice.client;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class OrderResponse {
+
+ private int orderId;
+ private String productId;
+ private String status;
+}
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/resources/application.properties
new file mode 100644
index 0000000000..53e503689f
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-client/src/main/resources/application.properties
@@ -0,0 +1 @@
+server.port=8002
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/pom.xml b/spring-boot-modules/spring-boot-microservices/order-service/order-server/pom.xml
new file mode 100644
index 0000000000..722bfa5aac
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/pom.xml
@@ -0,0 +1,29 @@
+
+
+
+ order-service
+ com.baeldung.orderservice
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ com.baeldung.orderservice
+ order-server
+
+
+ com.baeldung.orderservice
+ order-client
+ 1.0-SNAPSHOT
+ compile
+
+
+ com.baeldung.paymentservice
+ payment-client
+ 1.0-SNAPSHOT
+ compile
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/Order.java b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/Order.java
new file mode 100644
index 0000000000..719305064f
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/Order.java
@@ -0,0 +1,18 @@
+package com.baeldung.orderservice;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Order {
+
+ private Integer id;
+ private Integer customerId;
+ private String itemId;
+ private String date;
+
+}
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderApplication.java b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderApplication.java
new file mode 100644
index 0000000000..2d09479a57
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderApplication.java
@@ -0,0 +1,24 @@
+package com.baeldung.orderservice;
+
+import com.baeldung.paymentservice.PaymentClient;
+import com.baeldung.paymentservice.PaymentClientImpl;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+
+/**
+ * Spring Boot application starter class
+ */
+@SpringBootApplication
+public class OrderApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(OrderApplication.class, args);
+ }
+
+ @Bean
+ public PaymentClient getPaymentClient() {
+
+ return new PaymentClientImpl(new RestTemplateBuilder());
+ }
+}
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderService.java b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderService.java
new file mode 100644
index 0000000000..5ad66e1052
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/java/com/baeldung/orderservice/OrderService.java
@@ -0,0 +1,75 @@
+package com.baeldung.orderservice;
+
+import com.baeldung.orderservice.client.OrderDTO;
+import com.baeldung.orderservice.client.OrderResponse;
+import com.baeldung.paymentservice.PaymentClient;
+import com.baeldung.paymentservice.PaymentDTO;
+import com.baeldung.paymentservice.PaymentResponse;
+import org.apache.commons.lang.time.DateFormatUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@RestController
+public class OrderService {
+
+ @Autowired
+ private PaymentClient paymentClient;
+
+ private List orders = Arrays.asList(
+
+ new Order(1, 1, "A101", "2020/02/14"),
+ new Order(2, 1, "A101", "2020/02/14"),
+ new Order(3, 2, "A150", "2020/02/17"));
+
+ @GetMapping
+ public List getAllOrders() {
+ return orders;
+ }
+
+ @GetMapping("/{id}")
+ public List getOrdersByCustomer(@PathVariable int id) {
+ return orders.stream()
+ .filter(order -> order.getCustomerId() == id).collect(Collectors.toList());
+ }
+
+ @PostMapping("/create")
+ public OrderResponse createOrder(@RequestBody OrderDTO request) {
+
+ int lastIndex = orders.size();
+ Order order = new Order();
+ order.setId(lastIndex + 1);
+ order.setCustomerId(request.getCustomerId());
+ order.setItemId(request.getItemId());
+ String date = DateFormatUtils.format(new Date(), "yyyy/MM/dd");
+ order.setDate(date);
+
+ return new OrderResponse(order.getId(), order.getItemId(), "CREATED");
+ }
+
+ @PostMapping("/pay/{orderNumber}")
+ public PaymentResponse sendPayment(@PathVariable String orderNumber, @RequestBody Map body) {
+
+ PaymentDTO dto = new PaymentDTO();
+ dto.setFirstName((String) body.get("firstName"));
+ dto.setLastName((String) body.get("lastName"));
+ dto.setCardNumber((String) body.get("cardNumber"));
+ dto.setAmount((Double) body.get("amount"));
+ dto.setCurrency((String) body.get("currency"));
+
+ PaymentResponse paymentResponse = paymentClient.pay(orderNumber, dto);
+
+ return paymentResponse;
+
+ }
+}
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/resources/application.properties
new file mode 100644
index 0000000000..f4fe5e7079
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/main/resources/application.properties
@@ -0,0 +1,4 @@
+#Spring Boot server configuration
+server.servlet.context-path=/order-service
+server.port=8002
+
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/test/java/com/baeldung/orderservice/OrderServiceTest.java b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/test/java/com/baeldung/orderservice/OrderServiceTest.java
new file mode 100644
index 0000000000..2630f908be
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/order-server/src/test/java/com/baeldung/orderservice/OrderServiceTest.java
@@ -0,0 +1,35 @@
+package com.baeldung.orderservice;
+
+import com.baeldung.paymentservice.PaymentClient;
+import com.baeldung.paymentservice.PaymentDTO;
+import com.baeldung.paymentservice.PaymentResponse;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = OrderApplication.class)
+public class OrderServiceTest {
+
+ @Autowired
+ private PaymentClient paymentClient;
+
+
+ @Test
+ public void testSendPaySuccess(){
+
+
+ PaymentDTO dto = new PaymentDTO("Sasa","Milenkovic","4260-6720-3283-7081",150.0,"USD");
+
+ PaymentResponse response = paymentClient.pay("A152", dto);
+
+ Assert.assertNotNull("Payment Id not generated", response.getPaymentId());
+ Assert.assertEquals("CREDITCARD", response.getPaymentMethod());
+ Assert.assertEquals("Sasa Milenkovic", response.getCustomerFullName());
+ Assert.assertEquals(new Double(150.0), response.getAmount());
+ Assert.assertEquals("USD", response.getCurrency());
+ }
+}
diff --git a/spring-boot-modules/spring-boot-microservices/order-service/pom.xml b/spring-boot-modules/spring-boot-microservices/order-service/pom.xml
new file mode 100644
index 0000000000..603b845cef
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/order-service/pom.xml
@@ -0,0 +1,108 @@
+
+
+
+ CustomerOrderApp
+ com.baeldung
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ com.baeldung.orderservice
+ order-service
+ pom
+
+ order-client
+ order-server
+
+
+
+ 1.8
+ 2.6
+ 1.8
+ 1.8
+ UTF-8
+ com.baeldung.orderservice.OrderApplication
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 2.3.0.RELEASE
+ pom
+ import
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ commons-lang
+ commons-lang
+ ${commons-lang.version}
+
+
+ org.springframework.boot
+ spring-boot-starter-json
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+
+
+ org.springframework.boot
+ spring-boot-test-autoconfigure
+ test
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ ${orderservice.mainclass}
+
+
+
+
+ repackage
+
+
+ exe
+
+
+
+ start-application
+
+ com.baeldung.orderservice.OrderApplication
+ ../order-server/target/classes
+
+
+ start
+
+
+
+
+
+
+
+
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/.gitignore b/spring-boot-modules/spring-boot-microservices/payment-service/.gitignore
new file mode 100644
index 0000000000..0e9415ada6
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/.gitignore
@@ -0,0 +1,41 @@
+#https://github.com/spring-projects/spring-boot/blob/master/.gitignore
+
+*#
+*.iml
+*.ipr
+*.iws
+*.jar
+*.sw?
+*~
+.#*
+.*.md.html
+.DS_Store
+.classpath
+.factorypath
+.gradle
+.idea
+.metadata
+.project
+.recommenders
+.settings
+.springBeans
+/build
+/code
+MANIFEST.MF
+_site/
+activemq-data
+bin
+build
+build.log
+dependency-reduced-pom.xml
+dump.rdb
+interpolated*.xml
+lib/
+manifest.yml
+overridedb.*
+target
+transaction-logs
+.flattened-pom.xml
+secrets.yml
+.gradletasknamecache
+.sts4-cache
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/pom.xml b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/pom.xml
new file mode 100644
index 0000000000..19c1bb7e39
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+ payment-service
+ com.baeldung.paymentservice
+ 1.0-SNAPSHOT
+
+
+
+ com.baeldung.paymentservice
+ payment-client
+
+
+
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClient.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClient.java
new file mode 100644
index 0000000000..f9e24725b8
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClient.java
@@ -0,0 +1,6 @@
+package com.baeldung.paymentservice;
+
+public interface PaymentClient {
+
+ PaymentResponse pay (String orderNumber, PaymentDTO paymentDTO);
+}
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClientImpl.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClientImpl.java
new file mode 100644
index 0000000000..87609b098e
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentClientImpl.java
@@ -0,0 +1,35 @@
+package com.baeldung.paymentservice;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class PaymentClientImpl implements PaymentClient {
+
+ private RestTemplate restTemplate;
+
+ public PaymentClientImpl(RestTemplateBuilder builder) {
+
+ this.restTemplate = builder.build();
+ }
+
+ @Override
+ public PaymentResponse pay(String orderNumber, PaymentDTO paymentDTO) {
+
+ String serviceUrl = "http://localhost:8003/payment-service";
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.APPLICATION_JSON);
+
+ HttpEntity request = new HttpEntity<>(paymentDTO, headers);
+
+ PaymentResponse paymentResponse = restTemplate.postForObject(serviceUrl + "/pay/" + orderNumber, request, PaymentResponse.class);
+
+ return paymentResponse;
+
+ }
+}
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentDTO.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentDTO.java
new file mode 100644
index 0000000000..cd81b78366
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentDTO.java
@@ -0,0 +1,17 @@
+package com.baeldung.paymentservice;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PaymentDTO {
+
+ private String firstName;
+ private String lastName;
+ private String cardNumber;
+ private double amount;
+ private String currency;
+}
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentResponse.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentResponse.java
new file mode 100644
index 0000000000..4a155d4571
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/java/com.baeldung.paymentservice/PaymentResponse.java
@@ -0,0 +1,18 @@
+package com.baeldung.paymentservice;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PaymentResponse{
+
+ private String paymentId;
+ private String paymentMethod;
+ private String customerFullName;
+ private Double amount;
+ private String currency;
+
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/payment-service/payment-client/src/main/resources/application.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/pom.xml b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/pom.xml
new file mode 100644
index 0000000000..eb429553dd
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/pom.xml
@@ -0,0 +1,22 @@
+
+
+ 4.0.0
+
+
+ com.baeldung.paymentservice
+ payment-service
+ 1.0-SNAPSHOT
+
+ com.baeldung.paymentservice
+ payment-server
+ payment-server
+
+
+ com.baeldung.paymentservice
+ payment-client
+ 1.0-SNAPSHOT
+ compile
+
+
+
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/CardValidator.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/CardValidator.java
new file mode 100644
index 0000000000..e4f0a3a68a
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/CardValidator.java
@@ -0,0 +1,31 @@
+package com.baeldung.paymentservice;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CardValidator {
+
+ public static boolean validate(String cardNumber){
+
+ boolean isValid = false;
+
+ String regex = "^(?:(?4[0-9]{12}(?:[0-9]{3})?)|" +
+ "(?5[1-5][0-9]{14})|" +
+ "(?6(?:011|5[0-9]{2})[0-9]{12})|" +
+ "(?3[47][0-9]{13})|" +
+ "(?3(?:0[0-5]|[68][0-9])?[0-9]{11})|" +
+ "(?(?:2131|1800|35[0-9]{3})[0-9]{11}))$";
+
+
+ Pattern pattern = Pattern.compile(regex);
+ cardNumber = cardNumber.replaceAll("-", "");
+ Matcher matcher = pattern.matcher(cardNumber);
+
+ if(matcher.matches()){
+
+ isValid = true;
+ }
+
+ return isValid;
+ }
+}
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/Payment.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/Payment.java
new file mode 100644
index 0000000000..9789195c98
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/Payment.java
@@ -0,0 +1,19 @@
+package com.baeldung.paymentservice;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Payment {
+
+ private String paymentId;
+ private String paymentMethod;
+ private String customerFullName;
+ private double amount;
+ private String currency;
+
+}
+
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentApplication.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentApplication.java
new file mode 100644
index 0000000000..0e9336dcfe
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentApplication.java
@@ -0,0 +1,15 @@
+package com.baeldung.paymentservice;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ *
+ * Spring Boot application starter class
+ */
+@SpringBootApplication
+public class PaymentApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(PaymentApplication.class, args);
+ }
+}
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentService.java b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentService.java
new file mode 100644
index 0000000000..f44e342cd7
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/java/com/baeldung/paymentservice/PaymentService.java
@@ -0,0 +1,39 @@
+package com.baeldung.paymentservice;
+
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.smartcardio.CardException;
+import java.util.UUID;
+
+
+@RestController
+public class PaymentService {
+
+
+ @PostMapping("/pay/{orderNum}")
+ public PaymentResponse createPayment(@PathVariable String orderNum, @RequestBody PaymentDTO paymentDTO) {
+
+ Payment payment = new Payment();
+ payment.setPaymentId(UUID.randomUUID().toString().replace("-", ""));
+ String firstName = paymentDTO.getFirstName();
+ String lastName = paymentDTO.getLastName();
+ payment.setCustomerFullName(firstName + " " + lastName);
+ String cardNumber = paymentDTO.getCardNumber();
+
+ if(CardValidator.validate(cardNumber)){
+ payment.setPaymentMethod("CREDITCARD");
+ } else try {
+ throw new CardException("Card with number:"+ cardNumber + " is invalid");
+ } catch (CardException e) {
+ e.printStackTrace();
+ }
+ payment.setAmount(paymentDTO.getAmount());
+ payment.setCurrency(paymentDTO.getCurrency());
+
+ return new PaymentResponse(payment.getPaymentId(), payment.getPaymentMethod(), payment.getCustomerFullName(), payment.getAmount(), payment.getCurrency());
+
+ }
+}
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/resources/application.properties b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/resources/application.properties
new file mode 100644
index 0000000000..8f3550946e
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/payment-server/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+#Spring Boot server configuration
+server.servlet.context-path=/payment-service
+server.port=8003
diff --git a/spring-boot-modules/spring-boot-microservices/payment-service/pom.xml b/spring-boot-modules/spring-boot-microservices/payment-service/pom.xml
new file mode 100644
index 0000000000..474ab6fe93
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/payment-service/pom.xml
@@ -0,0 +1,110 @@
+
+
+
+ CustomerOrderApp
+ com.baeldung
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ com.baeldung.paymentservice
+ payment-service
+ pom
+
+ payment-client
+ payment-server
+
+
+
+ 1.8
+ 2.6
+ 1.8
+ 1.8
+ UTF-8
+ com.baeldung.paymentservice.PaymentApplication
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 2.3.0.RELEASE
+ pom
+ import
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ commons-lang
+ commons-lang
+ ${commons-lang.version}
+
+
+
+ org.springframework.boot
+ spring-boot-starter-json
+
+
+
+ org.springframework.boot
+ spring-boot-test
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-test-autoconfigure
+ test
+
+
+ junit
+ junit
+ test
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ ${paymentservice.mainclass}
+
+
+
+
+ repackage
+
+
+ exe
+
+
+
+ start-application
+
+ com.baeldung.paymentservice.PaymentApplication
+ ../payment-server/target/classes
+
+
+ start
+
+
+
+
+
+
+
+
diff --git a/spring-boot-modules/spring-boot-microservices/pom.xml b/spring-boot-modules/spring-boot-microservices/pom.xml
new file mode 100644
index 0000000000..1cdd7595d4
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/pom.xml
@@ -0,0 +1,46 @@
+
+ 4.0.0
+ com.baeldung
+ CustomerOrderApp
+ pom
+ 1.0-SNAPSHOT
+ CustomerOrderApp
+ http://maven.apache.org
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.3.0.RELEASE
+
+
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+ customer-service
+ order-service
+ payment-service
+
+
+
+
+ org.projectlombok
+ lombok
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
+
+
diff --git a/spring-boot-modules/spring-boot-microservices/postman/customer-order.postman_collection b/spring-boot-modules/spring-boot-microservices/postman/customer-order.postman_collection
new file mode 100644
index 0000000000..aa9960aead
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/postman/customer-order.postman_collection
@@ -0,0 +1,87 @@
+{
+ "info": {
+ "_postman_id": "92594398-49cc-4a7c-b44f-1037307afbd3",
+ "name": "postman-requests",
+ "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
+ },
+ "item": [
+ {
+ "name": "Crete new Customer order",
+ "request": {
+ "method": "POST",
+ "header": [
+ {
+ "key": "Content-Type",
+ "value": "multipart/form-data",
+ "type": "text",
+ "disabled": true
+ },
+ {
+ "key": "Accept-Charset",
+ "value": "utf-8",
+ "type": "text",
+ "disabled": true
+ },
+ {
+ "key": "boundary",
+ "value": "nAp4nMEt-BuGuuLlq-6fnASQErGjSamaG",
+ "type": "text",
+ "disabled": true
+ }
+ ],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n \"customerId\":2,\n \"itemId\":\"A152\"\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "http://localhost:8001/customer-service/order",
+ "protocol": "http",
+ "host": [
+ "localhost"
+ ],
+ "port": "8001",
+ "path": [
+ "customer-service",
+ "order"
+ ]
+ }
+ },
+ "response": []
+ },
+ {
+ "name": "Send Order for payment",
+ "request": {
+ "method": "POST",
+ "header": [],
+ "body": {
+ "mode": "raw",
+ "raw": "{\n\t\n\"firstName\":\"John\",\n\"lastName\":\"Smith\",\n\"cardNumber\":\"4260-6720-3283-7081\",\n\"amount\":150.0,\n\"currency\":\"USD\"\n\t\n\t\n}",
+ "options": {
+ "raw": {
+ "language": "json"
+ }
+ }
+ },
+ "url": {
+ "raw": "localhost:8002/order-service/pay/A152",
+ "host": [
+ "localhost"
+ ],
+ "port": "8002",
+ "path": [
+ "order-service",
+ "pay",
+ "A152"
+ ]
+ }
+ },
+ "response": []
+ }
+ ],
+ "protocolProfileBehavior": {}
+}
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-microservices/src/main/java/com/baeldung/CustomerOrderApp.java b/spring-boot-modules/spring-boot-microservices/src/main/java/com/baeldung/CustomerOrderApp.java
new file mode 100644
index 0000000000..15455ca16c
--- /dev/null
+++ b/spring-boot-modules/spring-boot-microservices/src/main/java/com/baeldung/CustomerOrderApp.java
@@ -0,0 +1,23 @@
+package com.baeldung;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+/**
+ * Customer Order Spring Boot Main Application
+ *
+ * */
+
+@SpringBootApplication
+@ComponentScan(basePackages = "com.baeldung.*")
+public class CustomerOrderApp
+{
+
+ public static void main( String[] args )
+ {
+
+ SpringApplication.run(CustomerOrderApp.class,args);
+
+ }
+}