|
@@ -30,13 +30,13 @@ public class OmgPaymentQueryService {
|
|
|
private static final String TRADE_UNPAID = "0";
|
|
private static final String TRADE_UNPAID = "0";
|
|
|
private static final String TRADE_PAID = "1";
|
|
private static final String TRADE_PAID = "1";
|
|
|
private static final String TRADE_FAILED = "10200095";
|
|
private static final String TRADE_FAILED = "10200095";
|
|
|
|
|
+ private static final String TRADE_NOT_FOUND = "10200047";
|
|
|
private static final DateTimeFormatter OMG_DATE = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
|
|
private static final DateTimeFormatter OMG_DATE = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
|
|
|
private static final ZoneId TAIPEI = ZoneId.of("Asia/Taipei");
|
|
private static final ZoneId TAIPEI = ZoneId.of("Asia/Taipei");
|
|
|
- private static final List<String> REQUIRED_FIELDS = List.of(
|
|
|
|
|
- "MerchantID", "MerchantTradeNo", "StoreID", "TradeNo", "TradeAmt",
|
|
|
|
|
- "PaymentDate", "PaymentType", "HandlingCharge", "PaymentTypeChargeFee",
|
|
|
|
|
- "TradeDate", "TradeStatus", "ItemName", "CustomField1", "CustomField2",
|
|
|
|
|
- "CustomField3", "CustomField4", "CheckMacValue");
|
|
|
|
|
|
|
+ private static final List<String> CORE_REQUIRED_FIELDS = List.of(
|
|
|
|
|
+ "MerchantID", "MerchantTradeNo", "TradeAmt", "TradeStatus", "CheckMacValue");
|
|
|
|
|
+ private static final List<String> PAID_REQUIRED_FIELDS = List.of(
|
|
|
|
|
+ "TradeNo", "PaymentDate", "PaymentType", "PaymentTypeChargeFee", "TradeDate");
|
|
|
|
|
|
|
|
private final IOmgPaymentAttemptService attempts;
|
|
private final IOmgPaymentAttemptService attempts;
|
|
|
private final OmgPaymentQueryGateway gateway;
|
|
private final OmgPaymentQueryGateway gateway;
|
|
@@ -137,7 +137,11 @@ public class OmgPaymentQueryService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private void validateResponse(Map<String, String> response, OmgPaymentAttempt attempt) {
|
|
private void validateResponse(Map<String, String> response, OmgPaymentAttempt attempt) {
|
|
|
- if (!REQUIRED_FIELDS.stream().allMatch(response::containsKey)) {
|
|
|
|
|
|
|
+ List<String> missingCoreFields = missingOrBlankFields(response, CORE_REQUIRED_FIELDS);
|
|
|
|
|
+ if (!missingCoreFields.isEmpty()) {
|
|
|
|
|
+ log.warn("OMG query response rejected merchantTradeNo={} reason=missing_core_fields fields={}",
|
|
|
|
|
+ OmgPaymentCreateService.maskMerchantTradeNo(attempt.getMerchantTradeNo()),
|
|
|
|
|
+ missingCoreFields);
|
|
|
throw new IllegalArgumentException("OMG query response has missing fields");
|
|
throw new IllegalArgumentException("OMG query response has missing fields");
|
|
|
}
|
|
}
|
|
|
String checkMacValue = response.get("CheckMacValue");
|
|
String checkMacValue = response.get("CheckMacValue");
|
|
@@ -151,11 +155,31 @@ public class OmgPaymentQueryService {
|
|
|
if (!OmgPaymentNotifyService.secureEquals(expected, checkMacValue)) {
|
|
if (!OmgPaymentNotifyService.secureEquals(expected, checkMacValue)) {
|
|
|
throw new IllegalArgumentException("OMG query response signature mismatch");
|
|
throw new IllegalArgumentException("OMG query response signature mismatch");
|
|
|
}
|
|
}
|
|
|
|
|
+ String tradeStatus = response.get("TradeStatus");
|
|
|
|
|
+ String expectedAmount = TRADE_NOT_FOUND.equals(tradeStatus)
|
|
|
|
|
+ ? "0" : String.valueOf(attempt.getAmount());
|
|
|
if (!attempt.getMerchantId().equals(response.get("MerchantID"))
|
|
if (!attempt.getMerchantId().equals(response.get("MerchantID"))
|
|
|
|| !attempt.getMerchantTradeNo().equals(response.get("MerchantTradeNo"))
|
|
|| !attempt.getMerchantTradeNo().equals(response.get("MerchantTradeNo"))
|
|
|
- || !String.valueOf(attempt.getAmount()).equals(response.get("TradeAmt"))) {
|
|
|
|
|
|
|
+ || !expectedAmount.equals(response.get("TradeAmt"))) {
|
|
|
throw new IllegalArgumentException("OMG query response identity mismatch");
|
|
throw new IllegalArgumentException("OMG query response identity mismatch");
|
|
|
}
|
|
}
|
|
|
|
|
+ if (TRADE_PAID.equals(tradeStatus)) {
|
|
|
|
|
+ List<String> missingPaidFields = missingOrBlankFields(response, PAID_REQUIRED_FIELDS);
|
|
|
|
|
+ if (!missingPaidFields.isEmpty()) {
|
|
|
|
|
+ log.warn("OMG paid query response rejected merchantTradeNo={} "
|
|
|
|
|
+ + "reason=missing_settlement_fields fields={}",
|
|
|
|
|
+ OmgPaymentCreateService.maskMerchantTradeNo(attempt.getMerchantTradeNo()),
|
|
|
|
|
+ missingPaidFields);
|
|
|
|
|
+ throw new IllegalArgumentException("OMG paid query response has missing fields");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static List<String> missingOrBlankFields(Map<String, String> response,
|
|
|
|
|
+ List<String> requiredFields) {
|
|
|
|
|
+ return requiredFields.stream()
|
|
|
|
|
+ .filter(field -> isBlank(response.get(field)))
|
|
|
|
|
+ .toList();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private String synchronizeIfFinal(String tradeStatus, Map<String, String> fields,
|
|
private String synchronizeIfFinal(String tradeStatus, Map<String, String> fields,
|
|
@@ -169,7 +193,9 @@ public class OmgPaymentQueryService {
|
|
|
if (TRADE_UNPAID.equals(tradeStatus)) {
|
|
if (TRADE_UNPAID.equals(tradeStatus)) {
|
|
|
return "UNPAID";
|
|
return "UNPAID";
|
|
|
}
|
|
}
|
|
|
- if (!TRADE_PAID.equals(tradeStatus) && !TRADE_FAILED.equals(tradeStatus)) {
|
|
|
|
|
|
|
+ if (!TRADE_PAID.equals(tradeStatus)
|
|
|
|
|
+ && !TRADE_FAILED.equals(tradeStatus)
|
|
|
|
|
+ && !TRADE_NOT_FOUND.equals(tradeStatus)) {
|
|
|
return "UNKNOWN";
|
|
return "UNKNOWN";
|
|
|
}
|
|
}
|
|
|
OmgPaymentSettlementResult result = settlement.synchronizeVerifiedQuery(
|
|
OmgPaymentSettlementResult result = settlement.synchronizeVerifiedQuery(
|
|
@@ -190,14 +216,14 @@ public class OmgPaymentQueryService {
|
|
|
throw new IllegalArgumentException("paid query response has no PaymentType");
|
|
throw new IllegalArgumentException("paid query response has no PaymentType");
|
|
|
}
|
|
}
|
|
|
BigDecimal fee = parseDecimal(fields.get("PaymentTypeChargeFee"));
|
|
BigDecimal fee = parseDecimal(fields.get("PaymentTypeChargeFee"));
|
|
|
- if (fee == null || fee.signum() < 0) {
|
|
|
|
|
|
|
+ if ((paid && fee == null) || (fee != null && fee.signum() < 0)) {
|
|
|
throw new IllegalArgumentException("invalid payment fee");
|
|
throw new IllegalArgumentException("invalid payment fee");
|
|
|
}
|
|
}
|
|
|
return new OmgPaymentGatewayFacts(OmgPaymentFactSource.QUERY,
|
|
return new OmgPaymentGatewayFacts(OmgPaymentFactSource.QUERY,
|
|
|
attempt.getMerchantId(), attempt.getMerchantTradeNo(), attempt.getAmount(),
|
|
attempt.getMerchantId(), attempt.getMerchantTradeNo(), attempt.getAmount(),
|
|
|
tradeStatus, "TradeStatus=" + tradeStatus, tradeNo, paymentType,
|
|
tradeStatus, "TradeStatus=" + tradeStatus, tradeNo, paymentType,
|
|
|
parseDate(fields.get("PaymentDate"), paid),
|
|
parseDate(fields.get("PaymentDate"), paid),
|
|
|
- parseDate(fields.get("TradeDate"), true), fee, null);
|
|
|
|
|
|
|
+ parseDate(fields.get("TradeDate"), paid), fee, null);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private static OmgQueryPaymentResponse toResponse(String status, Map<String, String> fields) {
|
|
private static OmgQueryPaymentResponse toResponse(String status, Map<String, String> fields) {
|