improving ecocash payment handling
This commit is contained in:
@@ -170,9 +170,14 @@ public class TransactionService {
|
||||
public Transaction findById(UUID id) {
|
||||
Transaction transaction = transactionRepository.findById(id).orElseThrow(() -> new ApiException("Transaction not found for ID: " + id));
|
||||
|
||||
AdditionalData additionalData = additionalDataService.getAdditionalDataRepository()
|
||||
.findByTransactionId(id).orElseThrow(() -> new ApiException("Additional data not found for transaction ID: " + id));
|
||||
transaction.setAdditionalData(Utils.fromJson(additionalData.getJsonString(), List.class));
|
||||
try {
|
||||
AdditionalData additionalData = additionalDataService.getAdditionalDataRepository()
|
||||
.findByTransactionId(id).orElseThrow(() -> new ApiException("Additional data not found for transaction ID: " + id));
|
||||
transaction.setAdditionalData(Utils.fromJson(additionalData.getJsonString(), List.class));
|
||||
} catch (ApiException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
@@ -60,8 +60,6 @@ public class EconetConfirmationProcessor implements TransactionProcessorInterfac
|
||||
|
||||
LinkedHashMap response = restService.postWithToken(token, url, request, LinkedHashMap.class);
|
||||
|
||||
logger.info("response: {}", response.toString());
|
||||
|
||||
LinkedHashMap body = (LinkedHashMap) response.get("body");
|
||||
|
||||
if (body.get("status").equals("SUCCESS")) {
|
||||
@@ -78,7 +76,6 @@ public class EconetConfirmationProcessor implements TransactionProcessorInterfac
|
||||
|
||||
} else {
|
||||
transaction.setStatus(Status.FAILED);
|
||||
transaction.setErrorMessage((String) body.get("message"));
|
||||
transaction.setResponseCode((String) body.get("responseCode"));
|
||||
transaction.setErrorMessage((String) body.get("errorMessage"));
|
||||
}
|
||||
|
||||
@@ -60,8 +60,6 @@ public class ZesaConfirmationProcessor implements TransactionProcessorInterface
|
||||
|
||||
LinkedHashMap response = restService.postWithToken(token, url, request, LinkedHashMap.class);
|
||||
|
||||
logger.info("response: {}", response.toString());
|
||||
|
||||
LinkedHashMap body = (LinkedHashMap) response.get("body");
|
||||
|
||||
if (body.get("status").equals("SUCCESS")) {
|
||||
@@ -78,7 +76,6 @@ public class ZesaConfirmationProcessor implements TransactionProcessorInterface
|
||||
|
||||
} else {
|
||||
transaction.setStatus(Status.FAILED);
|
||||
transaction.setErrorMessage((String) body.get("message"));
|
||||
transaction.setResponseCode((String) body.get("responseCode"));
|
||||
transaction.setErrorMessage((String) body.get("errorMessage"));
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ public class StewardIntegrationProcessor implements TransactionProcessorInterfac
|
||||
if (body.get("status").equals("SUCCESS")) {
|
||||
transaction.setStatus(Status.SUCCESS);
|
||||
transaction.setResponseCode((String) body.get("responseCode"));
|
||||
transaction.setCreditRef((String) body.get("creditReference"));
|
||||
transaction.setAdditionalData(body.get("additionalData"));
|
||||
transactionService.save(transaction);
|
||||
|
||||
|
||||
@@ -1,16 +1,103 @@
|
||||
package zw.qantra.tm.domain.services.processors.payments;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import java.math.BigDecimal;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import zw.qantra.tm.domain.dtos.SdkActionDto;
|
||||
import zw.qantra.tm.domain.enums.Status;
|
||||
import zw.qantra.tm.domain.models.Transaction;
|
||||
import zw.qantra.tm.domain.services.TransactionService;
|
||||
import zw.qantra.tm.domain.services.processors.TransactionProcessorInterface;
|
||||
import zw.qantra.tm.rest.RestService;
|
||||
|
||||
@Service("REQUEST_ECOCASH_REMOTE")
|
||||
@RequiredArgsConstructor
|
||||
public class EcocashRemotePaymentProcessor implements TransactionProcessorInterface {
|
||||
private final Logger logger = LoggerFactory.getLogger(EcocashRemotePaymentProcessor.class);
|
||||
private final RestService restService;
|
||||
private final TransactionService transactionService;
|
||||
|
||||
@Value("${sbz.aggregator.encryption-key}")
|
||||
private String encryptionKey;
|
||||
@Value("${sbz.aggregator.client-id}")
|
||||
private String clientId;
|
||||
@Value("${sbz.aggregator.client-secret}")
|
||||
private String clientSecret;
|
||||
@Value("${steward.payment.processor.url}")
|
||||
private String url;
|
||||
|
||||
@Override
|
||||
public Object process(Transaction transaction) throws Exception {
|
||||
|
||||
return transaction;
|
||||
logger.info("processing transaction");
|
||||
String token = restService.getMerchantToken();
|
||||
|
||||
// send total less gateway charges
|
||||
BigDecimal totalAmount = transaction.getAmount().add(transaction.getTax()).add(transaction.getCharge());
|
||||
|
||||
String concat = clientId+
|
||||
encryptionKey+
|
||||
transaction.getCreditPhone()+
|
||||
totalAmount;
|
||||
|
||||
String hex = getHash(concat);
|
||||
|
||||
SdkActionDto sdkActionDto = SdkActionDto.builder()
|
||||
.clientId(clientId)
|
||||
.clientSecret(clientSecret)
|
||||
.phone(transaction.getCreditPhone())
|
||||
.amount(totalAmount.toString())
|
||||
.currency(transaction.getDebitCurrency().toString())
|
||||
.hash(hex)
|
||||
.authType("REMOTE")
|
||||
.billerReference(transaction.getReference())
|
||||
.action("PAYMENT")
|
||||
.sandbox(true)
|
||||
.paymentProcessorLabel("ECOCASH")
|
||||
.responseUrl("https://peakapi.stewardpay.co.zw")
|
||||
.build();
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("Authorization", "Bearer " + token);
|
||||
headers.set("Content-Type", "application/json");
|
||||
|
||||
try {
|
||||
LinkedHashMap response = restService.postAs(url + "/merchant/sdk/action",
|
||||
sdkActionDto, headers, LinkedHashMap.class);
|
||||
|
||||
LinkedHashMap body = (LinkedHashMap) response.get("body");
|
||||
transaction.setSdkActionId((String) body.get("uid"));
|
||||
|
||||
if(body.get("status").equals("SUCCESS")){
|
||||
transaction.setStatus(Status.SUCCESS);
|
||||
transaction.setResponseCode("00");
|
||||
|
||||
LinkedHashMap transactionData = (LinkedHashMap) body.get("transaction");
|
||||
transaction.setDebitRef((String) transactionData.get("debitReference"));
|
||||
transactionService.save(transaction);
|
||||
}else{
|
||||
transaction.setStatus(Status.FAILED);
|
||||
transaction.setResponseCode("01");
|
||||
LinkedHashMap transactionData = (LinkedHashMap) body.get("transaction");
|
||||
transaction.setErrorMessage((String) transactionData.get("errorMessage"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
||||
transaction.setStatus(Status.FAILED);
|
||||
transaction.setResponseCode("99");
|
||||
transaction.setErrorMessage("Network error: " + e.getMessage());
|
||||
}
|
||||
|
||||
return transactionService.save(transaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -20,6 +107,64 @@ public class EcocashRemotePaymentProcessor implements TransactionProcessorInterf
|
||||
|
||||
@Override
|
||||
public Object poll(Transaction transaction) throws Exception {
|
||||
logger.info("polling transaction");
|
||||
String token = restService.getMerchantToken();
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.set("Authorization", "Bearer " + token);
|
||||
headers.set("Content-Type", "application/json");
|
||||
|
||||
try {
|
||||
LinkedHashMap response = restService.getAs(url + "/merchant/sdk/reference/" + transaction.getReference(),
|
||||
headers, LinkedHashMap.class);
|
||||
|
||||
LinkedHashMap body = (LinkedHashMap) response.get("body");
|
||||
|
||||
// only update tran status if polling returns a success
|
||||
if(body.get("status").equals("SUCCESS")){
|
||||
transaction.setStatus(Status.SUCCESS);
|
||||
transaction.setResponseCode("00");
|
||||
transaction.setTargetUrl((String) body.get("targetUrl"));
|
||||
|
||||
LinkedHashMap transactionData = (LinkedHashMap) body.get("transaction");
|
||||
transaction.setDebitRef((String) transactionData.get("debitReference"));
|
||||
|
||||
transactionService.save(transaction);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
||||
transaction.setStatus(Status.FAILED);
|
||||
transaction.setResponseCode("99");
|
||||
transaction.setErrorMessage("Network error: " + e.getMessage());
|
||||
}
|
||||
|
||||
return transaction;
|
||||
}
|
||||
|
||||
public String getHash(String originalString){
|
||||
String hex = "";
|
||||
MessageDigest digest = null;
|
||||
try {
|
||||
digest = MessageDigest.getInstance("SHA-256");
|
||||
byte[] encodedhash = digest.digest(
|
||||
originalString.getBytes(StandardCharsets.UTF_8));
|
||||
hex = bytesToHex(encodedhash);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return hex;
|
||||
}
|
||||
|
||||
private static String bytesToHex(byte[] hash) {
|
||||
StringBuilder hexString = new StringBuilder(2 * hash.length);
|
||||
for (int i = 0; i < hash.length; i++) {
|
||||
String hex = Integer.toHexString(0xff & hash[i]);
|
||||
if(hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -79,6 +79,7 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
|
||||
LinkedHashMap body = (LinkedHashMap) response.get("body");
|
||||
transaction.setSdkActionId((String) body.get("uid"));
|
||||
|
||||
// if status is not failed, set the transaction to pending and send customer to the target url
|
||||
if(!body.get("status").equals("FAILED")){
|
||||
transaction.setStatus(Status.PENDING);
|
||||
transaction.setResponseCode("00");
|
||||
@@ -86,7 +87,8 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
|
||||
}else{
|
||||
transaction.setStatus(Status.FAILED);
|
||||
transaction.setResponseCode("01");
|
||||
transaction.setErrorMessage((String) body.get("message"));
|
||||
LinkedHashMap transactionData = (LinkedHashMap) body.get("transaction");
|
||||
transaction.setErrorMessage((String) transactionData.get("errorMessage"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
||||
@@ -119,6 +121,10 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
|
||||
transaction.setStatus(Status.SUCCESS);
|
||||
transaction.setResponseCode("00");
|
||||
transaction.setTargetUrl((String) body.get("targetUrl"));
|
||||
|
||||
LinkedHashMap transactionData = (LinkedHashMap) body.get("transaction");
|
||||
transaction.setDebitRef((String) transactionData.get("debitReference"));
|
||||
|
||||
transactionService.save(transaction);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
Reference in New Issue
Block a user