|
|
@@ -2,6 +2,7 @@ package com.etotem.cfc.service;
|
|
|
|
|
|
import com.etotem.cfc.common.HmacSignUtil;
|
|
|
import com.etotem.cfc.dto.VirtualPayParamsDTO;
|
|
|
+import com.etotem.cfc.entity.AssessmentOrder;
|
|
|
import com.etotem.cfc.entity.VirtualGoodsConfig;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
|
@@ -114,13 +115,19 @@ public class VirtualPayService {
|
|
|
String transactionId = getStringIgnoreCase(payload, "TransactionId", "transaction_id");
|
|
|
|
|
|
if (outTradeNo == null || outTradeNo.isEmpty()) {
|
|
|
- log.error("虚拟支付发货推送缺少OutTradeNo: {}", payload);
|
|
|
- return failResult("参数错误");
|
|
|
+ log.error("虚拟支付发货推送缺少OutTradeNo,返回成功避免微信重试: {}", payload);
|
|
|
+ return successResult();
|
|
|
}
|
|
|
|
|
|
log.info("虚拟支付发货推送: outTradeNo={}, transactionId={}", outTradeNo, transactionId);
|
|
|
|
|
|
if (outTradeNo.startsWith("A")) {
|
|
|
+ // 幂等:已 paid/refunded 的重复推送直接返回成功,避免重复佣金结算(spec §6.2)
|
|
|
+ AssessmentOrder existing = assessmentOrderService.getByOrderNo(outTradeNo);
|
|
|
+ if (existing != null && ("paid".equals(existing.getStatus()) || "refunded".equals(existing.getStatus()))) {
|
|
|
+ log.info("虚拟支付发货推送重复通知,订单已终态: outTradeNo={}, status={}", outTradeNo, existing.getStatus());
|
|
|
+ return successResult();
|
|
|
+ }
|
|
|
// 测评订单:标记已付 + 佣金结算
|
|
|
assessmentOrderService.paySuccess(outTradeNo, transactionId, "virtual");
|
|
|
} else if (outTradeNo.startsWith("ORD") || outTradeNo.startsWith("SUB")) {
|
|
|
@@ -145,8 +152,8 @@ public class VirtualPayService {
|
|
|
String outTradeNo = getStringIgnoreCase(payload, "OutTradeNo", "out_trade_no");
|
|
|
|
|
|
if (outTradeNo == null || outTradeNo.isEmpty()) {
|
|
|
- log.error("虚拟支付退款推送缺少OutTradeNo: {}", payload);
|
|
|
- return failResult("参数错误");
|
|
|
+ log.error("虚拟支付退款推送缺少OutTradeNo,返回成功避免微信重试: {}", payload);
|
|
|
+ return successResult();
|
|
|
}
|
|
|
|
|
|
log.info("虚拟支付退款推送: outTradeNo={}", outTradeNo);
|
|
|
@@ -171,7 +178,7 @@ public class VirtualPayService {
|
|
|
* 官方规则要求 signData 不得包含 platform 字段(否则 -15005),此处统一剔除。
|
|
|
* extInfo 为 null 时仅拼 orderInfo。
|
|
|
*/
|
|
|
- private String buildSignData(Map<String, Object> orderInfo, Map<String, Object> extInfo) {
|
|
|
+ String buildSignData(Map<String, Object> orderInfo, Map<String, Object> extInfo) {
|
|
|
Map<String, Object> merged = new LinkedHashMap<>(orderInfo);
|
|
|
if (extInfo != null) {
|
|
|
merged.putAll(extInfo);
|