Commit 567cbeae681e4978f6ebe9292287aaa497ef123e

Authored by YunaiV
1 parent 3bde43b1

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

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; @@ -9,7 +9,6 @@ import cn.hutool.core.util.ObjectUtil;
9 import cn.hutool.core.util.RandomUtil; 9 import cn.hutool.core.util.RandomUtil;
10 import cn.hutool.core.util.StrUtil; 10 import cn.hutool.core.util.StrUtil;
11 import cn.hutool.extra.spring.SpringUtil; 11 import cn.hutool.extra.spring.SpringUtil;
12 -import cn.iocoder.yudao.framework.common.core.KeyValue;  
13 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 12 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
14 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 13 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
15 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; 14 import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
@@ -269,12 +268,24 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -269,12 +268,24 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
269 @Transactional(rollbackFor = Exception.class) 268 @Transactional(rollbackFor = Exception.class)
270 @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_PAY) 269 @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_PAY)
271 public void updateOrderPaid(Long id, Long payOrderId) { 270 public void updateOrderPaid(Long id, Long payOrderId) {
272 - // 1. 校验并获得交易订单(可支付)  
273 - KeyValue<TradeOrderDO, PayOrderRespDTO> orderResult = validateOrderPayable(id, payOrderId);  
274 - TradeOrderDO order = orderResult.getKey();  
275 - PayOrderRespDTO payOrder = orderResult.getValue(); 271 + // 1.1 校验订单是否存在
  272 + TradeOrderDO order = validateOrderExists(id);
  273 + // 1.2 校验订单已支付
  274 + if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayStatus()) {
  275 + // 特殊:如果订单已支付,且支付单号相同,直接返回,说明重复回调
  276 + if (ObjectUtil.equals(order.getPayOrderId(), payOrderId)) {
  277 + log.warn("[updateOrderPaid][order({}) 已支付,且支付单号相同({}),直接返回]", order, payOrderId);
  278 + return;
  279 + }
  280 + log.error("[updateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",
  281 + id, payOrderId, JsonUtils.toJsonString(order));
  282 + throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
  283 + }
  284 +
  285 + // 2. 校验支付订单的合法性
  286 + PayOrderRespDTO payOrder = validatePayOrderPaid(order, payOrderId);
276 287
277 - // 2. 更新 TradeOrderDO 状态为已支付,等待发货 288 + // 3. 更新 TradeOrderDO 状态为已支付,等待发货
278 int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(), 289 int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(),
279 new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayStatus(true) 290 new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayStatus(true)
280 .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode())); 291 .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode()));
@@ -282,66 +293,49 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -282,66 +293,49 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
282 throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); 293 throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);
283 } 294 }
284 295
285 - // 3. 执行 TradeOrderHandler 的后置处理 296 + // 4. 执行 TradeOrderHandler 的后置处理
286 List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id); 297 List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id);
287 tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order, orderItems)); 298 tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order, orderItems));
288 299
289 - // 4. 记录订单日志 300 + // 5. 记录订单日志
290 TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus()); 301 TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus());
291 TradeOrderLogUtils.setUserInfo(order.getUserId(), UserTypeEnum.MEMBER.getValue()); 302 TradeOrderLogUtils.setUserInfo(order.getUserId(), UserTypeEnum.MEMBER.getValue());
292 } 303 }
293 304
294 /** 305 /**
295 - * 校验交易订单满足被支付的条件  
296 - * <p>  
297 - * 1. 交易订单未支付  
298 - * 2. 支付单已支付 306 + * 校验支付订单的合法性
299 * 307 *
300 - * @param id 交易订单编号 308 + * @param order 交易订单
301 * @param payOrderId 支付订单编号 309 * @param payOrderId 支付订单编号
302 - * @return 交易订单 310 + * @return 支付订单
303 */ 311 */
304 - private KeyValue<TradeOrderDO, PayOrderRespDTO> validateOrderPayable(Long id, Long payOrderId) {  
305 - // 校验订单是否存在  
306 - TradeOrderDO order = validateOrderExists(id);  
307 - // 校验订单未支付  
308 - if (!TradeOrderStatusEnum.isUnpaid(order.getStatus()) || order.getPayStatus()) {  
309 - log.error("[validateOrderPaid][order({}) 不处于待支付状态,请进行处理!order 数据是:{}]",  
310 - id, JsonUtils.toJsonString(order));  
311 - throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID);  
312 - }  
313 - // 校验支付订单匹配  
314 - if (ObjectUtil.notEqual(order.getPayOrderId(), payOrderId)) { // 支付单号  
315 - log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!order 数据是:{}]",  
316 - id, payOrderId, JsonUtils.toJsonString(order));  
317 - throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);  
318 - }  
319 -  
320 - // 校验支付单是否存在 312 + private PayOrderRespDTO validatePayOrderPaid(TradeOrderDO order, Long payOrderId) {
  313 + // 1. 校验支付单是否存在
321 PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); 314 PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId);
322 if (payOrder == null) { 315 if (payOrder == null) {
323 - log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); 316 + log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order.getId(), payOrderId);
324 throw exception(ORDER_NOT_FOUND); 317 throw exception(ORDER_NOT_FOUND);
325 } 318 }
326 - // 校验支付单已支付 319 +
  320 + // 2.1 校验支付单已支付
