Compare commits
10 Commits
d53a427a5a
...
be0f0ae49c
| Author | SHA1 | Date | |
|---|---|---|---|
| be0f0ae49c | |||
| ba796527ae | |||
| 1de89364be | |||
| fbc3967215 | |||
| 94a30633ca | |||
| 5d3cfde7f6 | |||
|
|
b9efd83762 | ||
| 220c19123f | |||
| a4d210393e | |||
| 6d48472425 |
14
compose.yml
Normal file
14
compose.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
services:
|
||||||
|
velocity-pay-backend:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
image: velocity-pay-backend:0.0.2-RELEASE
|
||||||
|
restart: always
|
||||||
|
container_name: velocity-pay-backend
|
||||||
|
ports:
|
||||||
|
- 8058:8058
|
||||||
|
- 6950:6950
|
||||||
|
network_mode: host
|
||||||
|
environment:
|
||||||
|
- TZ=Africa/Harare
|
||||||
18
keys/velocityafrica.csr
Normal file
18
keys/velocityafrica.csr
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIIC7TCCAdUCAQAwgacxCzAJBgNVBAYTAlpXMQ8wDQYDVQQIDAZIYXJhcmUxDzAN
|
||||||
|
BgNVBAcMBkhhcmFyZTEYMBYGA1UECgwPV2FsbGV0IEV4Y2hhbmdlMRkwFwYDVQQL
|
||||||
|
DBBEaWdpdGFsIFBheW1lbnRzMR0wGwYDVQQDDBQqLnZlbG9jaXR5YWZyaWNhLm5l
|
||||||
|
dDEiMCAGCSqGSIb3DQEJARYTdnVzYWtob3phQGdtYWlsLmNvbTCCASIwDQYJKoZI
|
||||||
|
hvcNAQEBBQADggEPADCCAQoCggEBALl1Pvoh+NUK9A8KlwgLkAIiDs3l7Kbs2Zt5
|
||||||
|
FZvyOgpjD6Cl/IJy7DC8oJ7Ty+eJkoVKPjyX7urnf1wQgstQMgryA7YMVnQPcYJe
|
||||||
|
Zm3px+lPhbkEEeVc5veNktCqL590LLMrL6IZbGR1Xh8Phd7niLn1+o+ZebgWH6XD
|
||||||
|
nIb8JFrBTy5ZigU/dGBpII/NhciIVQDF4TPy5DwfNIBAAKZdp/CiYpTFN0iV7/UA
|
||||||
|
0g43zfS3CbuEK+Mj6BkkSquWHFd76W58BAhDa2S50sd6VF+jq4EFCdWmJXmxVmPI
|
||||||
|
rxUMFi9DbI7Cd9DB56pkfnSIYx0t60SjXKy3gkNdB6zcNcFZ860CAwEAAaAAMA0G
|
||||||
|
CSqGSIb3DQEBCwUAA4IBAQBK4YsEvIQolqsVeqUSxUforA1qo/iKhK+yetlQ8YdN
|
||||||
|
hR/v+4fIIoaIZLjdSTOLDTDIJ3AUBGlKvF7mf64X+JQpyQVqUIx58S92Zr645lfU
|
||||||
|
LADsliDXCNQp0nzWDavAC9HvbA4ibl+Z1X+z/uojf3fPZEmAli2howpWYiLIsQSj
|
||||||
|
quS5L3kkv8XhYBnE0h3L4GL3kp7bFAMRzJq3392pU3xAGiJhBS3oKyBel8mfWrTE
|
||||||
|
MQDsFgK6bjy2JWRgmb5lqKSV1KlqbG5zmBkSgFcEkrB9tm7DtQbo5oPSDKO5otWf
|
||||||
|
Wn40iNGAnSRhsc0jjXR1s1oqGQh7SrEhOvm9JI76LfGh
|
||||||
|
-----END CERTIFICATE REQUEST-----
|
||||||
28
keys/velocityafrica.key
Normal file
28
keys/velocityafrica.key
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5dT76IfjVCvQP
|
||||||
|
CpcIC5ACIg7N5eym7NmbeRWb8joKYw+gpfyCcuwwvKCe08vniZKFSj48l+7q539c
|
||||||
|
EILLUDIK8gO2DFZ0D3GCXmZt6cfpT4W5BBHlXOb3jZLQqi+fdCyzKy+iGWxkdV4f
|
||||||
|
D4Xe54i59fqPmXm4Fh+lw5yG/CRawU8uWYoFP3RgaSCPzYXIiFUAxeEz8uQ8HzSA
|
||||||
|
QACmXafwomKUxTdIle/1ANION830twm7hCvjI+gZJEqrlhxXe+lufAQIQ2tkudLH
|
||||||
|
elRfo6uBBQnVpiV5sVZjyK8VDBYvQ2yOwnfQweeqZH50iGMdLetEo1yst4JDXQes
|
||||||
|
3DXBWfOtAgMBAAECggEAE8cSIUCwNaAGaPg7JQt+nwucwo5rj12g0zi1ejz5vZPU
|
||||||
|
3c/1vr+cupHTGz0A+L8uFfLV8kZNn1VyupG0MRRrUcl/ZdGpApWHCF0i1UPiItpt
|
||||||
|
K07ozan7o5jAeGo9y+ZqweywFrxZV9lAYVWZdC0C4rn9r4Sxe1U4qMfUkHyhL+BQ
|
||||||
|
o2Ot2qxfHbbV/mNZcSlQHLByRu1tuVT8TxS5ZOqdu0ar8QnyoHr9tk6+x6WgCONr
|
||||||
|
K/Hvjej9BL6KrB2/vK52A8PclPJAqb8w5W8c0jQHhS9dAJV5t1KHXAejBz396vn3
|
||||||
|
PowurUTyu7RrVVK49j9/q0utPl2tosTOhPNobzY6wQKBgQD8iCyuCLMawh84i8qq
|
||||||
|
SFqyNI0bc2nWuF74QrCc/3NScUdOM8oMzUd5vskEyAa3yl1Xf0Ffg/nMO70E/3Ra
|
||||||
|
rvLoFnfS/WXHrY8TkSpNI6TY/gtf/F8LOW2HZemWSBZ4Q/iatfTX+gL/3cZFE9F6
|
||||||
|
dAbA8wcmGNR3GBKbDorxKhSv3QKBgQC8AUKI5ijfmqCnilqNrpiegxcAdGT8au1W
|
||||||
|
uIW9CjdXS9c1D/+cPFGRc+vLIqWUE7vStkSl6rzY4Va8uqh7t8P9MksE8ru8QcbD
|
||||||
|
Sq2RwO1vBPnNmb7eS/ooyRbYFOXlrSx7mntPkXUZE/c7Lpqe7XxeC+R/wsZc8fyd
|
||||||
|
H8RXlCH+EQKBgQCJNhBYy19NpbZDCimnFkM5WrZk+PPD+E+Zwtqlo2Lso6Ijyp35
|
||||||
|
ELzKWLBuiaSkzi6jcQB7PoFGyBqvEYIOF8rh8ftPR+G6egIolpKOcVSLlpVlpQGb
|
||||||
|
Xqu1itk9j5Ot6vi0TzNm+nAQyFaHh/ok99AHnMUAnTMsNoc9esxhtwSgfQKBgAoF
|
||||||
|
MyuiwMjyL9/eIudsR9wi9oXirkM5276EhTRHKB3x/91nJeOI33wWJpokFZkn2Bnp
|
||||||
|
9wy0zy3sDLhwZmx5peuH07HG0jS9eL+N6mRbWQxSwpGvwRmOCR5FYX9Q1dQA/97y
|
||||||
|
o+HgydH1W3b/C+SumbNVhO8+TV5E04b4W3mjfpBRAoGBAJMnFV0ivN+TN4/czmAx
|
||||||
|
4JulU6mh0qCfax6tMbx5RiXmlHitAXQvPooFpzItLWlrRnXj6aHHqXOs5uH0kspj
|
||||||
|
4pTnDGnQO9VxhRziEjPIAVS6vFntxOs0zshaROreLcaVoDSkmz6YkFTeiSbtzumo
|
||||||
|
rGOjofBa6j9pYfi9YCi8nSnK
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package zw.qantra.tm.domain.dtos.sms;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SmsPopCampaignRequest {
|
||||||
|
private String name;
|
||||||
|
private String message;
|
||||||
|
private String sender_id;
|
||||||
|
@Builder.Default
|
||||||
|
private String contact_import_method = "manual";
|
||||||
|
private String manual_contacts;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package zw.qantra.tm.domain.models;
|
package zw.qantra.tm.domain.models;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import zw.qantra.tm.domain.enums.Status;
|
import zw.qantra.tm.domain.enums.Status;
|
||||||
@@ -16,6 +17,7 @@ import zw.qantra.tm.domain.enums.Status;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class Otp extends BaseEntity{
|
public class Otp extends BaseEntity{
|
||||||
private String username;
|
private String username;
|
||||||
|
@JsonIgnore
|
||||||
private String otp;
|
private String otp;
|
||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
@Column(name = "otp_status")
|
@Column(name = "otp_status")
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ public class Transaction extends BaseEntity {
|
|||||||
@Enumerated(EnumType.STRING)
|
@Enumerated(EnumType.STRING)
|
||||||
private CurrencyType creditCurrency;
|
private CurrencyType creditCurrency;
|
||||||
private BigDecimal creditAmount;
|
private BigDecimal creditAmount;
|
||||||
|
private BigDecimal creditTotalAmount;
|
||||||
private String creditName;
|
private String creditName;
|
||||||
private String creditCard;
|
private String creditCard;
|
||||||
private String creditRef;
|
private String creditRef;
|
||||||
|
|||||||
@@ -22,5 +22,5 @@ public interface TransactionRepository extends JpaRepository<Transaction, UUID>,
|
|||||||
List<Transaction> findAllByWorkspaceIdIsNullAndUserIdIsNotNull();
|
List<Transaction> findAllByWorkspaceIdIsNullAndUserIdIsNotNull();
|
||||||
List<Transaction> findAllByConfirmationStatusAndPaymentStatusAndIntegrationStatus(
|
List<Transaction> findAllByConfirmationStatusAndPaymentStatusAndIntegrationStatus(
|
||||||
Status s1, Status s2, Status s3);
|
Status s1, Status s2, Status s3);
|
||||||
List<Transaction> findAllByPaymentStatusAndPollingStatus(Status s1, Status s2);
|
List<Transaction> findAllByPollingStatus(Status s2);
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,7 @@ public class JobService {
|
|||||||
|
|
||||||
public void checkOrphanedTransactions() {
|
public void checkOrphanedTransactions() {
|
||||||
List<Transaction> transactions = transactionService.getTransactionRepository()
|
List<Transaction> transactions = transactionService.getTransactionRepository()
|
||||||
.findAllByPaymentStatusAndPollingStatus(Status.SUCCESS, Status.PENDING);
|
.findAllByPollingStatus(Status.PENDING);
|
||||||
if (!transactions.isEmpty())
|
if (!transactions.isEmpty())
|
||||||
log.info("Transaction count {}", transactions.size());
|
log.info("Transaction count {}", transactions.size());
|
||||||
|
|
||||||
@@ -47,8 +47,13 @@ public class JobService {
|
|||||||
int maxRetries = settingService.getIntegerSetting("MAX_RETRIES");
|
int maxRetries = settingService.getIntegerSetting("MAX_RETRIES");
|
||||||
int retries = transaction.getRetries() == null ? 0 : transaction.getRetries();
|
int retries = transaction.getRetries() == null ? 0 : transaction.getRetries();
|
||||||
|
|
||||||
if (retries >= maxRetries)
|
if (retries >= maxRetries) {
|
||||||
break;
|
transaction.setPaymentStatus(Status.FAILED);
|
||||||
|
transaction.setPollingStatus(Status.FAILED);
|
||||||
|
transaction.setErrorMessage("Maximum retries reached");
|
||||||
|
transactionService.save(transaction);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
transaction.setRetries(retries + 1);
|
transaction.setRetries(retries + 1);
|
||||||
// polling logic
|
// polling logic
|
||||||
@@ -106,8 +111,8 @@ public class JobService {
|
|||||||
|
|
||||||
success++;
|
success++;
|
||||||
}else {
|
}else {
|
||||||
transaction.setPollingStatus(Status.FAILED);
|
transaction.setPollingStatus(Status.PENDING);
|
||||||
transaction.setIntegrationStatus(Status.FAILED);
|
transaction.setIntegrationStatus(Status.PENDING);
|
||||||
transactionService.save(transaction);
|
transactionService.save(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,16 +12,14 @@ import org.springframework.scheduling.annotation.Async;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import jakarta.mail.internet.MimeMessage;
|
import jakarta.mail.internet.MimeMessage;
|
||||||
import zw.qantra.tm.domain.dtos.sms.SmsApiResponse;
|
import zw.qantra.tm.domain.dtos.sms.SmsPopCampaignRequest;
|
||||||
import zw.qantra.tm.domain.dtos.sms.SmsBatchRequest;
|
|
||||||
import zw.qantra.tm.domain.dtos.sms.SmsMessage;
|
|
||||||
import zw.qantra.tm.rest.RestService;
|
import zw.qantra.tm.rest.RestService;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collections;
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -32,13 +30,18 @@ public class NotificationService {
|
|||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
private final JavaMailSender emailSender;
|
private final JavaMailSender emailSender;
|
||||||
|
|
||||||
@Value("${zss.sms.api.url}")
|
@Value("${sms-pop.url}")
|
||||||
private String smsApiUrl;
|
private String smsPopUrl;
|
||||||
@Value("${zss.sms.api.auth}")
|
@Value("${sms-pop.apikey}")
|
||||||
private String smsApiAuth;
|
private String smsPopApiKey;
|
||||||
@Value("${sms.debug}")
|
@Value("${sms.debug}")
|
||||||
private Boolean smsDebug;
|
private Boolean smsDebug;
|
||||||
|
|
||||||
|
@Value("${wa.api.url}")
|
||||||
|
private String waApiUrl;
|
||||||
|
@Value("${wa.api.key}")
|
||||||
|
private String waApiKey;
|
||||||
|
|
||||||
@Async
|
@Async
|
||||||
public void sendEmail(String to, String subject, String text) {
|
public void sendEmail(String to, String subject, String text) {
|
||||||
sendEmailWithHtml(to, subject, text, null);
|
sendEmailWithHtml(to, subject, text, null);
|
||||||
@@ -101,6 +104,24 @@ public class NotificationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
|
public void sendWA(String chatId, String text) {
|
||||||
|
try {
|
||||||
|
Map<String, String> payload = new HashMap<>();
|
||||||
|
payload.put("chatId", String.format("%s@c.us", chatId));
|
||||||
|
payload.put("text", text);
|
||||||
|
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.set("X-API-Key", waApiKey);
|
||||||
|
|
||||||
|
restService.postWithExternalAuth(waApiUrl, payload, headers, Object.class);
|
||||||
|
|
||||||
|
logger.info("WA message sent to {}: {}", chatId, text);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Failed to send WA message to {}: {}", chatId, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Async
|
@Async
|
||||||
public void sendSms(String to, String message) {
|
public void sendSms(String to, String message) {
|
||||||
if(smsDebug) {
|
if(smsDebug) {
|
||||||
@@ -108,28 +129,25 @@ public class NotificationService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
SmsMessage smsMessage = SmsMessage.builder()
|
String phoneNumber = to;
|
||||||
.reference(UUID.randomUUID().toString())
|
if (phoneNumber.startsWith("+")) {
|
||||||
.message(message)
|
phoneNumber = phoneNumber.substring(1);
|
||||||
.msisdn(to)
|
}
|
||||||
.build();
|
|
||||||
|
|
||||||
SmsBatchRequest batchRequest = SmsBatchRequest.builder()
|
SmsPopCampaignRequest campaignRequest = SmsPopCampaignRequest.builder()
|
||||||
.batchReference(UUID.randomUUID().toString())
|
.name("Velocity Payments")
|
||||||
.smsList(Collections.singletonList(smsMessage))
|
.message(message)
|
||||||
|
.sender_id("Velocity")
|
||||||
|
.contact_import_method("manual")
|
||||||
|
.manual_contacts(phoneNumber)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.set("Authorization", smsApiAuth);
|
headers.set("Authorization", "Bearer " + smsPopApiKey);
|
||||||
|
|
||||||
SmsApiResponse response = restService.postWithExternalAuth(
|
restService.postAs(smsPopUrl, campaignRequest, headers, Object.class);
|
||||||
smsApiUrl,
|
|
||||||
batchRequest,
|
|
||||||
headers,
|
|
||||||
SmsApiResponse.class
|
|
||||||
);
|
|
||||||
|
|
||||||
logger.info("SMS sent to {} - Status: {}, Result: {}", to, response.getStatus(), response.getResult());
|
logger.info("SMS sent to {} via SMSPOP", to);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to send SMS to {}: {}", to, e.getMessage(), e);
|
logger.error("Failed to send SMS to {}: {}", to, e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.springframework.data.domain.Pageable;
|
|||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import zw.qantra.tm.domain.enums.CurrencyType;
|
||||||
import zw.qantra.tm.domain.enums.RequestType;
|
import zw.qantra.tm.domain.enums.RequestType;
|
||||||
import zw.qantra.tm.domain.models.AdditionalData;
|
import zw.qantra.tm.domain.models.AdditionalData;
|
||||||
import zw.qantra.tm.domain.models.Currency;
|
import zw.qantra.tm.domain.models.Currency;
|
||||||
@@ -33,23 +34,20 @@ public class TransactionService {
|
|||||||
private final AdditionalDataService additionalDataService;
|
private final AdditionalDataService additionalDataService;
|
||||||
private final CurrencyService currencyService;
|
private final CurrencyService currencyService;
|
||||||
|
|
||||||
public BigDecimal calculateCreditAmount(Transaction transaction) {
|
public BigDecimal calculateCurrencyExchangeValue(CurrencyType from, CurrencyType to, BigDecimal amount) {
|
||||||
if (transaction.getCreditCurrency() == null) {
|
if (to == null) {
|
||||||
return BigDecimal.ZERO;
|
return BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
Currency debitCurrency = currencyService.findCurrencyByIsoCode(transaction.getDebitCurrency().name());
|
Currency debitCurrency = currencyService.findCurrencyByIsoCode(from.name());
|
||||||
Currency creditCurrency = currencyService.findCurrencyByIsoCode(transaction.getCreditCurrency().name());
|
Currency creditCurrency = currencyService.findCurrencyByIsoCode(to.name());
|
||||||
|
|
||||||
BigDecimal debitBankRate = new BigDecimal(debitCurrency.getBankRate());
|
BigDecimal debitBankRate = new BigDecimal(debitCurrency.getBankRate());
|
||||||
BigDecimal creditBankRate = new BigDecimal(creditCurrency.getBankRate());
|
BigDecimal creditBankRate = new BigDecimal(creditCurrency.getBankRate());
|
||||||
|
|
||||||
BigDecimal bankRate = creditBankRate.divide(debitBankRate, 4, RoundingMode.HALF_UP);
|
BigDecimal bankRate = creditBankRate.divide(debitBankRate, 4, RoundingMode.HALF_UP);
|
||||||
|
|
||||||
BigDecimal creditAmount = transaction.getAmount().multiply(bankRate).setScale(4, RoundingMode.HALF_UP);
|
return amount.multiply(bankRate).setScale(4, RoundingMode.HALF_UP);
|
||||||
|
|
||||||
transaction.setCreditAmount(creditAmount);
|
|
||||||
return creditAmount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reassignTransactions(UUID oldWorkspaceId, UUID newWorkspaceId){
|
public void reassignTransactions(UUID oldWorkspaceId, UUID newWorkspaceId){
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ public class VelocityPaymentService {
|
|||||||
? "VMC" : transaction.getPaymentProcessorLabel();
|
? "VMC" : transaction.getPaymentProcessorLabel();
|
||||||
VelocityTransactionDto payload = VelocityTransactionDto.builder()
|
VelocityTransactionDto payload = VelocityTransactionDto.builder()
|
||||||
.salesOrderId(transaction.getOrderId())
|
.salesOrderId(transaction.getOrderId())
|
||||||
.amount(transaction.getCreditAmount())
|
.amount(transaction.getCreditTotalAmount())
|
||||||
.debitPhone(transaction.getDebitPhone())
|
.debitPhone(transaction.getDebitPhone())
|
||||||
.debitRegion("ZW")
|
.debitRegion("ZW")
|
||||||
.type("REQUEST")
|
.type("REQUEST")
|
||||||
|
|||||||
@@ -56,8 +56,9 @@ public class NetoneConfirmationHotProcessor implements TransactionProcessorInter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction.setCreditCurrency(CurrencyType.USD);
|
transaction.setCreditCurrency(transaction.getDebitCurrency());
|
||||||
transaction.setCreditAmount(transaction.getAmount());
|
transaction.setCreditAmount(transaction.getAmount());
|
||||||
|
transaction.setCreditTotalAmount(transaction.getTotalAmount());
|
||||||
transaction.setCreditAccount(Utils.formatPhoneNumber(transaction.getCreditAccount(), "ZW"));
|
transaction.setCreditAccount(Utils.formatPhoneNumber(transaction.getCreditAccount(), "ZW"));
|
||||||
transaction.setStatus(Status.SUCCESS);
|
transaction.setStatus(Status.SUCCESS);
|
||||||
transaction.setResponseCode("00");
|
transaction.setResponseCode("00");
|
||||||
|
|||||||
@@ -5,14 +5,11 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import zw.qantra.tm.domain.enums.CurrencyType;
|
import zw.qantra.tm.domain.enums.CurrencyType;
|
||||||
import zw.qantra.tm.domain.enums.RequestType;
|
import zw.qantra.tm.domain.enums.RequestType;
|
||||||
import zw.qantra.tm.domain.enums.Status;
|
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.Provider;
|
|
||||||
import zw.qantra.tm.domain.models.Transaction;
|
import zw.qantra.tm.domain.models.Transaction;
|
||||||
import zw.qantra.tm.domain.services.*;
|
import zw.qantra.tm.domain.services.*;
|
||||||
import zw.qantra.tm.domain.services.processors.TransactionProcessorInterface;
|
import zw.qantra.tm.domain.services.processors.TransactionProcessorInterface;
|
||||||
@@ -20,7 +17,6 @@ import zw.qantra.tm.exceptions.ApiException;
|
|||||||
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.math.BigDecimal;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@Service("CONFIRM_ZESA_HOT")
|
@Service("CONFIRM_ZESA_HOT")
|
||||||
@@ -69,7 +65,14 @@ public class ZesaConfirmationHotProcessor implements TransactionProcessorInterfa
|
|||||||
transaction.setCreditCurrency(CurrencyType.USD);
|
transaction.setCreditCurrency(CurrencyType.USD);
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction.setCreditAmount(transactionService.calculateCreditAmount(transaction));
|
transaction.setCreditAmount(transactionService.calculateCurrencyExchangeValue(
|
||||||
|
transaction.getDebitCurrency(),
|
||||||
|
transaction.getCreditCurrency(),
|
||||||
|
transaction.getAmount()));
|
||||||
|
transaction.setCreditTotalAmount(transactionService.calculateCurrencyExchangeValue(
|
||||||
|
transaction.getDebitCurrency(),
|
||||||
|
transaction.getCreditCurrency(),
|
||||||
|
transaction.getTotalAmount()));
|
||||||
|
|
||||||
// token should've been updated by checkCustomer
|
// token should've been updated by checkCustomer
|
||||||
if (!hotRechargeBalanceService.checkBalance(token, transaction.getCreditAmount(), accId)) {
|
if (!hotRechargeBalanceService.checkBalance(token, transaction.getCreditAmount(), accId)) {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public class CityWalletRemotePaymentProcessor implements TransactionProcessorInt
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
||||||
|
transaction.setPaymentStatus(Status.FAILED);
|
||||||
transaction.setStatus(Status.FAILED);
|
transaction.setStatus(Status.FAILED);
|
||||||
transaction.setResponseCode("99");
|
transaction.setResponseCode("99");
|
||||||
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
||||||
@@ -71,6 +72,7 @@ public class CityWalletRemotePaymentProcessor implements TransactionProcessorInt
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
||||||
|
transaction.setPollingStatus(Status.FAILED);
|
||||||
transaction.setStatus(Status.FAILED);
|
transaction.setStatus(Status.FAILED);
|
||||||
transaction.setResponseCode("99");
|
transaction.setResponseCode("99");
|
||||||
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class EcocashRemotePaymentProcessor implements TransactionProcessorInterf
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
||||||
transaction.setStatus(Status.FAILED);
|
transaction.setStatus(Status.FAILED);
|
||||||
|
transaction.setPaymentStatus(Status.FAILED);
|
||||||
transaction.setResponseCode("99");
|
transaction.setResponseCode("99");
|
||||||
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
||||||
transaction.setErrorMessage("Payment failed. Please try again.");
|
transaction.setErrorMessage("Payment failed. Please try again.");
|
||||||
@@ -77,6 +78,7 @@ public class EcocashRemotePaymentProcessor implements TransactionProcessorInterf
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
||||||
transaction.setStatus(Status.FAILED);
|
transaction.setStatus(Status.FAILED);
|
||||||
|
transaction.setPollingStatus(Status.FAILED);
|
||||||
transaction.setResponseCode("99");
|
transaction.setResponseCode("99");
|
||||||
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
||||||
transaction.setErrorMessage("Payment failed. Please try again.");
|
transaction.setErrorMessage("Payment failed. Please try again.");
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
||||||
transaction.setStatus(Status.FAILED);
|
transaction.setStatus(Status.FAILED);
|
||||||
|
transaction.setPaymentStatus(Status.FAILED);
|
||||||
transaction.setResponseCode("99");
|
transaction.setResponseCode("99");
|
||||||
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
||||||
transaction.setErrorMessage("Payment failed. Please try again");
|
transaction.setErrorMessage("Payment failed. Please try again");
|
||||||
@@ -62,6 +63,7 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
|
|||||||
|
|
||||||
if(settingService.getBooleanSetting("SIMULATE_MPGS_SUCCESS")) {
|
if(settingService.getBooleanSetting("SIMULATE_MPGS_SUCCESS")) {
|
||||||
transaction.setStatus(Status.SUCCESS);
|
transaction.setStatus(Status.SUCCESS);
|
||||||
|
transaction.setPollingStatus(Status.SUCCESS);
|
||||||
transaction.setResponseCode("02");
|
transaction.setResponseCode("02");
|
||||||
transaction.setTargetUrl("/home");
|
transaction.setTargetUrl("/home");
|
||||||
return transaction;
|
return transaction;
|
||||||
@@ -74,6 +76,7 @@ public class MPGSWebPaymentProcessor implements TransactionProcessorInterface {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
logger.error("Network error during payment processing: {}", e.getMessage(), e);
|
||||||
transaction.setStatus(Status.FAILED);
|
transaction.setStatus(Status.FAILED);
|
||||||
|
transaction.setPollingStatus(Status.FAILED);
|
||||||
transaction.setResponseCode("99");
|
transaction.setResponseCode("99");
|
||||||
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
transaction.setSystemErrorMessage("Network error: " + e.getMessage());
|
||||||
transaction.setErrorMessage("Payment failed. Please try again");
|
transaction.setErrorMessage("Payment failed. Please try again");
|
||||||
|
|||||||
@@ -120,8 +120,8 @@ public class RegistrationWorkflow extends WorkflowDefinition {
|
|||||||
Otp otp = otpService.generateOtp(username, "REGISTRATION");
|
Otp otp = otpService.generateOtp(username, "REGISTRATION");
|
||||||
|
|
||||||
notificationService.sendOtpEmail(email, username, otp.getOtp());
|
notificationService.sendOtpEmail(email, username, otp.getOtp());
|
||||||
notificationService.sendSms(registerRequest.getPhone(),
|
String message = "Your Velocity Pay verification code is: " + otp.getOtp();
|
||||||
"Your Velocity Pay verification code is: " + otp.getOtp());
|
notificationService.sendSms(registerRequest.getPhone(), message);
|
||||||
|
|
||||||
log.info("otp generated successfully: {}", otp.getOtp());
|
log.info("otp generated successfully: {}", otp.getOtp());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -146,8 +146,8 @@ public class RegistrationWorkflow extends WorkflowDefinition {
|
|||||||
Otp otp = otpService.generateOtp(otpRequest.getUsername(), "REGISTRATION");
|
Otp otp = otpService.generateOtp(otpRequest.getUsername(), "REGISTRATION");
|
||||||
// The username field in OtpRequest may actually contain the email; use it directly
|
// The username field in OtpRequest may actually contain the email; use it directly
|
||||||
notificationService.sendOtpEmail(otpRequest.getUsername(), otpRequest.getUsername(), otp.getOtp());
|
notificationService.sendOtpEmail(otpRequest.getUsername(), otpRequest.getUsername(), otp.getOtp());
|
||||||
notificationService.sendSms(otpRequest.getPhone(),
|
String message = "Your Velocity Pay verification code is: " + otp.getOtp();
|
||||||
"Your Velocity Pay verification code is: " + otp.getOtp());
|
notificationService.sendSms(otpRequest.getPhone(), message);
|
||||||
|
|
||||||
log.info("otp resent successfully: {}", otp.getOtp());
|
log.info("otp resent successfully: {}", otp.getOtp());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package zw.qantra.tm.domain.services.processors.workflows.handlers;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import zw.qantra.tm.domain.enums.Status;
|
import zw.qantra.tm.domain.enums.Status;
|
||||||
import zw.qantra.tm.domain.models.Transaction;
|
import zw.qantra.tm.domain.models.Transaction;
|
||||||
@@ -22,6 +23,10 @@ public class GatewayPaymentHandler implements HandlerInterface {
|
|||||||
private final RecipientService recipientService;
|
private final RecipientService recipientService;
|
||||||
private final TransactionEventService transactionEventService;
|
private final TransactionEventService transactionEventService;
|
||||||
private final TransactionService transactionService;
|
private final TransactionService transactionService;
|
||||||
|
private final NotificationService notificationService;
|
||||||
|
|
||||||
|
@Value("${wa.api.phone}")
|
||||||
|
private String waPhone;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object process(Transaction incomingTransaction) throws Exception {
|
public Object process(Transaction incomingTransaction) throws Exception {
|
||||||
@@ -73,7 +78,12 @@ public class GatewayPaymentHandler implements HandlerInterface {
|
|||||||
transaction.setResponseCode("01");
|
transaction.setResponseCode("01");
|
||||||
transaction.setErrorMessage(e.getMessage());
|
transaction.setErrorMessage(e.getMessage());
|
||||||
transactionService.save(transaction);
|
transactionService.save(transaction);
|
||||||
return transaction;
|
}
|
||||||
|
|
||||||
|
if(Status.FAILED.equals(transaction.getPaymentStatus())) {
|
||||||
|
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());
|
transactionEvent.setStatus(transaction.getStatus());
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package zw.qantra.tm.domain.services.processors.workflows.handlers;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import zw.qantra.tm.domain.enums.RequestType;
|
import zw.qantra.tm.domain.enums.RequestType;
|
||||||
import zw.qantra.tm.domain.enums.Status;
|
import zw.qantra.tm.domain.enums.Status;
|
||||||
@@ -28,6 +29,10 @@ public class IntegrationHandler implements HandlerInterface {
|
|||||||
private final RecipientService recipientService;
|
private final RecipientService recipientService;
|
||||||
private final TransactionEventService transactionEventService;
|
private final TransactionEventService transactionEventService;
|
||||||
private final TransactionService transactionService;
|
private final TransactionService transactionService;
|
||||||
|
private final NotificationService notificationService;
|
||||||
|
|
||||||
|
@Value("${wa.api.phone}")
|
||||||
|
private String waPhone;
|
||||||
|
|
||||||
List<String> lock = new ArrayList<>();
|
List<String> lock = new ArrayList<>();
|
||||||
|
|
||||||
@@ -86,6 +91,12 @@ public class IntegrationHandler implements HandlerInterface {
|
|||||||
|
|
||||||
transaction.setIntegrationStatus(transaction.getStatus());
|
transaction.setIntegrationStatus(transaction.getStatus());
|
||||||
|
|
||||||
|
if(!Status.SUCCESS.equals(transaction.getIntegrationStatus())) {
|
||||||
|
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());
|
removeLock(transaction.getId().toString());
|
||||||
if(transaction.getStatus() != Status.SUCCESS){
|
if(transaction.getStatus() != Status.SUCCESS){
|
||||||
transactionService.save(transaction);
|
transactionService.save(transaction);
|
||||||
|
|||||||
@@ -84,9 +84,14 @@ jobrunr.datasource.password=
|
|||||||
app.reports.storage-path=/srv/data/reports
|
app.reports.storage-path=/srv/data/reports
|
||||||
app.base-url=https://payapi.velocityafrica.net
|
app.base-url=https://payapi.velocityafrica.net
|
||||||
|
|
||||||
zss.sms.api.url=https://secure.zss.co.zw/vportal/cnm/vsms/json/batch
|
|
||||||
zss.sms.api.auth=Basic UWFudHJhdGVjaDpVbUk3OUpwUDh3QTY=
|
|
||||||
sms.debug=false
|
sms.debug=false
|
||||||
|
|
||||||
|
sms-pop.url=https://smspop.co.zw/api/campaigns
|
||||||
|
sms-pop.apikey=108|ypBpUtJGlPzelxJl2aySp672I9KKbyaQPtcxMPBrfb70be27
|
||||||
|
|
||||||
cloudflare-token=cfut_U0qhvhzAATLqHQa9lad7oRmBmPoJ6n9uIoCBbNOWc9884f18
|
cloudflare-token=cfut_U0qhvhzAATLqHQa9lad7oRmBmPoJ6n9uIoCBbNOWc9884f18
|
||||||
cloudflare-zone-id=378cea8e50c0d9a158816109b3b1fd8d
|
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
|
||||||
@@ -1,23 +1,8 @@
|
|||||||
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
|
||||||
<changeSet author="khoza (generated)" id="1782340507017-3">
|
<changeSet author="khoza (generated)" id="1783202068979-3">
|
||||||
<addColumn tableName="transaction">
|
<addColumn tableName="transaction">
|
||||||
<column name="batch_description" type="varchar(255)"/>
|
<column name="credit_total_amount" type="numeric(38, 2)"/>
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
<changeSet author="khoza (generated)" id="1782340507017-4">
|
|
||||||
<addColumn tableName="group_batch_item">
|
|
||||||
<column name="credit_address" type="varchar(255)"/>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
<changeSet author="khoza (generated)" id="1782340507017-5">
|
|
||||||
<addColumn tableName="payment_processor">
|
|
||||||
<column name="currency" type="varchar(255)"/>
|
|
||||||
</addColumn>
|
|
||||||
</changeSet>
|
|
||||||
<changeSet author="khoza (generated)" id="1782340507017-6">
|
|
||||||
<addColumn tableName="transaction">
|
|
||||||
<column name="username" type="varchar(255)"/>
|
|
||||||
</addColumn>
|
</addColumn>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ class TransactionServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Should calculate credit amount using bank rate")
|
@DisplayName("Should calculate credit amount using bank rate")
|
||||||
void shouldCalculateCreditAmount() {
|
void shouldCalculateCurrencyExchangeValue() {
|
||||||
Currency currencyUsd = new Currency();
|
Currency currencyUsd = new Currency();
|
||||||
currencyUsd.setBankRate("1.0");
|
currencyUsd.setBankRate("1.0");
|
||||||
Currency currencyZwl = new Currency();
|
Currency currencyZwl = new Currency();
|
||||||
@@ -130,10 +130,12 @@ class TransactionServiceTest {
|
|||||||
when(currencyService.findCurrencyByIsoCode("USD")).thenReturn(currencyUsd);
|
when(currencyService.findCurrencyByIsoCode("USD")).thenReturn(currencyUsd);
|
||||||
when(currencyService.findCurrencyByIsoCode("ZWL")).thenReturn(currencyZwl);
|
when(currencyService.findCurrencyByIsoCode("ZWL")).thenReturn(currencyZwl);
|
||||||
|
|
||||||
BigDecimal creditAmount = transactionService.calculateCreditAmount(transaction);
|
BigDecimal creditAmount = transactionService.calculateCurrencyExchangeValue(
|
||||||
|
transaction.getDebitCurrency(),
|
||||||
|
transaction.getCreditCurrency(),
|
||||||
|
transaction.getAmount());
|
||||||
|
|
||||||
assertEquals(new BigDecimal("1500.0000"), creditAmount);
|
assertEquals(new BigDecimal("1500.0000"), creditAmount);
|
||||||
assertEquals(new BigDecimal("1500.0000"), transaction.getCreditAmount());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -141,7 +143,10 @@ class TransactionServiceTest {
|
|||||||
void shouldReturnZeroWhenCreditCurrencyNull() {
|
void shouldReturnZeroWhenCreditCurrencyNull() {
|
||||||
transaction.setCreditCurrency(null);
|
transaction.setCreditCurrency(null);
|
||||||
|
|
||||||
BigDecimal result = transactionService.calculateCreditAmount(transaction);
|
BigDecimal result = transactionService.calculateCurrencyExchangeValue(
|
||||||
|
transaction.getDebitCurrency(),
|
||||||
|
transaction.getCreditCurrency(),
|
||||||
|
transaction.getAmount());
|
||||||
|
|
||||||
assertEquals(BigDecimal.ZERO, result);
|
assertEquals(BigDecimal.ZERO, result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ class GatewayPaymentHandlerTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private TransactionProcessorInterface transactionProcessor;
|
private TransactionProcessorInterface transactionProcessor;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private NotificationService notificationService;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private GatewayPaymentHandler handler;
|
private GatewayPaymentHandler handler;
|
||||||
|
|
||||||
@@ -63,7 +66,7 @@ class GatewayPaymentHandlerTest {
|
|||||||
transaction.setType(RequestType.REQUEST);
|
transaction.setType(RequestType.REQUEST);
|
||||||
transaction.setAuthType(AuthType.MOBILE);
|
transaction.setAuthType(AuthType.MOBILE);
|
||||||
transaction.setPaymentProcessorLabel("ecocash");
|
transaction.setPaymentProcessorLabel("ecocash");
|
||||||
transaction.setPaymentStatus(null);
|
transaction.setPaymentStatus(Status.PENDING);
|
||||||
|
|
||||||
lenient().when(transactionService.getTransactionRepository()).thenReturn(transactionRepository);
|
lenient().when(transactionService.getTransactionRepository()).thenReturn(transactionRepository);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ class IntegrationHandlerTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private TransactionProcessorInterface transactionProcessor;
|
private TransactionProcessorInterface transactionProcessor;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private NotificationService notificationService;
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private IntegrationHandler handler;
|
private IntegrationHandler handler;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user