Microservices - Utility Payment Service Implementation
Chinthaka Dinadasa
- 10 Nov, 2021

Hello readers, here is the latest article onBuilding Microservices With Spring Boot – Free Course With Practical Project which focuses on utility payment service implementation which enables users to process utility payments through internet banking solution microservices.
Here I’ll cover only limited functionality includes placing utility payments and reading placed utility payments from DB.
Developing Utility Payment Service
Just create another spring boot application usingSpring Initializr with the following dependencies,
- Spring Web
- Lombok
- Spring Data JPA
- MySQL
- Eureka Discovery Client
Create Spring Boot Project For Utility Payments Service Using Spring Initializr
Database Models
Here I’m going to store the utility payments summary with the status of a process in a single table.
package com.javatodev.finance.model;public enum TransactionStatus { PENDING, PROCESSING, SUCCESS, FAILED}
package com.javatodev.finance.model.entity;import com.javatodev.finance.model.TransactionStatus;import lombok.Getter;import lombok.Setter;import javax.persistence.*;import java.math.BigDecimal;@Getter@Setter@Entity@Table(name = "utility_payment")public class UtilityPaymentEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private Long providerId; private BigDecimal amount; private String referenceNumber; private String account; private String transactionId; @Enumerated(EnumType.STRING) private TransactionStatus status;}
Repository Layer
package com.javatodev.finance.repository;import com.javatodev.finance.model.dto.UtilityPayment;import com.javatodev.finance.model.entity.UtilityPaymentEntity;import org.springframework.data.jpa.repository.JpaRepository;public interface UtilityPaymentRepository extends JpaRepository<UtilityPaymentEntity, UtilityPayment> {}
DTO, Mapper, and REST Request and Responses
Here I’m going to use a separate DTO layer to bring data from this core service to the public over the API. Basically here I’ll not go to expose my entity layer, instead of that I’ll define the DTO layer to bring in and out data from this API.
package com.javatodev.finance.model.dto;import com.javatodev.finance.model.TransactionStatus;import lombok.Data;import java.math.BigDecimal;@Datapublic class UtilityPayment { private Long providerId; private BigDecimal amount; private String referenceNumber; private String account; private TransactionStatus status;}
Create utility payment request to bind incoming data from API,
package com.javatodev.finance.rest.request;import lombok.Data;import java.math.BigDecimal;@Datapublic class UtilityPaymentRequest { private Long providerId; private BigDecimal amount; private String referenceNumber; private String account;}
UtilityPaymentResponse to map response from API after processing utility payment.
package com.javatodev.finance.rest.response;import lombok.Data;@Datapublic class UtilityPaymentResponse { private String message; private String transactionId;}
Mapper class to map DTO -> Entity and vice versa,
package com.javatodev.finance.model.mapper;import java.util.Collection;import java.util.List;import java.util.Set;import java.util.stream.Collectors;public abstract class BaseMapper<E, D> { public abstract E convertToEntity(D dto,Object...args); public abstract D convertToDto(E entity,Object...args); public Collection<E> convertToEntity(Collection<D>dto,Object...args) { return dto.stream().map(d-> convertToEntity(d, args)).collect(Collectors.toList()); } public Collection<D> convertToDto(Collection<E>entity,Object...args) { return entity.stream().map(e-> convertToDto(e, args)).collect(Collectors.toList()); } public List<E> convertToEntityList(Collection<D>dto,Object...args) { return convertToEntity(dto, args).stream().collect(Collectors.toList()); } public List<D> convertToDtoList(Collection<E>entity,Object...args) { return convertToDto(entity, args).stream().collect(Collectors.toList()); } public Set<E> convertToEntitySet(Collection<D>dto,Object...args) { return convertToEntity(dto, args).stream().collect(Collectors.toSet()); } public Set<D> convertToDtoSet(Collection<E>entity,Object...args) { return convertToDto(entity, args).stream().collect(Collectors.toSet()); }}
package com.javatodev.finance.model.mapper;import com.javatodev.finance.model.dto.UtilityPayment;import com.javatodev.finance.model.entity.UtilityPaymentEntity;import org.springframework.beans.BeanUtils;public class UtilityPaymentMapper extends BaseMapper<UtilityPaymentEntity, UtilityPayment> { @Override public UtilityPaymentEntity convertToEntity(UtilityPayment dto,Object...args) { UtilityPaymentEntity entity = new UtilityPaymentEntity(); if (dto!= null) { BeanUtils.copyProperties(dto, entity); } return entity; } @Override public UtilityPayment convertToDto(UtilityPaymentEntity entity,Object...args) { UtilityPayment dto = new UtilityPayment(); if (entity!= null) { BeanUtils.copyProperties(entity, dto); } return dto; }}
Now we have all the components in order to place a utility payment in the database and read those when needed. Let’s focus on creating a utility payments service from here,
Utility Payments Service
In this service implementation, I’m going to explain how we could save all the utility payments requests in the local database.But here there is one more thing which should be present which is building communication with the core banking system, Which I’ll explain in the next article in this series.
package com.javatodev.finance.service;import com.javatodev.finance.model.TransactionStatus;import com.javatodev.finance.model.dto.UtilityPayment;import com.javatodev.finance.model.entity.UtilityPaymentEntity;import com.javatodev.finance.model.mapper.UtilityPaymentMapper;import com.javatodev.finance.repository.UtilityPaymentRepository;import com.javatodev.finance.rest.request.UtilityPaymentRequest;import com.javatodev.finance.rest.response.UtilityPaymentResponse;import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.BeanUtils;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.stereotype.Service;import java.util.List;import java.util.UUID;@Slf4j@Service@RequiredArgsConstructorpublic class UtilityPaymentService { private final UtilityPaymentRepository utilityPaymentRepository; private UtilityPaymentMapper utilityPaymentMapper= new UtilityPaymentMapper(); public UtilityPaymentResponse utilPayment(UtilityPaymentRequest paymentRequest) { log.info("Utility payment processing {}",paymentRequest.toString()); UtilityPaymentEntity entity = new UtilityPaymentEntity(); BeanUtils.copyProperties(paymentRequest, entity); entity.setStatus(TransactionStatus.PROCESSING); UtilityPaymentEntity optUtilPayment = utilityPaymentRepository.save(entity); String transactionId = UUID.randomUUID().toString(); optUtilPayment.setStatus(TransactionStatus.SUCCESS); optUtilPayment.setTransactionId(transactionId); utilityPaymentRepository.save(optUtilPayment); return UtilityPaymentResponse.builder().message("Utility Payment Successfully Processed").transactionId(transactionId).build(); } public List<UtilityPayment> readPayments(Pageable pageable) { Page<UtilityPaymentEntity>allUtilPayments = utilityPaymentRepository.findAll(pageable); return utilityPaymentMapper.convertToDtoList(allUtilPayments.getContent()); }}
Controller Layer
Here we are exposing 2 endpoints in order to place utility payments and read all placed payments in the database.
package com.javatodev.finance.controller;import com.javatodev.finance.rest.request.UtilityPaymentRequest;import com.javatodev.finance.service.UtilityPaymentService;import lombok.RequiredArgsConstructor;import org.springframework.data.domain.Pageable;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.*;@RestController@RequiredArgsConstructor@RequestMapping(value = "/api/v1/utility-payment")public class UtilityPaymentController { private final UtilityPaymentService utilityPaymentService; @GetMapping public ResponseEntity readPayments(Pageable pageable) { return ResponseEntity.ok(utilityPaymentService.readPayments(pageable)); } @PostMapping public ResponseEntity processPayment(@RequestBody UtilityPaymentRequest paymentRequest) { return ResponseEntity.ok(utilityPaymentService.utilPayment(paymentRequest)); }}
All done for basic utility payments service and let’s configure application configurations as below,
server: port:8085spring: application: name:internet-banking-utility-payment-service datasource: url:jdbc:mysql://localhost:3306/banking_core_utility_payment_service username:root password:password jpa: hibernate: ddl-auto:updateeureka: client: service-url: defaultZone:http://localhost:8081/eurekainfo: app: name:${spring.application.name}server: port:8085spring: application: name:internet-banking-utility-payment-service datasource: url:jdbc:mysql://localhost:3306/banking_core_utility_payment_service username:root password:password jpa: hibernate: ddl-auto:updateeureka: client: service-url: defaultZone:http://localhost:8081/eurekainfo: app: name:${spring.application.name}
Then there is one more thing to do in the API gateway we developed earlier inMicroservices – Setup API Gateway Using Spring Cloud Gateway, Just add the following route definition to the API gateway in order to access this utility payments service.
-id:internet-banking-utility-payment-service uri:lb://internet-banking-utility-payment-service predicates: -Path=/utility-payment/** filters: -StripPrefix=1
Testing API With Postman
Just start all the components including service registry, API gateway, and internet banking utility payments service, and test API over a gateway to check the implementation.
Spring Eureka Service Registry – Utility Payment Service Implementation
Here are a few screenshots while testing the user service API using Postman, and you can access the same collection using the below link.
Read Utility Payments From API Postman Request
Create Utility Payments Postman Request
Conclusion
Thanks for reading our latest article onUtility Payments Service Implementation with practical usage.
This article only covers the basic implementation of utility payments service in an internet banking microservice project.I’ll explain the pending part which isbuilding the communication layer between user service and core banking microservice with the next article.
If you are looking forspring boot practical application development tutorials, just check our article series.
You can get the source code for this tutorial from our GitHub repository.