소스 검색

【功能优化】商城:商城订单的支付回调,增加“已支付”情况下的防重处理

YunaiV 8 달 전
부모
커밋
567cbeae68

+ 37 - 43
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java

@@ -9,7 +9,6 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
-import cn.iocoder.yudao.framework.common.core.KeyValue;
 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
@@ -269,12 +268,24 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
     @Transactional(rollbackFor = Exception.class)
     @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_PAY)
     public void updateOrderPaid(Long id, Long payOrderId) {
-        // 1. 校验并获得交易订单(可支付)
-        KeyValue<TradeOrderDO, PayOrderRespDTO> orderResult = validateOrderPayable(id, payOrderId);
-        TradeOrderDO order = orderResult.getKey();
-        PayOrderRespDTO payOrder = orderResult.getValue();
+        // 1.1 校验订单是否存在
+        TradeOrderDO order = validateOrderExists(id);
+        // 1.2 校验订单已支付
+        if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayStatus()) {
+            // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调
+            if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) {
+                log.warn("[updateOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", order, payOrderId);
+                return;
+            }
+            log.error("[updateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",
+                    id, payOrderId, JsonUtils.toJsonString(order));
+            throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
+        }
+
+        // 2. 校验支付订单的合法性
+        PayOrderRespDTO payOrder = validatePayOrderPaid(order, payOrderId);
 
-        // 2. 更新 TradeOrderDO 状态为已支付,等待发货
+        // 3. 更新 TradeOrderDO 状态为已支付,等待发货
         int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(),
                 new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayStatus(true)
                         .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode()));
@@ -282,66 +293,49 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
             throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);
         }
 
-        // 3. 执行 TradeOrderHandler 的后置处理
+        // 4. 执行 TradeOrderHandler 的后置处理
         List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);
         tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order, orderItems));
 
-        // 4. 记录订单日志
+        // 5. 记录订单日志
         TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus());
         TradeOrderLogUtils.setUserInfo(order.getUserId(), UserTypeEnum.MEMBER.getValue());
     }
 
     /**
-     * 校验交易订单满足被支付的条件
-     * <p>
-     * 1. 交易订单未支付
-     * 2. 支付单已支付
+     * 校验支付订单的合法性
      *
-     * @param id         交易订单编号
+     * @param order 交易订单
      * @param payOrderId 支付订单编号
-     * @return 交易订单
+     * @return 支付订单
      */
-    private KeyValue<TradeOrderDO, PayOrderRespDTO> validateOrderPayable(Long id, Long payOrderId) {
-        // 校验订单是否存在
-        TradeOrderDO order = validateOrderExists(id);
-        // 校验订单未支付
-        if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayStatus()) {
-            log.error("[validateOrderPaid][order({}) 不处于待支付状态,请进行处理!order 数据是:{}]",
-                    id, JsonUtils.toJsonString(order));
-            throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);
-        }
-        // 校验支付订单匹配
-        if (ObjectUtil.notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号
-            log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",
-                    id, payOrderId, JsonUtils.toJsonString(order));
-            throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
-        }
-
-        // 校验支付单是否存在
+    private PayOrderRespDTO validatePayOrderPaid(TradeOrderDO order, Long payOrderId) {
+        // 1. 校验支付单是否存在
         PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId);
         if (payOrder == null) {
-            log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId);
+            log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order.getId(), payOrderId);
             throw exception(ORDER_NOT_FOUND);
         }
-        // 校验支付单已支付
+
+        // 2.1 校验支付单已支付
         if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
-            log.error("[validateOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
-                    id, payOrderId, JsonUtils.toJsonString(payOrder));
+            log.error("[validatePayOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
+                    order.getId(), payOrderId, JsonUtils.toJsonString(payOrder));
             throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
         }
-        // 校验支付金额一致
+        // 2.2 校验支付金额一致
         if (ObjectUtil.notEqual(payOrder.getPrice(), order.getPayPrice())) {
-            log.error("[validateOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
-                    id, payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder));
+            log.error("[validatePayOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
+                    order.getId(), payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder));
             throw exception(ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH);
         }
-        // 校验支付订单匹配(二次)
-        if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), id.toString())) {
-            log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
-                    id, payOrderId, JsonUtils.toJsonString(payOrder));
+        // 2.2 校验支付订单匹配(二次)
+        if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), order.getId().toString())) {
+            log.error("[validatePayOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
+                    order.getId(), payOrderId, JsonUtils.toJsonString(payOrder));
             throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
         }
-        return new KeyValue<>(order, payOrder);
+        return payOrder;
     }
 
     @Override

+ 4 - 4
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java

@@ -154,25 +154,25 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
         // 1. 校验支付单是否存在
         PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId);
         if (payOrder == null) {
-            log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order, payOrderId);
+            log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order.getId(), payOrderId);
             throw exception(PAY_ORDER_NOT_FOUND);
         }
         // 2.1 校验支付单已支付
         if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
             log.error("[validatePayOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
-                    order, payOrderId, toJsonString(payOrder));
+                    order.getId(), payOrderId, toJsonString(payOrder));
             throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
         }
         // 2.1 校验支付金额一致
         if (notEqual(payOrder.getPrice(), order.getPrice())) {
             log.error("[validatePayOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
-                    order, payOrderId, toJsonString(order), toJsonString(payOrder));
+                    order.getId(), payOrderId, toJsonString(order), toJsonString(payOrder));
             throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH);
         }
         // 2.2 校验支付订单匹配(二次)
         if (notEqual(payOrder.getMerchantOrderId(), order.getId().toString())) {
             log.error("[validatePayOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
-                    order, payOrderId, toJsonString(payOrder));
+                    order.getId(), payOrderId, toJsonString(payOrder));
             throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
         }
         return payOrder;

+ 4 - 4
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java

@@ -292,26 +292,26 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
         PayOrderDO payOrder = payOrderService.getOrder(payOrderId);
         if (payOrder == null) {
             log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 不存在,请进行处理!]",
-                    recharge, payOrderId);
+                    recharge.getId(), payOrderId);
             throw exception(PAY_ORDER_NOT_FOUND);
         }
 
         // 2.1 校验支付单已支付
         if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
             log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
-                    recharge, payOrderId, toJsonString(payOrder));
+                    recharge.getId(), payOrderId, toJsonString(payOrder));
             throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS);
         }
         // 2.2 校验支付金额一致
         if (notEqual(payOrder.getPrice(), recharge.getPayPrice())) {
             log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 支付金额不匹配,请进行处理!钱包 数据是:{},payOrder 数据是:{}]",
-                    recharge, payOrderId, toJsonString(recharge), toJsonString(payOrder));
+                    recharge.getId(), payOrderId, toJsonString(recharge), toJsonString(payOrder));
             throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_PRICE_NOT_MATCH);
         }
         // 2.3 校验支付订单的商户订单匹配
         if (notEqual(payOrder.getMerchantOrderId(), recharge.getId().toString())) {
             log.error("[validatePayOrderPaid][充值订单({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
-                    recharge, payOrderId, toJsonString(payOrder));
+                    recharge.getId(), payOrderId, toJsonString(payOrder));
             throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR);
         }
         return payOrder;