major reshuffle of workflow logic

This commit is contained in:
2025-10-30 18:56:52 +02:00
parent 3b3c8d8f1b
commit 883d3ace9a
7 changed files with 130 additions and 72 deletions

View File

@@ -13,12 +13,14 @@ import zw.qantra.tm.domain.enums.Status;
import zw.qantra.tm.domain.models.AdditionalData; import zw.qantra.tm.domain.models.AdditionalData;
import zw.qantra.tm.domain.models.Transaction; import zw.qantra.tm.domain.models.Transaction;
import zw.qantra.tm.domain.services.AdditionalDataService; import zw.qantra.tm.domain.services.AdditionalDataService;
import zw.qantra.tm.domain.services.SettingService;
import zw.qantra.tm.domain.services.TransactionService; import zw.qantra.tm.domain.services.TransactionService;
import zw.qantra.tm.domain.services.processors.TransactionProcessorInterface; import zw.qantra.tm.domain.services.processors.TransactionProcessorInterface;
import zw.qantra.tm.rest.RestService; import zw.qantra.tm.rest.RestService;
import zw.qantra.tm.utils.Utils; import zw.qantra.tm.utils.Utils;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Objects;
@Service("INTEGRATION_STEWARD") @Service("INTEGRATION_STEWARD")
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -27,6 +29,7 @@ public class StewardIntegrationProcessor implements TransactionProcessorInterfac
private final RestService restService; private final RestService restService;
private final TransactionService transactionService; private final TransactionService transactionService;
private final AdditionalDataService additionalDataService; private final AdditionalDataService additionalDataService;
private final SettingService settingService;
@Value("${sbz.aggregator.url}") @Value("${sbz.aggregator.url}")
private String aggregatorUrl; private String aggregatorUrl;
@@ -36,10 +39,20 @@ public class StewardIntegrationProcessor implements TransactionProcessorInterfac
private String aggregatorPhone; private String aggregatorPhone;
@Value("${sbz.aggregator.account}") @Value("${sbz.aggregator.account}")
private String aggregatorAccount; private String aggregatorAccount;
@Value("${powertel.clientid}")
private String powertelClientId;
@Override @Override
@Transactional @Transactional
public Object process(Transaction transaction) throws Exception { public Object process(Transaction transaction) throws Exception {
if(settingService.getBooleanSetting("SIMULATE_INTEGRATION_FAILURE")){
transaction.setStatus(Status.FAILED);
transaction.setResponseCode("92");
transaction.setErrorMessage("Simulated failure");
return transaction;
}
logger.info("processing integration"); logger.info("processing integration");
String token = restService.getMerchantToken(); String token = restService.getMerchantToken();
@@ -49,7 +62,7 @@ public class StewardIntegrationProcessor implements TransactionProcessorInterfac
} }
BillPaymentDto request = BillPaymentDto.builder() BillPaymentDto request = BillPaymentDto.builder()
.type(RequestType.REQUEST) .type(RequestType.CONFIRM)
.billClientId(transaction.getBillClientId()) .billClientId(transaction.getBillClientId())
.debitRef(debitRef) .debitRef(debitRef)
.debitCurrency(transaction.getDebitCurrency()) .debitCurrency(transaction.getDebitCurrency())
@@ -60,14 +73,22 @@ public class StewardIntegrationProcessor implements TransactionProcessorInterfac
.creditAccount(transaction.getCreditAccount()) // customer's zesa meter number .creditAccount(transaction.getCreditAccount()) // customer's zesa meter number
.creditPhone(transaction.getCreditPhone()) // customer's contact phone number .creditPhone(transaction.getCreditPhone()) // customer's contact phone number
.billName(transaction.getBillName()) .billName(transaction.getBillName())
.authType(transaction.getAuthType())
.trace(transaction.getTrace())
.build(); .build();
if(Objects.equals(powertelClientId, transaction.getBillClientId())) {
logger.info("send confirmation again");
String url = aggregatorUrl + "/merchant/aggregation/transaction"; String url = aggregatorUrl + "/merchant/aggregation/transaction";
LinkedHashMap response = restService.postWithToken(token, url, request, LinkedHashMap.class); LinkedHashMap response = restService.postWithToken(token, url, request, LinkedHashMap.class);
logger.info("response: {}", response.toString());
}
// once done, update and send request
request.setType(RequestType.REQUEST);
request.setAuthType(transaction.getAuthType());
request.setTrace(transaction.getTrace());
String url = aggregatorUrl + "/merchant/aggregation/transaction";
LinkedHashMap response = restService.postWithToken(token, url, request, LinkedHashMap.class);
logger.info("response: {}", response.toString()); logger.info("response: {}", response.toString());
LinkedHashMap body = (LinkedHashMap) response.get("body"); LinkedHashMap body = (LinkedHashMap) response.get("body");

