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,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 | * @param status 状态 | 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,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil; | ||
| 4 | import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; | 4 | import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 7 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | 8 | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| 8 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | 9 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| 9 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; | 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 +12,14 @@ import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; | ||
| 11 | import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; | 12 | import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; |
| 12 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; | 13 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderDO; |
| 13 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; | 14 | import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; |
| 15 | +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; | ||
| 14 | import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; | 16 | import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; |
| 15 | import cn.iocoder.yudao.module.pay.service.app.PayAppService; | 17 | import cn.iocoder.yudao.module.pay.service.app.PayAppService; |
| 16 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; | 18 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 17 | import com.google.common.collect.Maps; | 19 | import com.google.common.collect.Maps; |
| 18 | import io.swagger.v3.oas.annotations.Operation; | 20 | import io.swagger.v3.oas.annotations.Operation; |
| 19 | import io.swagger.v3.oas.annotations.Parameter; | 21 | import io.swagger.v3.oas.annotations.Parameter; |
| 22 | +import io.swagger.v3.oas.annotations.Parameters; | ||
| 20 | import io.swagger.v3.oas.annotations.tags.Tag; | 23 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 21 | import jakarta.annotation.Resource; | 24 | import jakarta.annotation.Resource; |
| 22 | import jakarta.servlet.http.HttpServletResponse; | 25 | import jakarta.servlet.http.HttpServletResponse; |
| @@ -51,10 +54,21 @@ public class PayOrderController { | @@ -51,10 +54,21 @@ public class PayOrderController { | ||
| 51 | 54 | ||
| 52 | @GetMapping("/get") | 55 | @GetMapping("/get") |
| 53 | @Operation(summary = "获得支付订单") | 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 | @PreAuthorize("@ss.hasPermission('pay:order:query')") | 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 | @GetMapping("/get-detail") | 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 | package cn.iocoder.yudao.module.pay.controller.app.order; | 1 | package cn.iocoder.yudao.module.pay.controller.app.order; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | ||
| 4 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; | 5 | import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; |
| 5 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO; | 6 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderRespVO; |
| 6 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; | 7 | import cn.iocoder.yudao.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO; |
| 7 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; | 8 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO; |
| 8 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; | 9 | import cn.iocoder.yudao.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO; |
| 9 | import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; | 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 | import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; | 13 | import cn.iocoder.yudao.module.pay.framework.pay.core.WalletPayClient; |
| 11 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; | 14 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 12 | import com.google.common.collect.Maps; | 15 | import com.google.common.collect.Maps; |
| 13 | import io.swagger.v3.oas.annotations.Operation; | 16 | import io.swagger.v3.oas.annotations.Operation; |
| 14 | import io.swagger.v3.oas.annotations.Parameter; | 17 | import io.swagger.v3.oas.annotations.Parameter; |
| 18 | +import io.swagger.v3.oas.annotations.Parameters; | ||
| 15 | import io.swagger.v3.oas.annotations.tags.Tag; | 19 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 16 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
| 17 | import org.springframework.validation.annotation.Validated; | 21 | import org.springframework.validation.annotation.Validated; |
| @@ -37,12 +41,22 @@ public class AppPayOrderController { | @@ -37,12 +41,22 @@ public class AppPayOrderController { | ||
| 37 | @Resource | 41 | @Resource |
| 38 | private PayOrderService payOrderService; | 42 | private PayOrderService payOrderService; |
| 39 | 43 | ||
| 40 | - // TODO 芋艿:临时 demo,技术打样。 | ||
| 41 | @GetMapping("/get") | 44 | @GetMapping("/get") |
| 42 | @Operation(summary = "获得支付订单") | 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 | @PostMapping("/submit") | 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,6 +24,11 @@ public interface PayOrderExtensionMapper extends BaseMapperX<PayOrderExtensionDO | ||
| 24 | return selectList(PayOrderExtensionDO::getOrderId, orderId); | 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 | default List<PayOrderExtensionDO> selectListByStatusAndCreateTimeGe(Integer status, LocalDateTime minCreateTime) { | 32 | default List<PayOrderExtensionDO> selectListByStatusAndCreateTimeGe(Integer status, LocalDateTime minCreateTime) { |
| 28 | return selectList(new LambdaQueryWrapper<PayOrderExtensionDO>() | 33 | return selectList(new LambdaQueryWrapper<PayOrderExtensionDO>() |
| 29 | .eq(PayOrderExtensionDO::getStatus, status) | 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,6 +140,16 @@ public interface PayOrderService { | ||
| 140 | int syncOrder(LocalDateTime minCreateTime); | 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 | * @return 过期的订单数量 | 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,6 +467,18 @@ public class PayOrderServiceImpl implements PayOrderService { | ||
| 467 | return count; | 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 | * |