added openwa failure notifications

This commit is contained in:
2026-07-09 21:19:43 +02:00
parent 94a30633ca
commit fbc3967215
10 changed files with 45 additions and 11 deletions

View File

@@ -22,5 +22,5 @@ public interface TransactionRepository extends JpaRepository<Transaction, UUID>,
List<Transaction> findAllByWorkspaceIdIsNullAndUserIdIsNotNull();
List<Transaction> findAllByConfirmationStatusAndPaymentStatusAndIntegrationStatus(
Status s1, Status s2, Status s3);
List<Transaction> findAllByPaymentStatusAndPollingStatus(Status s1, Status s2);
List<Transaction> findAllByPollingStatus(Status s2);
}

View File

@@ -35,7 +35,7 @@ public class JobService {
public void checkOrphanedTransactions() {
List<Transaction> transactions = transactionService.getTransactionRepository()
.findAllByPaymentStatusAndPollingStatus(Status.SUCCESS, Status.PENDING);
.findAllByPollingStatus(Status.PENDING);
if (!transactions.isEmpty())
log.info("Transaction count {}", transactions.size());
@@ -47,8 +47,13 @@ public class JobService {
int maxRetries = settingService.getIntegerSetting("MAX_RETRIES");
int retries = transaction.getRetries() == null ? 0 : transaction.getRetries();
if (retries >= maxRetries)
if (retries >= maxRetries) {
transaction.setPaymentStatus(Status.FAILED);
transaction.setPollingStatus(Status.FAILED);
transaction.setErrorMessage("Maximum retries reached");
transactionService.save(transaction);
break;
}
transaction.setRetries(retries + 1);
// polling logic
@@ -106,8 +111,8 @@ public class JobService {
success++;
}else {
transaction.setPollingStatus(Status.FAILED);
transaction.setIntegrationStatus(Status.FAILED);
transaction.setPollingStatus(Status.PENDING);
transaction.setIntegrationStatus(Status.PENDING);
transactionService.save(transaction);
}

View File

@@ -108,7 +108,7 @@ public class NotificationService {
public void sendWA(String chatId, String text) {
try {
Map<String, String> payload = new HashMap<>();
payload.put("chatId", chatId);
payload.put("chatId", String.format("%s@c.us", chatId));
payload.put("text", text);
HttpHeaders headers = new HttpHeaders();

View File

@@ -40,6 +40,7 @@ public class CityWalletRemotePaymentProcessor implements TransactionProcessorInt
} catch (Exception e) {
e.printStackTrace();
logger.error("Network error during payment processing: {}", e.getMessage(), e);
transaction.setPaymentStatus(Status.FAILED);
transaction.setStatus(Status.FAILED);
transaction.setResponseCode("99");
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
@@ -71,6 +72,7 @@ public class CityWalletRemotePaymentProcessor implements TransactionProcessorInt
} catch (Exception e) {
e.printStackTrace();
logger.error("Network error during payment processing: {}", e.getMessage(), e);
transaction.setPollingStatus(Status.FAILED);
transaction.setStatus(Status.FAILED);
transaction.setResponseCode("99");
transaction.setSystemErrorMessage("Network error: " + e.getMessage());

View File

@@ -46,6 +46,7 @@ public class EcocashRemotePaymentProcessor implements TransactionProcessorInterf
e.printStackTrace();
logger.error("Network error during payment processing: {}", e.getMessage(), e);
transaction.setStatus(Status.FAILED);
transaction.setPaymentStatus(Status.FAILED);
transaction.setResponseCode("99");
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
transaction.setErrorMessage("Payment failed. Please try again.");
@@ -77,6 +78,7 @@ public class EcocashRemotePaymentProcessor implements TransactionProcessorInterf
e.printStackTrace();
logger.error("Network error during payment processing: {}", e.getMessage(), e);
transaction.setStatus(Status.FAILED);
transaction.setPollingStatus(Status.FAILED);
transaction.setResponseCode("99");
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
transaction.setErrorMessage("Payment failed. Please try again.");

View File

@@ -48,6 +48,7 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
e.printStackTrace();
logger.error("Network error during payment processing: {}", e.getMessage(), e);
transaction.setStatus(Status.FAILED);
transaction.setPaymentStatus(Status.FAILED);
transaction.setResponseCode("99");
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
transaction.setErrorMessage("Payment failed. Please try again");
@@ -62,6 +63,7 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
if(settingService.getBooleanSetting("SIMULATE_MPGS_SUCCESS")) {
transaction.setStatus(Status.SUCCESS);
transaction.setPollingStatus(Status.SUCCESS);
transaction.setResponseCode("02");
transaction.setTargetUrl("/home");
return transaction;
@@ -74,6 +76,7 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
e.printStackTrace();
logger.error("Network error during payment processing: {}", e.getMessage(), e);
transaction.setStatus(Status.FAILED);
transaction.setPollingStatus(Status.FAILED);
transaction.setResponseCode("99");
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
transaction.setErrorMessage("Payment failed. Please try again");

View File

@@ -120,8 +120,8 @@ public class RegistrationWorkflow extends WorkflowDefinition {
Otp otp = otpService.generateOtp(username, "REGISTRATION");
notificationService.sendOtpEmail(email, username, otp.getOtp());
notificationService.sendSms(registerRequest.getPhone(),
"Your Velocity Pay verification code is: " + otp.getOtp());
String message = "Your Velocity Pay verification code is: " + otp.getOtp();
notificationService.sendSms(registerRequest.getPhone(), message);
log.info("otp generated successfully: {}", otp.getOtp());
} catch (Exception e) {
@@ -146,8 +146,8 @@ public class RegistrationWorkflow extends WorkflowDefinition {
Otp otp = otpService.generateOtp(otpRequest.getUsername(), "REGISTRATION");
// The username field in OtpRequest may actually contain the email; use it directly
notificationService.sendOtpEmail(otpRequest.getUsername(), otpRequest.getUsername(), otp.getOtp());
notificationService.sendSms(otpRequest.getPhone(),
"Your Velocity Pay verification code is: " + otp.getOtp());
String message = "Your Velocity Pay verification code is: " + otp.getOtp();
notificationService.sendSms(otpRequest.getPhone(), message);
log.info("otp resent successfully: {}", otp.getOtp());
}

View File

@@ -3,6 +3,7 @@ package zw.qantra.tm.domain.services.processors.workflows.handlers;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import zw.qantra.tm.domain.enums.Status;
import zw.qantra.tm.domain.models.Transaction;
@@ -22,6 +23,10 @@ public class GatewayPaymentHandler implements HandlerInterface {
private final RecipientService recipientService;
private final TransactionEventService transactionEventService;
private final TransactionService transactionService;
private final NotificationService notificationService;
@Value("${wa.api.phone}")
private String waPhone;
@Override
public Object process(Transaction incomingTransaction) throws Exception {
@@ -73,7 +78,12 @@ public class GatewayPaymentHandler implements HandlerInterface {
transaction.setResponseCode("01");
transaction.setErrorMessage(e.getMessage());
transactionService.save(transaction);
return transaction;
}
if(transaction.getPaymentStatus().equals(Status.FAILED)) {
notificationService.sendWA(waPhone, String.format(
"Payment failed: Transaction: %s, Customer message: %s, System message: %s",
transaction.getId(), transaction.getErrorMessage(), transaction.getSystemErrorMessage()));
}
transactionEvent.setStatus(transaction.getStatus());

View File

@@ -3,6 +3,7 @@ package zw.qantra.tm.domain.services.processors.workflows.handlers;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import zw.qantra.tm.domain.enums.RequestType;
import zw.qantra.tm.domain.enums.Status;
@@ -28,6 +29,10 @@ public class IntegrationHandler implements HandlerInterface {
private final RecipientService recipientService;
private final TransactionEventService transactionEventService;
private final TransactionService transactionService;
private final NotificationService notificationService;
@Value("${wa.api.phone}")
private String waPhone;
List<String> lock = new ArrayList<>();
@@ -86,6 +91,12 @@ public class IntegrationHandler implements HandlerInterface {
transaction.setIntegrationStatus(transaction.getStatus());
if(!transaction.getIntegrationStatus().equals(Status.SUCCESS)) {
notificationService.sendWA(waPhone, String.format(
"Integration failed: Transaction %s, Customer message: %s, System message: %s",
transaction.getId(), transaction.getErrorMessage(), transaction.getSystemErrorMessage()));
}
removeLock(transaction.getId().toString());
if(transaction.getStatus() != Status.SUCCESS){
transactionService.save(transaction);

View File

@@ -94,3 +94,4 @@ cloudflare-zone-id=378cea8e50c0d9a158816109b3b1fd8d
wa.api.url=http://173.212.247.232:2785/api/sessions/70eae8dc-2be8-465a-a54b-b6c1d3313699/messages/send-text
wa.api.key=owa_k1_3d2198d81573303f0b48c3c4a6981fd13261b1d0099758eabf4efb53beaba77d
wa.api.phone=263773591219