Untitled
public abstract class AbstractBatchTransactionService<T extends BatchTransaction> { private final AccountService accountService; private final CardPropertyConfig cardPropertyConfig; private final MJSHelperImpl mjsHelper; private static final String TRANSACTION_NARRATION_FORMAT = "Transaction from %s to %s"; protected AbstractBatchTransactionService(AccountService accountService, CardPropertyConfig cardPropertyConfig, MJSHelperImpl mjsHelper) { this.accountService = accountService; this.cardPropertyConfig = cardPropertyConfig; this.mjsHelper = mjsHelper; } protected abstract TransactionRepository<T> getTransactionRepository(); protected T createTransaction(T transaction, long amount) { transaction.setAmount(amount); return getTransactionRepository().save(transaction); } protected TransactionStatus handlePayment(T transaction, String sourceAccount, String destinationAccount, boolean forceDebit) { try { WalletTransactionResponse walletTransactionResponse = debitWallet(sourceAccount, destinationAccount, transaction.getAmount(), transaction.getTransactionReference(), forceDebit); if (isTransactionFailed(walletTransactionResponse)) { handleTransactionFailure(transaction, walletTransactionResponse); handleReversalForFailure(transaction, walletTransactionResponse); return TransactionStatus.FAILED; } updateTransactionForSuccess(transaction, walletTransactionResponse); return TransactionStatus.COMPLETED; } catch (Exception ex) { log.error("Error during debit: {}", ex.getMessage(), ex); return TransactionStatus.FAILED; } } protected void processReversalResult(T transaction, WalletTransactionResponse reverseTransactionResponse) { transaction.setReversalResponseBody(convertToJsonString(reverseTransactionResponse)); transaction.setCbaReversalCode(reverseTransactionResponse.getResponseCode()); if (TransactionResponseCode.SUCCESS.getCode().equalsIgnoreCase(reverseTransactionResponse.getResponseCode())) { transaction.setReversed(Boolean.TRUE); transaction.setShouldBeReversed(Boolean.FALSE); } else { transaction.setReversed(Boolean.FALSE); } } protected void handleTransactionFailure(T transaction, WalletTransactionResponse response) { transaction.setResponseMessage(PostilionResponse.getDescription(response.getResponseCode())); transaction.setResponseCode(response.getResponseCode()); transaction.setStatus(TransactionStatus.FAILED); getTransactionRepository().save(transaction); } protected void handleReversalForFailure(T transaction, WalletTransactionResponse walletTransactionResponse) { if (PostilionResponse._96.getCode().equalsIgnoreCase(walletTransactionResponse.getResponseCode())) { mjsHelper.createBackOffNewJob( MJSJobType.CARD_BATCH_TRANSACTION_PROCESS, transaction.getTransactionReference(), cardPropertyConfig.getReversalDeferRetries(), TimeUtil.addMinutesToTimestamp(TimeUtil.getCurrentTimestamp(), 1) ); } } private WalletTransactionResponse debitWallet(String sourceAccountNumber, String destinationAccountNumber, long debitAmount, String transactionReference, boolean forceDebit) { String narration = String.format(TRANSACTION_NARRATION_FORMAT, Util.maskAccountNumber(sourceAccountNumber), Util.maskAccountNumber(destinationAccountNumber)); DebitAccountRequest debitAccountRequest = DebitAccountRequest.builder() .sourceAccountNumber(sourceAccountNumber) .destinationAccountNumber(destinationAccountNumber) .transactionReference(transactionReference) .amount(debitAmount) .transactionAmount(debitAmount) .narration(narration) .useLedgerAccount(Boolean.TRUE) .forceDebit(forceDebit) .transactionType(MonnifyTransactionType.CARD_BATCH_TRANSACTION) .build(); return accountService.debitAccount(debitAccountRequest); } private void updateTransactionForSuccess(T transaction, WalletTransactionResponse walletTransactionResponse) { transaction.setShouldBeReversed(Boolean.FALSE); transaction.setReversed(Boolean.TRUE); transaction.setReversalResponseBody(convertToJsonString(walletTransactionResponse)); transaction.setResponseBody(convertToJsonString(walletTransactionResponse)); transaction.setResponseCode(walletTransactionResponse.getResponseCode()); transaction.setResponseMessage(walletTransactionResponse.getResponseMessage()); transaction.setStatus(TransactionStatus.COMPLETED); getTransactionRepository().save(transaction); } private boolean isTransactionFailed(WalletTransactionResponse walletTransactionResponse) { return !"00".equalsIgnoreCase(walletTransactionResponse.getResponseCode()); } private String convertToJsonString(Object object) { // Use Gson or Jackson to convert object to JSON string return new Gson().toJson(object); } }
Leave a Comment