View File

@@ -148,6 +148,7 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
} }
transaction.setStatus(Status.SUCCESS); transaction.setStatus(Status.SUCCESS);
transaction.setPaymentStatus(Status.SUCCESS);
transaction.setResponseCode("00"); transaction.setResponseCode("00");
transaction.setTargetUrl((String) body.get("targetUrl")); transaction.setTargetUrl((String) body.get("targetUrl"));

View File

@@ -46,29 +46,31 @@ public class TransactionWorkflow extends WorkflowDefinition {
public static final State SALES_INVOICE = new State("salesInvoice"); public static final State SALES_INVOICE = new State("salesInvoice");
public static final State JOURNAL_ENTRY = new State("journalEntry"); public static final State JOURNAL_ENTRY = new State("journalEntry");
public static final State SALES_PAYMENT = new State("salesPayment"); public static final State SALES_PAYMENT = new State("salesPayment");
public static final State PURCHASE_INVOICE = new State("purchaseInvoice", WorkflowStateType.manual); public static final State PURCHASE_INVOICE = new State("purchaseInvoice");
public static final State PURCHASE_INVOICE_SUCCESS = new State("purchaseInvoiceSuccess", WorkflowStateType.manual);
public static final State INTEGRATION = new State("integration"); public static final State INTEGRATION = new State("integration");
public static final State PURCHASE_INVOICE_PAYMENT = new State("purchaseInvoicePayment"); public static final State PURCHASE_INVOICE_PAYMENT = new State("purchaseInvoicePayment");
public static final State FAILED = new State("failed", WorkflowStateType.manual); public static final State TRAN_FAILED = new State("failed", WorkflowStateType.manual);
public static final State DONE = new State("done", WorkflowStateType.end); public static final State DONE = new State("done", WorkflowStateType.end);
public TransactionWorkflow() { public TransactionWorkflow() {
super(TYPE, CALCULATE_CHARGES, FAILED); super(TYPE, CALCULATE_CHARGES, TRAN_FAILED);
permit(CALCULATE_CHARGES, CLEANUP); permit(CALCULATE_CHARGES, CLEANUP);
permit(CLEANUP, CONFIRM); permit(CLEANUP, CONFIRM);
permit(CONFIRM, RECIPIENTS_UPDATE, FAILED); permit(CONFIRM, RECIPIENTS_UPDATE, TRAN_FAILED);
permit(RECIPIENTS_UPDATE, CONFIRM_SUCCESS); permit(RECIPIENTS_UPDATE, CONFIRM_SUCCESS);
permit(CONFIRM_SUCCESS, GATEWAY_PAYMENT); permit(CONFIRM_SUCCESS, GATEWAY_PAYMENT);
permit(GATEWAY_PAYMENT, GATEWAY_PAYMENT_SUCCESS, FAILED); permit(GATEWAY_PAYMENT, GATEWAY_PAYMENT_SUCCESS, TRAN_FAILED);
permit(GATEWAY_PAYMENT_SUCCESS, POLL_STATUS); permit(GATEWAY_PAYMENT_SUCCESS, POLL_STATUS);
permit(POLL_STATUS, SALES_INVOICE, FAILED); permit(POLL_STATUS, SALES_INVOICE, TRAN_FAILED);
permit(SALES_INVOICE, JOURNAL_ENTRY); permit(SALES_INVOICE, JOURNAL_ENTRY);
permit(JOURNAL_ENTRY, SALES_PAYMENT); permit(JOURNAL_ENTRY, SALES_PAYMENT);
permit(SALES_PAYMENT, PURCHASE_INVOICE); permit(SALES_PAYMENT, PURCHASE_INVOICE);
permit(PURCHASE_INVOICE, INTEGRATION); permit(PURCHASE_INVOICE, PURCHASE_INVOICE_SUCCESS);
permit(INTEGRATION, PURCHASE_INVOICE_PAYMENT, FAILED); permit(PURCHASE_INVOICE_SUCCESS, INTEGRATION);
permit(INTEGRATION, PURCHASE_INVOICE_PAYMENT, TRAN_FAILED);
permit(PURCHASE_INVOICE_PAYMENT, DONE); permit(PURCHASE_INVOICE_PAYMENT, DONE);
} }
@@ -78,13 +80,16 @@ public class TransactionWorkflow extends WorkflowDefinition {
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
process(transaction, "calculateCharges"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("calculateCharges");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(CLEANUP, "Charge calculation complete"); return NextAction.moveToState(CLEANUP, "Charge calculation complete");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return NextAction.moveToState(FAILED, e.getMessage()); return NextAction.moveToState(TRAN_FAILED, e.getMessage());
} }
} }
@@ -94,13 +99,16 @@ public class TransactionWorkflow extends WorkflowDefinition {
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
process(transaction, "cleanup"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("cleanup");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(CONFIRM, "Cleanup complete"); return NextAction.moveToState(CONFIRM, "Cleanup complete");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return NextAction.moveToState(FAILED, e.getMessage()); return NextAction.moveToState(TRAN_FAILED, e.getMessage());
} }
} }
@@ -111,21 +119,26 @@ public class TransactionWorkflow extends WorkflowDefinition {
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
transaction.setWorkflowId(execution.getWorkflowInstanceId()); transaction.setWorkflowId(execution.getWorkflowInstanceId());
transaction = process(transaction, "confirm"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("confirm");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(RECIPIENTS_UPDATE, "Recipients updated successfully"); return NextAction.moveToState(RECIPIENTS_UPDATE, "Recipients updated successfully");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return NextAction.moveToState(FAILED, e.getMessage()); return NextAction.moveToState(TRAN_FAILED, e.getMessage());
} }
} }
public NextAction recipientsUpdate(StateExecution execution) throws IOException { public NextAction recipientsUpdate(StateExecution execution) throws Exception {
LinkedHashMap map = execution.getVariable("body", LinkedHashMap.class); LinkedHashMap map = execution.getVariable("body", LinkedHashMap.class);
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
process(transaction, "recipientsUpdate"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("recipientsUpdate");
handlerInterface.process(transaction);
return NextAction.moveToState(CONFIRM_SUCCESS, "Transaction confirmed successfully"); return NextAction.moveToState(CONFIRM_SUCCESS, "Transaction confirmed successfully");
} }
@@ -140,12 +153,15 @@ public class TransactionWorkflow extends WorkflowDefinition {
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
transaction = process(transaction, "gatewayPayment"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("gatewayPayment");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(GATEWAY_PAYMENT_SUCCESS, "Gateway payment initiated"); return NextAction.moveToState(GATEWAY_PAYMENT_SUCCESS, "Gateway payment initiated");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return NextAction.moveToState(FAILED, e.getMessage()); return NextAction.moveToState(TRAN_FAILED, e.getMessage());
} }
} }
@@ -153,30 +169,37 @@ public class TransactionWorkflow extends WorkflowDefinition {
log.info("Gateway payment initiation complete"); log.info("Gateway payment initiation complete");
} }
public NextAction pollStatus(StateExecution execution) { public NextAction pollStatus(StateExecution execution) throws IOException {
try {
// cannot cast direct to Transaction object because of some jackson mapper hullabaloo :( // cannot cast direct to Transaction object because of some jackson mapper hullabaloo :(
LinkedHashMap map = execution.getVariable("body", LinkedHashMap.class); LinkedHashMap map = execution.getVariable("body", LinkedHashMap.class);
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
transaction = process(transaction, "pollStatus"); try {
HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("pollStatus");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(SALES_INVOICE, "Polling complete"); return NextAction.moveToState(SALES_INVOICE, "Polling complete");
} catch (Exception e) { } catch (Exception e) {
log.info(e.getCause().getMessage()); log.info(e.getMessage());
return NextAction.moveToState(FAILED, e.getCause().getMessage()); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(TRAN_FAILED, e.getMessage());
} }
} }
public NextAction salesInvoice(StateExecution execution) { public NextAction salesInvoice(StateExecution execution) {
try { try {
// cannot cast direct to Transaction object because of some jackson mapper hullabaloo :( // cannot cast direct to Transaction object because of some jackson mapper hullabaloo :(
LinkedHashMap map = execution.getVariable("request", LinkedHashMap.class); LinkedHashMap map = execution.getVariable("body", LinkedHashMap.class);
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
transaction = process(transaction, "salesInvoice"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("salesInvoice");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(JOURNAL_ENTRY, return NextAction.moveToState(JOURNAL_ENTRY,
"Sales invoice generated - id:" + transaction.getErpSalesRef()); "Sales invoice generated - id:" + transaction.getErpSalesRef());
@@ -192,7 +215,10 @@ public class TransactionWorkflow extends WorkflowDefinition {
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
transaction = process(transaction, "journalEntry"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("journalEntry");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(SALES_PAYMENT, return NextAction.moveToState(SALES_PAYMENT,
"Journal Entry successful - id: " + transaction.getErpJournalRef()); "Journal Entry successful - id: " + transaction.getErpJournalRef());
@@ -208,7 +234,10 @@ public class TransactionWorkflow extends WorkflowDefinition {
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
transaction = process(transaction, "salesPayment"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("salesPayment");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(PURCHASE_INVOICE, return NextAction.moveToState(PURCHASE_INVOICE,
"Sales payment successful - id: " + transaction.getErpSalesPaymentRef()); "Sales payment successful - id: " + transaction.getErpSalesPaymentRef());
@@ -218,30 +247,46 @@ public class TransactionWorkflow extends WorkflowDefinition {
} }
} }
public void purchaseInvoice(StateExecution execution) throws IOException { public NextAction purchaseInvoice(StateExecution execution) throws Exception {
LinkedHashMap map = execution.getVariable("body", LinkedHashMap.class);
byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class);
transaction = process(transaction, "purchaseInvoice");
execution.setVariable("body", Utils.toJson(transaction));
}
public NextAction integration(StateExecution execution) {
try { try {
LinkedHashMap map = execution.getVariable("body", LinkedHashMap.class); LinkedHashMap map = execution.getVariable("body", LinkedHashMap.class);
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
transaction = process(transaction, "integration"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("purchaseInvoice");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(PURCHASE_INVOICE_SUCCESS,
"Purchase invoice successful - id: " + transaction.getErpPurchaseRef());
}catch (Exception e) {
e.printStackTrace();
return NextAction.retryAfter(new DateTime().plusMinutes(1), e.getMessage());
}
}
public void purchaseInvoiceSuccess(StateExecution execution) {
log.info("Purchase invoice payment complete");
}
public NextAction integration(StateExecution execution) throws IOException {
LinkedHashMap map = execution.getVariable("body", LinkedHashMap.class);
byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class);
try {
HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("integration");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(PURCHASE_INVOICE_PAYMENT, "Integration request successful"); return NextAction.moveToState(PURCHASE_INVOICE_PAYMENT, "Integration request successful");
} catch (ApiException e) {
log.info(e.getMessage());
return NextAction.moveToState(FAILED, e.getMessage());
} catch (Exception e) { } catch (Exception e) {
log.info(e.getMessage()); log.info(e.getMessage());
return NextAction.moveToState(FAILED, e.getMessage()); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(TRAN_FAILED, e.getMessage());
} }
} }
@@ -251,7 +296,10 @@ public class TransactionWorkflow extends WorkflowDefinition {
byte[] json = objectMapper.writeValueAsBytes(map); byte[] json = objectMapper.writeValueAsBytes(map);
Transaction transaction = objectMapper.readValue(json, Transaction.class); Transaction transaction = objectMapper.readValue(json, Transaction.class);
transaction = process(transaction, "purchaseInvoicePayment"); HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler("purchaseInvoicePayment");
transaction = (Transaction) handlerInterface.process(transaction);
execution.setVariable("body", Utils.toJson(transaction)); execution.setVariable("body", Utils.toJson(transaction));
return NextAction.moveToState(DONE, return NextAction.moveToState(DONE,
"Purchase invoice payment generated - id: " + transaction.getErpPurchasePaymentRef()); "Purchase invoice payment generated - id: " + transaction.getErpPurchasePaymentRef());
@@ -260,21 +308,4 @@ public class TransactionWorkflow extends WorkflowDefinition {
return NextAction.retryAfter(new DateTime().plusMinutes(1), e.getMessage()); return NextAction.retryAfter(new DateTime().plusMinutes(1), e.getMessage());
} }
} }
public Transaction process(Transaction transaction, String beanName) {
HandlerInterface handlerInterface =
(HandlerInterface) workflowHandlerFactory.getWorkflowHandler(beanName);
try {
transaction = (Transaction) handlerInterface.process(transaction);
}catch (Exception e){
e.printStackTrace();
e.getCause().printStackTrace();
transaction.setStatus(Status.FAILED);
transaction.setResponseCode("01");
transaction.setErrorMessage(e.getMessage());
transactionService.getTransactionRepository().save(transaction);
}
return transaction;
}
} }

View File

@@ -68,11 +68,13 @@ public class IntegrationHandler implements HandlerInterface {
transactionEvent.setMessage(transaction.getErrorMessage()); transactionEvent.setMessage(transaction.getErrorMessage());
transactionEventService.save(transactionEvent); transactionEventService.save(transactionEvent);
transaction.setIntegrationStatus(transaction.getStatus());
if(transaction.getStatus() != Status.SUCCESS){ if(transaction.getStatus() != Status.SUCCESS){
transactionService.save(transaction); transactionService.save(transaction);
throw new ApiException("Transaction failed: " + transaction.getErrorMessage() ); throw new ApiException("Transaction failed: " + transaction.getErrorMessage() );
}else { }else {
transaction.setIntegrationStatus(transaction.getStatus()); transaction.setErrorMessage(null);
} }
Transaction t1 = Utils.deepCopy(transaction, Transaction.class); Transaction t1 = Utils.deepCopy(transaction, Transaction.class);

View File

@@ -63,7 +63,6 @@ public class PollStatusHandler implements HandlerInterface {
transaction.setErrorMessage(null); transaction.setErrorMessage(null);
} }
transactionService.save(transaction); return transactionService.save(transaction);
return transaction;
} }
} }

View File

@@ -50,3 +50,5 @@ nflow.db.postgresql.driver=org.postgresql.Driver
nflow.db.postgresql.url=jdbc:postgresql://173.212.247.232:5532/qpay nflow.db.postgresql.url=jdbc:postgresql://173.212.247.232:5532/qpay
nflow.db.postgresql.user=postgres nflow.db.postgresql.user=postgres
nflow.db.postgresql.password=zdDZMzq6F4B4L1IUl nflow.db.postgresql.password=zdDZMzq6F4B4L1IUl
powertel.clientid=powertel_zesa

View File

@@ -65,3 +65,5 @@ spring.mail.username=notifications@qantra.co.zw
spring.mail.password=QdZucpJMJIZ spring.mail.password=QdZucpJMJIZ
spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.enable=true
powertel.clientid=zesa_prepaid_usd