package zw.qantra.tm.domain.services; import lombok.Getter; import lombok.RequiredArgsConstructor; import java.util.UUID; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import zw.qantra.tm.domain.enums.RequestType; import zw.qantra.tm.domain.enums.Status; import zw.qantra.tm.domain.models.Provider; import zw.qantra.tm.domain.models.Transaction; 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.LogicPipeline; import zw.qantra.tm.domain.services.processors.handlers.ValidationHandler; import zw.qantra.tm.exceptions.ApiException; @Service @RequiredArgsConstructor public class TransactionService { Logger logger = LoggerFactory.getLogger(TransactionService.class); @Getter private final TransactionRepository transactionRepository; private final PaymentProcessorFactory paymentProcessorFactory; private final CalculateChargesHandler calculateChargesHandler; private final ProviderService providerService; public Transaction poll(UUID uuid){ if(!transactionRepository.existsById(uuid)){ throw new ApiException("Transaction not found for ID: " + uuid); } Transaction transaction = transactionRepository.findById(uuid).get(); // no persistence happens during polling unless the transaction status changes String label = getLabel(transaction); logger.info("label: {}", label); TransactionProcessorInterface transactionProcessorInterface = (TransactionProcessorInterface) paymentProcessorFactory.getPaymentProcessor(label); try { transactionProcessorInterface.poll(transaction); } catch (Exception e) { e.printStackTrace(); transaction.setStatus(Status.FAILED); transaction.setResponseCode("01"); transaction.setErrorMessage(e.getMessage()); } return transaction; } public Transaction execute(Transaction transaction) { transaction.setReference(UUID.randomUUID().toString()); LogicPipeline transactionLogic = new LogicPipeline<>(calculateChargesHandler) .addHandler(new ValidationHandler()); transaction = transactionLogic.execute(transaction); String label = getLabel(transaction); logger.info("label: {}", label); TransactionProcessorInterface transactionProcessorInterface = (TransactionProcessorInterface) paymentProcessorFactory.getPaymentProcessor(label); try { transactionProcessorInterface.process(transaction); }catch (Exception e){ e.printStackTrace(); transaction.setStatus(Status.FAILED); transaction.setResponseCode("01"); transaction.setErrorMessage(e.getMessage()); transactionRepository.save(transaction); return transaction; } 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(); }else{ label = transaction.getType() + "_" + transaction.getPaymentProcessorLabel() + "_" + transaction.getAuthType(); } return label; } public Transaction save(Transaction transaction){ return transactionRepository.save(transaction); } }