bug fixes
This commit is contained in:
@@ -23,6 +23,7 @@ import java.util.UUID;
|
||||
public class Transaction extends BaseEntity {
|
||||
private String userId;
|
||||
private String trace;
|
||||
private String region;
|
||||
private BigDecimal amount;
|
||||
private BigDecimal charge;
|
||||
private BigDecimal gatewayCharge;
|
||||
|
||||
@@ -15,4 +15,5 @@ public interface ChargeRepository extends JpaRepository<Charge, UUID> {
|
||||
List<Charge> findAllByCurrency(CurrencyType currency);
|
||||
boolean existsByChargeLabelAndCurrency(ChargeLabelEnum chargeLabel, CurrencyType currency);
|
||||
boolean existsByChargeLabelAndCurrencyAndPercentageRate(ChargeLabelEnum chargeLabel, CurrencyType currency, BigDecimal percentageRate);
|
||||
boolean existsByChargeLabelAndCurrencyAndDescription(ChargeLabelEnum chargeLabel, CurrencyType currency, String description);
|
||||
}
|
||||
@@ -34,52 +34,6 @@ public class HotRechargeTokenService {
|
||||
private long cacheExpiryTime;
|
||||
|
||||
public synchronized String getToken() {
|
||||
if (isCacheValid()) {
|
||||
logger.info("Cache is valid, attempting token refresh");
|
||||
return refreshCachedToken();
|
||||
}
|
||||
return fetchNewToken();
|
||||
}
|
||||
|
||||
private boolean isCacheValid() {
|
||||
return cachedToken != null && cachedRefreshToken != null && System.currentTimeMillis() < cacheExpiryTime;
|
||||
}
|
||||
|
||||
private synchronized String refreshCachedToken() {
|
||||
if (!isCacheValid()) {
|
||||
return fetchNewToken();
|
||||
}
|
||||
|
||||
try {
|
||||
logger.info("Refreshing HotRecharge token via refresh endpoint");
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
|
||||
Map<String, String> payload = Map.of(
|
||||
"token", cachedToken,
|
||||
"refreshToken", cachedRefreshToken
|
||||
);
|
||||
|
||||
LinkedHashMap<String, Object> response = restService.postAs(hotAuthUrl + "/identity/refresh", payload, headers, LinkedHashMap.class);
|
||||
cachedToken = (String) response.get("token");
|
||||
cachedRefreshToken = (String) response.get("refreshToken");
|
||||
cacheExpiryTime = System.currentTimeMillis() + (cacheDurationMinutes * 60 * 1000L);
|
||||
|
||||
logger.info("HotRecharge token refreshed via refresh endpoint, cache extended by {} minutes", cacheDurationMinutes);
|
||||
return cachedToken;
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to refresh HotRecharge token: " + e.getMessage(), e);
|
||||
// Fall back to login on refresh failure
|
||||
return fetchNewToken();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized String fetchNewToken() {
|
||||
if (isCacheValid()) {
|
||||
return refreshCachedToken();
|
||||
}
|
||||
|
||||
try {
|
||||
logger.info("Fetching new HotRecharge token via login");
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
@@ -99,9 +53,33 @@ public class HotRechargeTokenService {
|
||||
logger.info("New HotRecharge token cached, cache expires in {} minutes", cacheDurationMinutes);
|
||||
return cachedToken;
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to fetch HotRecharge token: " + e.getMessage(), e);
|
||||
cachedToken = null;
|
||||
cachedRefreshToken = null;
|
||||
logger.error("Failed to fetch HotRecharge token: {}", e.getMessage(), e);
|
||||
logger.info("Trying to refresh token");
|
||||
return refreshCachedToken();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized String refreshCachedToken() {
|
||||
try {
|
||||
logger.info("Refreshing HotRecharge token via refresh endpoint");
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||
|
||||
Map<String, String> payload = Map.of(
|
||||
"token", cachedToken,
|
||||
"refreshToken", cachedRefreshToken
|
||||
);
|
||||
|
||||
LinkedHashMap<String, Object> response = restService.postAs(hotAuthUrl + "/identity/refresh", payload, headers, LinkedHashMap.class);
|
||||
cachedToken = (String) response.get("token");
|
||||
cachedRefreshToken = (String) response.get("refreshToken");
|
||||
cacheExpiryTime = System.currentTimeMillis() + (cacheDurationMinutes * 60 * 1000L);
|
||||
|
||||
logger.info("HotRecharge token refreshed via refresh endpoint, cache extended by {} minutes", cacheDurationMinutes);
|
||||
return cachedToken;
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to refresh HotRecharge token: {}", e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,10 +155,10 @@ public class VelocityPaymentService {
|
||||
.paymentProcessorLabel(paymentProcessorLabel)
|
||||
.debitCurrency(transaction.getDebitCurrency().name())
|
||||
.debitRef(transaction.getErpSalesRef())
|
||||
.creditPhone(velocityApiProperties.getCreditPhone())
|
||||
.creditPhone("")
|
||||
.creditRegion("ZW")
|
||||
.creditAccount(velocityApiProperties.getCreditAccount())
|
||||
.authType(velocityApiProperties.getDefaultAuthType())
|
||||
.creditAccount("")
|
||||
.authType(paymentProcessorLabel.equals("VMC") ? "WEB" : "REMOTE")
|
||||
.build();
|
||||
|
||||
if ("MPGS".equalsIgnoreCase(transaction.getPaymentProcessorLabel())) {
|
||||
|
||||
@@ -59,9 +59,15 @@ public class NetoneConfirmationHotProcessor implements TransactionProcessorInter
|
||||
put("value", transaction.getBillName());
|
||||
}});
|
||||
additionalDataList.add(new HashMap() {{
|
||||
put("name", "Destination Phone Number");
|
||||
put("name", "From");
|
||||
put("value", transaction.getDebitPhone());
|
||||
}});
|
||||
|
||||
additionalDataList.add(new HashMap() {{
|
||||
put("name", "To");
|
||||
put("value", transaction.getCreditAccount());
|
||||
}});
|
||||
|
||||
if(transaction.getBillProductName() != null && !transaction.getBillProductName().isEmpty()) {
|
||||
additionalDataList.add(new HashMap() {{
|
||||
put("name", "Product");
|
||||
|
||||
@@ -74,14 +74,12 @@ public class CleanupHandler implements HandlerInterface {
|
||||
String debitPhoneNumber = transaction.getDebitPhone();
|
||||
String creditPhoneNumber = transaction.getCreditPhone();
|
||||
|
||||
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
|
||||
|
||||
if(debitPhoneNumber != null && !debitPhoneNumber.isEmpty()){
|
||||
transaction.setDebitPhone(Utils.formatPhoneNumber(debitPhoneNumber, ""));
|
||||
transaction.setDebitPhone(Utils.formatPhoneNumber(debitPhoneNumber, transaction.getRegion()));
|
||||
}
|
||||
|
||||
if(creditPhoneNumber != null && !creditPhoneNumber.isEmpty()){
|
||||
transaction.setDebitPhone(Utils.formatPhoneNumber(creditPhoneNumber, "ZW"));
|
||||
transaction.setCreditAccount(Utils.formatPhoneNumber(creditPhoneNumber, "ZW"));
|
||||
}
|
||||
|
||||
return transaction;
|
||||
|
||||
@@ -39,34 +39,34 @@ public class ChargeSeeder implements Seeder {
|
||||
}
|
||||
|
||||
// Ecocash Gateway Fee (1%)
|
||||
if (chargeRepository.existsByChargeLabelAndCurrencyAndPercentageRate(
|
||||
ChargeLabelEnum.GATEWAY_FEE, CurrencyType.USD, new BigDecimal("1"))) {
|
||||
log.info("Charge 'Gateway fee (1%)' already exists, skipping.");
|
||||
if (chargeRepository.existsByChargeLabelAndCurrencyAndDescription(
|
||||
ChargeLabelEnum.GATEWAY_FEE, CurrencyType.USD, "Ecocash Gateway fee")) {
|
||||
log.info("Charge 'Ecocash Gateway fee (1%)' already exists, skipping.");
|
||||
} else {
|
||||
chargeRepository.save(Charge.builder()
|
||||
.description("Gateway fee")
|
||||
.description("Ecocash Gateway fee")
|
||||
.chargeLabel(ChargeLabelEnum.GATEWAY_FEE)
|
||||
.currency(CurrencyType.USD)
|
||||
.percentageRate(new BigDecimal("1"))
|
||||
.includes(new HashSet<>(Arrays.asList(ecocashCondition)))
|
||||
.build());
|
||||
log.info("Charge 'Gateway fee (1%)' seeded.");
|
||||
log.info("Charge 'Ecocash Gateway fee (1%)' seeded.");
|
||||
}
|
||||
|
||||
// MPGS Gateway Fee (2%, min 0.55)
|
||||
if (chargeRepository.existsByChargeLabelAndCurrencyAndPercentageRate(
|
||||
ChargeLabelEnum.GATEWAY_FEE, CurrencyType.USD, new BigDecimal("2"))) {
|
||||
log.info("Charge 'Gateway fee (2%)' already exists, skipping.");
|
||||
if (chargeRepository.existsByChargeLabelAndCurrencyAndDescription(
|
||||
ChargeLabelEnum.GATEWAY_FEE, CurrencyType.USD, "MPGS Gateway fee")) {
|
||||
log.info("Charge 'MPGS Gateway fee (1% min 0.50)' already exists, skipping.");
|
||||
} else {
|
||||
chargeRepository.save(Charge.builder()
|
||||
.description("Gateway fee")
|
||||
.description("MPGS Gateway fee")
|
||||
.chargeLabel(ChargeLabelEnum.GATEWAY_FEE)
|
||||
.currency(CurrencyType.USD)
|
||||
.percentageRate(new BigDecimal("1"))
|
||||
.min(new BigDecimal("0.20"))
|
||||
.min(new BigDecimal("0.50"))
|
||||
.includes(new HashSet<>(Arrays.asList(mpgsCondition)))
|
||||
.build());
|
||||
log.info("Charge 'Gateway fee (2%)' seeded.");
|
||||
log.info("Charge 'MPGS Gateway fee (1% min 0.50)' seeded.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,5 +68,5 @@ hot.cache.duration.minutes=5
|
||||
|
||||
velocity.api.base-url=https://api.velocityafrica.net
|
||||
velocity.api.api-key=cHE08ADmiATtf8VYgA59-wKVKVKj2WusKDAaaRLDsG8
|
||||
velocity.api.cancel-url=https://pay.velocityafrica/poll
|
||||
velocity.api.success-url=https://pay.velocityafrica/poll
|
||||
velocity.api.cancel-url=https://pay.velocityafrica.net/poll
|
||||
velocity.api.success-url=https://pay.velocityafrica.net/poll
|
||||
@@ -1,80 +0,0 @@
|
||||
<?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">
|
||||
<changeSet author="khoza (generated)" id="1780061546055-17">
|
||||
<addColumn tableName="transaction">
|
||||
<column name="order_id" type="varchar(255)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-18">
|
||||
<addColumn tableName="transaction">
|
||||
<column name="order_trace" type="varchar(255)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-19">
|
||||
<addColumn tableName="transaction">
|
||||
<column name="order_transaction_trace" type="varchar(255)"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-20">
|
||||
<dropColumn columnName="version" tableName="transaction"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-1">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="additional_data"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-2">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="category"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-3">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="charge"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-4">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="charge_condition"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-5">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="currency"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-6">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="integration_processor"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-7">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="otp"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-8">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="payment_processor"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-9">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="provider"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-10">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="recipient"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-11">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="setting"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-12">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="transaction"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-13">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="transaction_event"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-14">
|
||||
<addDefaultValue columnDataType="boolean" columnName="deleted" defaultValueBoolean="false" tableName="users"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-15">
|
||||
<dropUniqueConstraint constraintName="UC_USERSUSERNAME_COL" tableName="users"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780061546055-16">
|
||||
<addUniqueConstraint columnNames="username" constraintName="UC_USERSUSERNAME_COL" tableName="users"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780062553770-3">
|
||||
<addColumn tableName="provider">
|
||||
<column name="priority" type="integer"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780062553770-1">
|
||||
<dropUniqueConstraint constraintName="UC_USERSUSERNAME_COL" tableName="users"/>
|
||||
</changeSet>
|
||||
<changeSet author="khoza (generated)" id="1780062553770-2">
|
||||
<addUniqueConstraint columnNames="username" constraintName="UC_USERSUSERNAME_COL" tableName="users"/>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
@@ -1,7 +1,7 @@
|
||||
changeLogFile=src/main/resources/liquibase-diff-changeLog.xml
|
||||
url=jdbc:postgresql://localhost:5432/qpay?serverTimezone=Africa/Harare&useLegacyDatetimeCode=false
|
||||
username=postgres
|
||||
password=zdDZMzq6F4B4L1IUl
|
||||
password=example
|
||||
|
||||
driver=org.postgresql.Driver
|
||||
referenceUrl=hibernate:spring:zw.qantra.tm.domain.models?dialect=org.hibernate.dialect.PostgreSQLDialect&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy&hibernate.physical_naming_strategy=org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
|
||||
|
||||
Reference in New Issue
Block a user