Commit 57a934ae09bbaebaf7ecc51f8f8b58f806e75414

Authored by YunaiV
1 parent 2c2e9fe8

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

yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java
1 package cn.iocoder.yudao.module.pay.service.demo; 1 package cn.iocoder.yudao.module.pay.service.demo;
2 2
3 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
  4 +import cn.hutool.core.util.ObjectUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageParam; 5 import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; 7 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
@@ -14,11 +15,11 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO; @@ -14,11 +15,11 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO;
14 import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoOrderMapper; 15 import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoOrderMapper;
15 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; 16 import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
16 import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum; 17 import cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum;
  18 +import jakarta.annotation.Resource;
17 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
18 import org.springframework.stereotype.Service; 20 import org.springframework.stereotype.Service;
19 import org.springframework.validation.annotation.Validated; 21 import org.springframework.validation.annotation.Validated;
20 22
21 -import jakarta.annotation.Resource;  
22 import java.time.Duration; 23 import java.time.Duration;
23 import java.time.LocalDateTime; 24 import java.time.LocalDateTime;
24 import java.util.HashMap; 25 import java.util.HashMap;
@@ -111,10 +112,28 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { @@ -111,10 +112,28 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
111 112
112 @Override 113 @Override
113 public void updateDemoOrderPaid(Long id, Long payOrderId) { 114 public void updateDemoOrderPaid(Long id, Long payOrderId) {
114 - // 校验并获得支付订单(可支付)  
115 - PayOrderRespDTO payOrder = validateDemoOrderCanPaid(id, payOrderId); 115 + // 1.1 校验订单是否存在
  116 + PayDemoOrderDO order = payDemoOrderMapper.selectById(id);
  117 + if (order == null) {
  118 + throw exception(DEMO_ORDER_NOT_FOUND);
  119 + }
  120 + // 1.2 校验订单已支付
  121 + if (order.getPayStatus()) {
  122 + // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调
  123 + if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) {
  124 + log.warn("[updateDemoOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", id, payOrderId);
  125 + return;
  126 + }
  127 + // 异常:支付单号不同,说明支付单号错误
  128 + log.error("[updateDemoOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",
  129 + id, payOrderId, toJsonString(order));
  130 + throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
  131 + }
  132 +
  133 + // 2. 校验支付订单的合法性
  134 + PayOrderRespDTO payOrder = validatePayOrderPaid(order, payOrderId);
116 135
117 - // 更新 PayDemoOrderDO 状态为已支付 136 + // 3. 更新 PayDemoOrderDO 状态为已支付
118 int updateCount = payDemoOrderMapper.updateByIdAndPayed(id, false, 137 int updateCount = payDemoOrderMapper.updateByIdAndPayed(id, false,
119 new PayDemoOrderDO().setPayStatus(true).setPayTime(LocalDateTime.now()) 138 new PayDemoOrderDO().setPayStatus(true).setPayTime(LocalDateTime.now())
120 .setPayChannelCode(payOrder.getChannelCode())); 139 .setPayChannelCode(payOrder.getChannelCode()));
@@ -124,56 +143,35 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService { @@ -124,56 +143,35 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
124 } 143 }
125 144
126 /** 145 /**
127 - * 校验交易订单满足被支付的条件  
128 - *  
129 - * 1. 交易订单未支付  
130 - * 2. 支付单已支付 146 + * 校验支付订单的合法性
131 * 147 *
132 - * @param id 交易订单编号 148 + * @param order 交易订单
133 * @param payOrderId 支付订单编号 149 * @param payOrderId 支付订单编号
134 - * @return 交易订单 150 + * @return 支付订单
135 */ 151 */
136 - private PayOrderRespDTO validateDemoOrderCanPaid(Long id, Long payOrderId) {  
137 - // 1.1 校验订单是否存在  
138 - PayDemoOrderDO order = payDemoOrderMapper.selectById(id);  
139 - if (order == null) {  
140 - throw exception(DEMO_ORDER_NOT_FOUND);  
141 - }  
142 - // 1.2 校验订单未支付  
143 - if (order.getPayStatus()) {  
144 - log.error("[validateDemoOrderCanPaid][order({}) 不处于待支付状态,请进行处理!order 数据是:{}]",  
145 - id, toJsonString(order));  
146 - throw exception(DEMO_ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);  
147 - }  
148 - // 1.3 校验支付订单匹配  
149 - if (notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号  
150 - log.error("[validateDemoOrderCanPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",  
151 - id, payOrderId, toJsonString(order));  
152 - throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);  
153 - }  
154 -  
155 - // 2.1 校验支付单是否存在 152 + private PayOrderRespDTO validatePayOrderPaid(PayDemoOrderDO order, Long payOrderId) {
  153 + // 1. 校验支付单是否存在
156 PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); 154 PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId);
157 if (payOrder == null) { 155 if (payOrder == null) {
158 - log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); 156 + log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 不存在,请进行处理!]", order, payOrderId);
159 throw exception(PAY_ORDER_NOT_FOUND); 157 throw exception(PAY_ORDER_NOT_FOUND);
160 } 158 }
161 - // 2.2 校验支付单已支付 159 + // 2.1 校验支付单已支付
162 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { 160 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
163 log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", 161 log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
164 - id, payOrderId, toJsonString(payOrder)); 162 + order, payOrderId, toJsonString(payOrder));
165 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); 163 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
166 } 164 }
167 - // 2.3 校验支付金额一致 165 + // 2.1 校验支付金额一致
168 if (notEqual(payOrder.getPrice(), order.getPrice())) { 166 if (notEqual(payOrder.getPrice(), order.getPrice())) {
169 log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]", 167 log.error("[validateDemoOrderCanPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
170 - id, payOrderId, toJsonString(order), toJsonString(payOrder)); 168 + order, payOrderId, toJsonString(order), toJsonString(payOrder));
171 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); 169 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH);
172 } 170 }
173 - // 2.4 校验支付订单匹配(二次)  
174 - if (notEqual(payOrder.getMerchantOrderId(), id.toString())) { 171 + // 2.2 校验支付订单匹配(二次)
  172 + if (notEqual(payOrder.getMerchantOrderId(), order.getId().toString())) {
175 log.error("[validateDemoOrderCanPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", 173 log.error("[validateDemoOrderCanPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
176 - id, payOrderId, toJsonString(payOrder)); 174 + order, payOrderId, toJsonString(payOrder));
177 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); 175 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
178 } 176 }
179 return payOrder; 177 return payOrder;