327 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { 321 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
328 - log.error("[validateOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",  
329 - id, payOrderId, JsonUtils.toJsonString(payOrder)); 322 + log.error("[validatePayOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
  323 + order.getId(), payOrderId, JsonUtils.toJsonString(payOrder));
330 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); 324 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
331 } 325 }
332 - // 校验支付金额一致 326 + // 2.2 校验支付金额一致
333 if (ObjectUtil.notEqual(payOrder.getPrice(), order.getPayPrice())) { 327 if (ObjectUtil.notEqual(payOrder.getPrice(), order.getPayPrice())) {
334 - log.error("[validateOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",  
335 - id, payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder)); 328 + log.error("[validatePayOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
  329 + order.getId(), payOrderId, JsonUtils.toJsonString(order), JsonUtils.toJsonString(payOrder));
336 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); 330 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH);
337 } 331 }
338 - // 校验支付订单匹配(二次)  
339 - if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), id.toString())) {  
340 - log.error("[validateOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",  
341 - id, payOrderId, JsonUtils.toJsonString(payOrder)); 332 + // 2.2 校验支付订单匹配(二次)
  333 + if (ObjectUtil.notEqual(payOrder.getMerchantOrderId(), order.getId().toString())) {
  334 + log.error("[validatePayOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
  335 + order.getId(), payOrderId, JsonUtils.toJsonString(payOrder));
342 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); 336 throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
343 } 337 }
344 - return new KeyValue<>(order, payOrder); 338 + return payOrder;
345 } 339 }
346 340
347 @Override 341 @Override
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 { @@ -154,25 +154,25 @@ public class PayDemoOrderServiceImpl implements PayDemoOrderService {
154 // 1. 校验支付单是否存在 154 // 1. 校验支付单是否存在
155 PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); 155 PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId);
156 if (payOrder == null) { 156 if (payOrder == null) {
157 - log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order, payOrderId); 157 + log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order.getId(), payOrderId);
158 throw exception(PAY_ORDER_NOT_FOUND); 158 throw exception(PAY_ORDER_NOT_FOUND);
159 } 159 }
160 // 2.1 校验支付单已支付 160 // 2.1 校验支付单已支付
161 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { 161 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
162 log.error("[validatePayOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", 162 log.error("[validatePayOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
163 - order, payOrderId, toJsonString(payOrder)); 163 + order.getId(), payOrderId, toJsonString(payOrder));
164 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); 164 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS);
165 } 165 }
166 // 2.1 校验支付金额一致 166 // 2.1 校验支付金额一致
167 if (notEqual(payOrder.getPrice(), order.getPrice())) { 167 if (notEqual(payOrder.getPrice(), order.getPrice())) {
168 log.error("[validatePayOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]", 168 log.error("[validatePayOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]",
169 - order, payOrderId, toJsonString(order), toJsonString(payOrder)); 169 + order.getId(), payOrderId, toJsonString(order), toJsonString(payOrder));
170 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); 170 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH);
171 } 171 }
172 // 2.2 校验支付订单匹配(二次) 172 // 2.2 校验支付订单匹配(二次)
173 if (notEqual(payOrder.getMerchantOrderId(), order.getId().toString())) { 173 if (notEqual(payOrder.getMerchantOrderId(), order.getId().toString())) {
174 log.error("[validatePayOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", 174 log.error("[validatePayOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
175 - order, payOrderId, toJsonString(payOrder)); 175 + order.getId(), payOrderId, toJsonString(payOrder));
176 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); 176 throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR);
177 } 177 }
178 return payOrder; 178 return payOrder;
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 { @@ -292,26 +292,26 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
292 PayOrderDO payOrder = payOrderService.getOrder(payOrderId); 292 PayOrderDO payOrder = payOrderService.getOrder(payOrderId);
293 if (payOrder == null) { 293 if (payOrder == null) {
294 log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 不存在,请进行处理!]", 294 log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 不存在,请进行处理!]",
295 - recharge, payOrderId); 295 + recharge.getId(), payOrderId);
296 throw exception(PAY_ORDER_NOT_FOUND); 296 throw exception(PAY_ORDER_NOT_FOUND);
297 } 297 }
298 298
299 // 2.1 校验支付单已支付 299 // 2.1 校验支付单已支付
300 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { 300 if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) {
301 log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", 301 log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]",
302 - recharge, payOrderId, toJsonString(payOrder)); 302 + recharge.getId(), payOrderId, toJsonString(payOrder));
303 throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS); 303 throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS);
304 } 304 }
305 // 2.2 校验支付金额一致 305 // 2.2 校验支付金额一致
306 if (notEqual(payOrder.getPrice(), recharge.getPayPrice())) { 306 if (notEqual(payOrder.getPrice(), recharge.getPayPrice())) {
307 log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 支付金额不匹配,请进行处理!钱包 数据是:{},payOrder 数据是:{}]", 307 log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 支付金额不匹配,请进行处理!钱包 数据是:{},payOrder 数据是:{}]",
308 - recharge, payOrderId, toJsonString(recharge), toJsonString(payOrder)); 308 + recharge.getId(), payOrderId, toJsonString(recharge), toJsonString(payOrder));
309 throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_PRICE_NOT_MATCH); 309 throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_PRICE_NOT_MATCH);
310 } 310 }
311 // 2.3 校验支付订单的商户订单匹配 311 // 2.3 校验支付订单的商户订单匹配
312 if (notEqual(payOrder.getMerchantOrderId(), recharge.getId().toString())) { 312 if (notEqual(payOrder.getMerchantOrderId(), recharge.getId().toString())) {
313 log.error("[validatePayOrderPaid][充值订单({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", 313 log.error("[validatePayOrderPaid][充值订单({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]",
314 - recharge, payOrderId, toJsonString(payOrder)); 314 + recharge.getId(), payOrderId, toJsonString(payOrder));
315 throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR); 315 throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR);
316 } 316 }
317 return payOrder; 317 return payOrder;