Commit 567cbeae681e4978f6ebe9292287aaa497ef123e
1 parent
3bde43b1
【功能优化】商城:商城订单的支付回调,增加“已支付”情况下的防重处理
Showing
3 changed files
with
45 additions
and
51 deletions
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 | 9 | import cn.hutool.core.util.RandomUtil; |
| 10 | 10 | import cn.hutool.core.util.StrUtil; |
| 11 | 11 | import cn.hutool.extra.spring.SpringUtil; |
| 12 | -import cn.iocoder.yudao.framework.common.core.KeyValue; | |
| 13 | 12 | import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; |
| 14 | 13 | import cn.iocoder.yudao.framework.common.util.json.JsonUtils; |
| 15 | 14 | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| ... | ... | @@ -269,12 +268,24 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 269 | 268 | @Transactional(rollbackFor = Exception.class) |
| 270 | 269 | @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_PAY) |
| 271 | 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 | 289 | int updateCount = tradeOrderMapper.updateByIdAndStatus(id, order.getStatus(), |
| 279 | 290 | new TradeOrderDO().setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()).setPayStatus(true) |
| 280 | 291 | .setPayTime(LocalDateTime.now()).setPayChannelCode(payOrder.getChannelCode())); |
| ... | ... | @@ -282,66 +293,49 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { |
| 282 | 293 | throw exception(ORDER_UPDATE_PAID_STATUS_NOT_UNPAID); |
| 283 | 294 | } |
| 284 | 295 | |
| 285 | - // 3. 执行 TradeOrderHandler 的后置处理 | |
| 296 | + // 4. 执行 TradeOrderHandler 的后置处理 | |
| 286 | 297 | List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id); |
| 287 | 298 | tradeOrderHandlers.forEach(handler -> handler.afterPayOrder(order, orderItems)); |
| 288 | 299 | |
| 289 | - // 4. 记录订单日志 | |
| 300 | + // 5. 记录订单日志 | |
| 290 | 301 | TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.UNDELIVERED.getStatus()); |
| 291 | 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 | 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 | 314 | PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); |
| 322 | 315 | if (payOrder == null) { |
| 323 | - log.error("[validateOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", id, payOrderId); | |
| 316 | + log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order.getId(), payOrderId); | |
| 324 | 317 | throw exception(ORDER_NOT_FOUND); |
| 325 | 318 | } |
| 326 | - // 校验支付单已支付 | |
| 319 | + | |
| 320 | + // 2.1 校验支付单已支付 | |
| 327 | 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 | 324 | throw exception(ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); |
| 331 | 325 | } |
| 332 | - // 校验支付金额一致 | |
| 326 | + // 2.2 校验支付金额一致 | |
| 333 | 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 | 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 | 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 | 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 | 154 | // 1. 校验支付单是否存在 |
| 155 | 155 | PayOrderRespDTO payOrder = payOrderApi.getOrder(payOrderId); |
| 156 | 156 | if (payOrder == null) { |
| 157 | - log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order, payOrderId); | |
| 157 | + log.error("[validatePayOrderPaid][order({}) payOrder({}) 不存在,请进行处理!]", order.getId(), payOrderId); | |
| 158 | 158 | throw exception(PAY_ORDER_NOT_FOUND); |
| 159 | 159 | } |
| 160 | 160 | // 2.1 校验支付单已支付 |
| 161 | 161 | if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { |
| 162 | 162 | log.error("[validatePayOrderPaid][order({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", |
| 163 | - order, payOrderId, toJsonString(payOrder)); | |
| 163 | + order.getId(), payOrderId, toJsonString(payOrder)); | |
| 164 | 164 | throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_STATUS_NOT_SUCCESS); |
| 165 | 165 | } |
| 166 | 166 | // 2.1 校验支付金额一致 |
| 167 | 167 | if (notEqual(payOrder.getPrice(), order.getPrice())) { |
| 168 | 168 | log.error("[validatePayOrderPaid][order({}) payOrder({}) 支付金额不匹配,请进行处理!order 数据是:{},payOrder 数据是:{}]", |
| 169 | - order, payOrderId, toJsonString(order), toJsonString(payOrder)); | |
| 169 | + order.getId(), payOrderId, toJsonString(order), toJsonString(payOrder)); | |
| 170 | 170 | throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_PRICE_NOT_MATCH); |
| 171 | 171 | } |
| 172 | 172 | // 2.2 校验支付订单匹配(二次) |
| 173 | 173 | if (notEqual(payOrder.getMerchantOrderId(), order.getId().toString())) { |
| 174 | 174 | log.error("[validatePayOrderPaid][order({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", |
| 175 | - order, payOrderId, toJsonString(payOrder)); | |
| 175 | + order.getId(), payOrderId, toJsonString(payOrder)); | |
| 176 | 176 | throw exception(DEMO_ORDER_UPDATE_PAID_FAIL_PAY_ORDER_ID_ERROR); |
| 177 | 177 | } |
| 178 | 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 | 292 | PayOrderDO payOrder = payOrderService.getOrder(payOrderId); |
| 293 | 293 | if (payOrder == null) { |
| 294 | 294 | log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 不存在,请进行处理!]", |
| 295 | - recharge, payOrderId); | |
| 295 | + recharge.getId(), payOrderId); | |
| 296 | 296 | throw exception(PAY_ORDER_NOT_FOUND); |
| 297 | 297 | } |
| 298 | 298 | |
| 299 | 299 | // 2.1 校验支付单已支付 |
| 300 | 300 | if (!PayOrderStatusEnum.isSuccess(payOrder.getStatus())) { |
| 301 | 301 | log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 未支付,请进行处理!payOrder 数据是:{}]", |
| 302 | - recharge, payOrderId, toJsonString(payOrder)); | |
| 302 | + recharge.getId(), payOrderId, toJsonString(payOrder)); | |
| 303 | 303 | throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_STATUS_NOT_SUCCESS); |
| 304 | 304 | } |
| 305 | 305 | // 2.2 校验支付金额一致 |
| 306 | 306 | if (notEqual(payOrder.getPrice(), recharge.getPayPrice())) { |
| 307 | 307 | log.error("[validatePayOrderPaid][充值订单({}) payOrder({}) 支付金额不匹配,请进行处理!钱包 数据是:{},payOrder 数据是:{}]", |
| 308 | - recharge, payOrderId, toJsonString(recharge), toJsonString(payOrder)); | |
| 308 | + recharge.getId(), payOrderId, toJsonString(recharge), toJsonString(payOrder)); | |
| 309 | 309 | throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_PRICE_NOT_MATCH); |
| 310 | 310 | } |
| 311 | 311 | // 2.3 校验支付订单的商户订单匹配 |
| 312 | 312 | if (notEqual(payOrder.getMerchantOrderId(), recharge.getId().toString())) { |
| 313 | 313 | log.error("[validatePayOrderPaid][充值订单({}) 支付单不匹配({}),请进行处理!payOrder 数据是:{}]", |
| 314 | - recharge, payOrderId, toJsonString(payOrder)); | |
| 314 | + recharge.getId(), payOrderId, toJsonString(payOrder)); | |
| 315 | 315 | throw exception(WALLET_RECHARGE_UPDATE_PAID_PAY_ORDER_ID_ERROR); |
| 316 | 316 | } |
| 317 | 317 | return payOrder; | ... | ... |