浏览代码

mall + pay:
1. 增加退款同步的 Job

YunaiV 1 年之前
父节点
当前提交
9812881094

+ 4 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/refund/PayRefundMapper.java

@@ -68,4 +68,8 @@ public interface PayRefundMapper extends BaseMapperX<PayRefundDO> {
                 .orderByDesc(PayRefundDO::getId));
     }
 
+    default List<PayRefundDO> selectListByStatus(Integer status) {
+        return selectList(PayRefundDO::getStatus, status);
+    }
+
 }

+ 1 - 1
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/order/PayOrderSyncJob.java

@@ -37,7 +37,7 @@ public class PayOrderSyncJob implements JobHandler {
     public String execute(String param) {
         LocalDateTime minCreateTime = LocalDateTime.now().minus(CREATE_TIME_DURATION_BEFORE);
         int count = orderService.syncOrder(minCreateTime);
-        return StrUtil.format("同步订单 {} 个", count);
+        return StrUtil.format("同步支付订单 {} 个", count);
     }
 
 }

+ 0 - 4
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/package-info.java

@@ -1,4 +0,0 @@
-/**
- * 占位,无特殊含义
- */
-package cn.iocoder.yudao.module.pay.job;

+ 31 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/refund/PayRefundSyncJob.java

@@ -0,0 +1,31 @@
+package cn.iocoder.yudao.module.pay.job.refund;
+
+import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
+import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
+import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 退款订单的同步 Job
+ *
+ * 由于退款订单的状态,是由支付渠道异步通知进行同步,考虑到异步通知可能会失败(小概率),所以需要定时进行同步。
+ *
+ * @author 芋道源码
+ */
+@Component
+@TenantJob
+public class PayRefundSyncJob implements JobHandler {
+
+    @Resource
+    private PayRefundService refundService;
+
+    @Override
+    public String execute(String param) {
+        int count = refundService.syncRefund();
+        return StrUtil.format("同步退款订单 {} 个", count);
+    }
+
+}

+ 1 - 1
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java

@@ -450,7 +450,7 @@ public class PayOrderServiceImpl implements PayOrderService {
             // 1.2 回调支付结果
             notifyOrder(orderExtension.getChannelId(), respDTO);
 
-            // 2. 如果是已支付,则返回 1
+            // 2. 如果是已支付,则返回 true
             return PayOrderStatusRespEnum.isSuccess(respDTO.getStatus());
         } catch (Throwable e) {
             log.error("[syncOrder][orderExtension({}) 同步支付状态异常]", orderExtension.getId(), e);

+ 7 - 0
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundService.java

@@ -64,4 +64,11 @@ public interface PayRefundService {
      */
     void notifyRefund(Long channelId, PayRefundRespDTO notify);
 
+    /**
+     * 同步渠道退款的退款状态
+     *
+     * @return 同步到状态的退款数量,包括退款成功、退款失败
+     */
+    int syncRefund();
+
 }

+ 45 - 2
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pay.service.refund;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.extra.spring.SpringUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
@@ -242,7 +243,7 @@ public class PayRefundServiceImpl implements PayRefundService {
         // 2. 更新订单
         orderService.updateOrderRefundPrice(refund.getOrderId(), refund.getRefundPrice());
 
-        // 3. 插入退款通知记录 TODO 芋艿:退款成功
+        // 3. 插入退款通知记录
         notifyService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder()
                 .type(PayNotifyTypeEnum.REFUND.getType()).dataId(refund.getId()).build());
     }
@@ -274,11 +275,53 @@ public class PayRefundServiceImpl implements PayRefundService {
         }
         log.info("[notifyRefundFailure][退款订单({}) 更新为退款失败]", refund.getId());
 
-        // 2. 插入退款通知记录 TODO 芋艿:退款失败
+        // 2. 插入退款通知记录
         notifyService.createPayNotifyTask(PayNotifyTaskCreateReqDTO.builder()
                 .type(PayNotifyTypeEnum.REFUND.getType()).dataId(refund.getId()).build());
     }
 
+    @Override
+    public int syncRefund() {
+        // 1. 查询指定创建时间内的待退款订单
+        List<PayRefundDO> refunds = refundMapper.selectListByStatus(PayRefundStatusEnum.WAITING.getStatus());
+        if (CollUtil.isEmpty(refunds)) {
+            return 0;
+        }
+        // 2. 遍历执行
+        int count = 0;
+        for (PayRefundDO refund : refunds) {
+            count += syncRefund(refund) ? 1 : 0;
+        }
+        return count;
+    }
+
+    /**
+     * 同步单个退款订单
+     *
+     * @param refund 退款订单
+     * @return 是否同步到
+     */
+    private boolean syncRefund(PayRefundDO refund) {
+        try {
+            // 1.1 查询退款订单信息
+            PayClient payClient = payClientFactory.getPayClient(refund.getChannelId());
+            if (payClient == null) {
+                log.error("[syncRefund][渠道编号({}) 找不到对应的支付客户端]", refund.getChannelId());
+                return false;
+            }
+            PayRefundRespDTO respDTO = payClient.getRefund(refund.getOrderNo(), refund.getNo());
+            // 1.2 回调退款结果
+            notifyRefund(refund.getChannelId(), respDTO);
+
+            // 2. 如果同步到,则返回 true
+            return PayRefundStatusEnum.isSuccess(respDTO.getStatus())
+                    || PayRefundStatusEnum.isFailure(respDTO.getStatus());
+        } catch (Throwable e) {
+            log.error("[syncRefund][refund({}) 同步退款状态异常]", refund.getId(), e);
+            return false;
+        }
+    }
+
     /**
      * 获得自身的代理对象,解决 AOP 生效问题
      *