updates on transaction structure

This commit is contained in:
2025-09-01 23:53:29 +02:00
parent 0ee5c2297d
commit 285b03a724
12 changed files with 133 additions and 82 deletions

View File

@@ -3,7 +3,6 @@ package zw.qantra.tm.domain.services;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
@@ -23,6 +22,7 @@ import zw.qantra.tm.domain.repositories.TransactionRepository;
import zw.qantra.tm.domain.services.factories.PaymentProcessorFactory;
import zw.qantra.tm.domain.services.processors.TransactionProcessorInterface;
import zw.qantra.tm.domain.services.processors.handlers.CalculateChargesHandler;
import zw.qantra.tm.domain.services.processors.handlers.ConfirmationLabelHandler;
import zw.qantra.tm.domain.services.processors.handlers.ConfirmationLogicHandler;
import zw.qantra.tm.domain.services.processors.handlers.FormattingHandler;
import zw.qantra.tm.domain.services.processors.handlers.LogicPipeline;
@@ -31,7 +31,6 @@ import zw.qantra.tm.domain.services.processors.handlers.ValidationHandler;
import zw.qantra.tm.domain.services.processors.handlers.erp.PurchaseInvoiceHandler;
import zw.qantra.tm.domain.services.processors.handlers.erp.SalesInvoiceHandler;
import zw.qantra.tm.domain.models.TransactionEvent;
import zw.qantra.tm.domain.services.TransactionEventService;
import zw.qantra.tm.exceptions.ApiException;
import zw.qantra.tm.utils.Utils;
@@ -78,6 +77,8 @@ public class TransactionService {
try {
transactionProcessorInterface.process(transaction);
transaction.setIntegrationStatus(transaction.getStatus());
transactionRepository.save(transaction);
}catch (Exception e){
e.printStackTrace();
transaction.setStatus(Status.FAILED);
@@ -106,7 +107,7 @@ public class TransactionService {
Transaction transaction = transactionRepository.findById(uuid).get();
// if the transaction is already successful, return it
if(transaction.getStatus() == Status.SUCCESS){
if(transaction.getIntegrationStatus() == Status.SUCCESS){
return transaction;
}
@@ -118,7 +119,7 @@ public class TransactionService {
transactionEventService.save(transactionEvent);
// no persistence happens during polling unless the transaction status changes
String label = getLabel(transaction);
String label = "REQUEST_" + transaction.getPaymentProcessorLabel() + "_" + transaction.getAuthType();
logger.info("label: {}", label);
TransactionProcessorInterface transactionProcessorInterface =
@@ -131,6 +132,9 @@ public class TransactionService {
transactionEvent.setMessage(transaction.getErrorMessage());
transactionEventService.save(transactionEvent);
transaction.setPollingStatus(transaction.getStatus());
transactionRepository.save(transaction);
// if tran was successful push integration to the aggregator
if(transaction.getStatus() == Status.SUCCESS){
transaction.setType(RequestType.INTEGRATION);
@@ -146,15 +150,25 @@ public class TransactionService {
return transaction;
}
public Transaction execute(Transaction incomingTransaction) {
public Transaction request(Transaction incomingTransaction) {
// if payment request (not confirm), then fetch already existing transaction record
Transaction transaction = incomingTransaction;
if(incomingTransaction.getId() != null){
transaction = getTransactionRepository().findById(incomingTransaction.getId()).orElseThrow(() ->
new ApiException("Transaction not found for ID: " + incomingTransaction.getId()));
transaction.setType(incomingTransaction.getType()); // type should be REQUEST here
transaction.setAuthType(incomingTransaction.getAuthType());
}
// run pre transaction logic
LogicPipeline<Transaction, Transaction> preTransactionLogic =
new LogicPipeline<>(new CalculateChargesHandler(chargeService))
.addHandler(new FormattingHandler())
.addHandler(new ValidationHandler());
transaction = preTransactionLogic.execute(transaction);
transactionRepository.save(transaction);
TransactionEvent transactionEvent = TransactionEvent.builder()
.transactionId(transaction.getId().toString())
.event(transaction.getType().name())
@@ -162,15 +176,7 @@ public class TransactionService {
.build();
transactionEventService.save(transactionEvent);
// run pre transaction logic
LogicPipeline<Transaction, Transaction> preTransactionLogic =
new LogicPipeline<>(new CalculateChargesHandler(chargeService))
.addHandler(new ConfirmationLogicHandler())
.addHandler(new FormattingHandler())
.addHandler(new ValidationHandler());
transaction = preTransactionLogic.execute(transaction);
String label = getLabel(transaction);
String label = transaction.getType() + "_" + transaction.getPaymentProcessorLabel() + "_" + transaction.getAuthType();
logger.info("label: {}", label);
TransactionProcessorInterface transactionProcessorInterface =
@@ -179,12 +185,7 @@ public class TransactionService {
try {
// MAIN TRANSACTION LOGIC!
transactionProcessorInterface.process(transaction);
if(transaction.getType() == RequestType.CONFIRM){
transaction.setConfirmationStatus(transaction.getStatus());
}else{
transaction.setPaymentStatus(transaction.getStatus());
}
transaction.setPaymentStatus(transaction.getStatus());
}catch (Exception e){
e.printStackTrace();
@@ -208,25 +209,52 @@ public class TransactionService {
return transaction;
}
private String getLabel(Transaction transaction){
String label = "";
if(transaction.getType() == RequestType.CONFIRM){
// get processor label from billClientId
Provider provider = providerService.getProviderRepository()
.findByClientId(transaction.getBillClientId());
if(provider == null){
throw new ApiException("Provider not found for billClientId: " + transaction.getBillClientId());
}
label = transaction.getType() + "_" +
provider.getLabel();
public Transaction confirm(Transaction transaction) {
// run pre transaction logic
LogicPipeline<Transaction, Transaction> preTransactionLogic =
new LogicPipeline<>(new CalculateChargesHandler(chargeService))
.addHandler(new ConfirmationLabelHandler(providerService))
.addHandler(new ConfirmationLogicHandler())
.addHandler(new FormattingHandler())
.addHandler(new ValidationHandler());
transaction = preTransactionLogic.execute(transaction);
transactionRepository.save(transaction);
transaction.setIntegrationProcessorLabel(provider.getIntegrationProcessorLabel());
}else{
label = transaction.getType() + "_" +
transaction.getPaymentProcessorLabel() + "_" +
transaction.getAuthType();
TransactionEvent transactionEvent = TransactionEvent.builder()
.transactionId(transaction.getId().toString())
.event(transaction.getType().name())
.status(Status.PROCESSING)
.build();
transactionEventService.save(transactionEvent);
TransactionProcessorInterface transactionProcessorInterface =
(TransactionProcessorInterface) paymentProcessorFactory.getPaymentProcessor(
transaction.getConfirmationProcessorLabel());
try {
// MAIN TRANSACTION LOGIC!
transactionProcessorInterface.process(transaction);
transaction.setConfirmationStatus(transaction.getStatus());
}catch (Exception e){
e.printStackTrace();
transaction.setStatus(Status.FAILED);
transaction.setResponseCode("01");
transaction.setErrorMessage(e.getMessage());
transactionRepository.save(transaction);
return transaction;
}
return label;
// run post transaction logic
LogicPipeline<Transaction, Transaction> postTransactionLogic =
new LogicPipeline<>(new RecipientsUpdateHandler(recipientService));
transaction = postTransactionLogic.execute(transaction);
transactionEvent.setStatus(transaction.getStatus());
transactionEvent.setMessage(transaction.getErrorMessage());
transactionEventService.save(transactionEvent);
return transaction;
}
public Transaction findById(UUID id) {
@@ -234,7 +262,8 @@ public class TransactionService {
try {
AdditionalData additionalData = additionalDataService.getAdditionalDataRepository()
.findByTransactionId(id).orElseThrow(() -> new ApiException("Additional data not found for transaction ID: " + id));
.findByTransactionIdAndRequestType(id, RequestType.INTEGRATION).orElseThrow(() ->
new ApiException("Additional data not found for transaction ID: " + id + " and request type: " + RequestType.INTEGRATION));
transaction.setAdditionalData(Utils.fromJson(additionalData.getJsonString(), List.class));
} catch (ApiException e) {
// TODO Auto-generated catch block