Commit 2c2e9fe87d7d4a2357bd57c27e423faada12bab9
1 parent
4d9d702c
【功能优化】支付:查询支付订单时,增加 sync 主动轮询,解决支付宝、微信存在延迟的问题
Showing
6 changed files
with
72 additions
and
7 deletions
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/order/PayOrderStatusEnum.java
| ... | ... | @@ -31,6 +31,16 @@ public enum PayOrderStatusEnum implements IntArrayValuable { |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | /** |
| 34 | + * 判断是否等待支付 | |
| 35 | + * | |
| 36 | + * @param status 状态 | |
| 37 | + * @return 是否等待支付 | |
| 38 | + */ | |
| 39 | + public static boolean isWaiting(Integer status) { | |
| 40 | + return Objects.equals(status, WAITING.getStatus()); | |
| 41 | + } | |
| 42 | + | |
| 43 | + /** | |
| 34 | 44 | * 判断是否支付成功 |
| 35 | 45 | * |
| 36 | 46 | * @param status 状态 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java
| ... | ... | @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil; |
| 4 | 4 | import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; |
| 5 | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 6 | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 7 | 8 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 8 | 9 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| 9 | 10 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; |
| ... | ... | @@ -11,12 +12,14 @@ import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; |
| 11 | 12 | import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; |
| 12 | 13 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; |
| 13 | 14 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; |
| 15 | +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | |
| 14 | 16 | import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; |
| 15 | 17 | import cn.iocoder.yudao.module.pay.service.app.PayAppService; |
| 16 | 18 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 17 | 19 | import com.google.common.collect.Maps; |
| 18 | 20 | import io.swagger.v3.oas.annotations.Operation; |
| 19 | 21 | import io.swagger.v3.oas.annotations.Parameter; |
| 22 | +import io.swagger.v3.oas.annotations.Parameters; | |
| 20 | 23 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 21 | 24 | import jakarta.annotation.Resource; |
| 22 | 25 | import jakarta.servlet.http.HttpServletResponse; |
| ... | ... | @@ -51,10 +54,21 @@ public class PayOrderController { |
| 51 | 54 | |
| 52 | 55 | @GetMapping("/get") |
| 53 | 56 | @Operation(summary = "获得支付订单") |
| 54 | - @Parameter(name = "id", description = "编号", required = true, example = "1024") | |
| 57 | + @Parameters({ | |
| 58 | + @Parameter(name = "id", description = "编号", required = true, example = "1024"), | |
| 59 | + @Parameter(name = "sync", description = "是否同步", example = "true") | |
| 60 | + }) | |
| 55 | 61 | @PreAuthorize("@ss.hasPermission('pay:order:query')") |
| 56 | - public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id) { | |
| 57 | - return success(PayOrderConvert.INSTANCE.convert(orderService.getOrder(id))); | |
| 62 | + public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id, | |
| 63 | + @RequestParam(value = "sync", required = false) Boolean sync) { | |
| 64 | + PayOrderDO order = orderService.getOrder(id); | |
| 65 | + // sync 仅在等待支付 | |
| 66 | + if (Boolean.TRUE.equals(sync) && PayOrderStatusEnum.isWaiting(order.getStatus())) { | |
| 67 | + orderService.syncOrderQuietly(order.getId()); | |
| 68 | + // 重新查询,因为同步后,可能会有变化 | |
| 69 | + order = orderService.getOrder(id); | |
| 70 | + } | |
| 71 | + return success(BeanUtils.toBean(order, PayOrderRespVO.class)); | |
| 58 | 72 | } |
| 59 | 73 | |
| 60 | 74 | @GetMapping("/get-detail") | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/order/AppPayOrderController.java
| 1 | 1 | package cn.iocoder.yudao.module.pay.controller.app.order; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 4 | 5 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| 5 | 6 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO; |
| 6 | 7 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; |
| 7 | 8 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; |
| 8 | 9 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; |
| 9 | 10 | import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; |
| 11 | +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; | |
| 12 | +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | |
| 10 | 13 | import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; |
| 11 | 14 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 12 | 15 | import com.google.common.collect.Maps; |
| 13 | 16 | import io.swagger.v3.oas.annotations.Operation; |
| 14 | 17 | import io.swagger.v3.oas.annotations.Parameter; |
| 18 | +import io.swagger.v3.oas.annotations.Parameters; | |
| 15 | 19 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 16 | 20 | import lombok.extern.slf4j.Slf4j; |
| 17 | 21 | import org.springframework.validation.annotation.Validated; |
| ... | ... | @@ -37,12 +41,22 @@ public class AppPayOrderController { |
| 37 | 41 | @Resource |
| 38 | 42 | private PayOrderService payOrderService; |
| 39 | 43 | |
| 40 | - // TODO 芋艿:临时 demo,技术打样。 | |
| 41 | 44 | @GetMapping("/get") |
| 42 | 45 | @Operation(summary = "获得支付订单") |
| 43 | - @Parameter(name = "id", description = "编号", required = true, example = "1024") | |
| 44 | - public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id) { | |
| 45 | - return success(PayOrderConvert.INSTANCE.convert(payOrderService.getOrder(id))); | |
| 46 | + @Parameters({ | |
| 47 | + @Parameter(name = "id", description = "编号", required = true, example = "1024"), | |
| 48 | + @Parameter(name = "sync", description = "是否同步", example = "true") | |
| 49 | + }) | |
| 50 | + public CommonResult<PayOrderRespVO> getOrder(@RequestParam("id") Long id, | |
| 51 | + @RequestParam(value = "sync", required = false) Boolean sync) { | |
| 52 | + PayOrderDO order = payOrderService.getOrder(id); | |
| 53 | + // sync 仅在等待支付 | |
| 54 | + if (Boolean.TRUE.equals(sync) && PayOrderStatusEnum.isWaiting(order.getStatus())) { | |
| 55 | + payOrderService.syncOrderQuietly(order.getId()); | |
| 56 | + // 重新查询,因为同步后,可能会有变化 | |
| 57 | + order = payOrderService.getOrder(id); | |
| 58 | + } | |
| 59 | + return success(BeanUtils.toBean(order, PayOrderRespVO.class)); | |
| 46 | 60 | } |
| 47 | 61 | |
| 48 | 62 | @PostMapping("/submit") | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/order/PayOrderExtensionMapper.java
| ... | ... | @@ -24,6 +24,11 @@ public interface PayOrderExtensionMapper extends BaseMapperX<PayOrderExtensionDO |
| 24 | 24 | return selectList(PayOrderExtensionDO::getOrderId, orderId); |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | + default List<PayOrderExtensionDO> selectListByOrderIdAndStatus(Long orderId, Integer status) { | |
| 28 | + return selectList(PayOrderExtensionDO::getOrderId, orderId, | |
| 29 | + PayOrderExtensionDO::getStatus, status); | |
| 30 | + } | |
| 31 | + | |
| 27 | 32 | default List<PayOrderExtensionDO> selectListByStatusAndCreateTimeGe(Integer status, LocalDateTime minCreateTime) { |
| 28 | 33 | return selectList(new LambdaQueryWrapper<PayOrderExtensionDO>() |
| 29 | 34 | .eq(PayOrderExtensionDO::getStatus, status) | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderService.java
| ... | ... | @@ -140,6 +140,16 @@ public interface PayOrderService { |
| 140 | 140 | int syncOrder(LocalDateTime minCreateTime); |
| 141 | 141 | |
| 142 | 142 | /** |
| 143 | + * 同步订单的支付状态 | |
| 144 | + * | |
| 145 | + * 1. Quietly 表示,即使同步失败,也不会抛出异常 | |
| 146 | + * 2. 什么时候回出现异常?因为是主动同步,可能和支付渠道的异步回调存在并发冲突,导致抛出异常 | |
| 147 | + * | |
| 148 | + * @param id 订单编号 | |
| 149 | + */ | |
| 150 | + void syncOrderQuietly(Long id); | |
| 151 | + | |
| 152 | + /** | |
| 143 | 153 | * 将已过期的订单,状态修改为已关闭 |
| 144 | 154 | * |
| 145 | 155 | * @return 过期的订单数量 | ... | ... |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
| ... | ... | @@ -467,6 +467,18 @@ public class PayOrderServiceImpl implements PayOrderService { |
| 467 | 467 | return count; |
| 468 | 468 | } |
| 469 | 469 | |
| 470 | + @Override | |
| 471 | + public void syncOrderQuietly(Long id) { | |
| 472 | + // 1. 查询待支付订单 | |
| 473 | + List<PayOrderExtensionDO> orderExtensions = orderExtensionMapper.selectListByOrderIdAndStatus(id, | |
| 474 | + PayOrderStatusEnum.WAITING.getStatus()); | |
| 475 | + | |
| 476 | + // 2. 遍历执行 | |
| 477 | + for (PayOrderExtensionDO orderExtension : orderExtensions) { | |
| 478 | + syncOrder(orderExtension); | |
| 479 | + } | |
| 480 | + } | |
| 481 | + | |
| 470 | 482 | /** |
| 471 | 483 | * 同步单个支付拓展单 |
| 472 | 484 | * | ... | ... |