Selaa lähdekoodia

mall + pay:
1. 拆分支付回调、退款回调的 URL
2. 修复微信支付回调的时间解析错误

YunaiV 1 vuosi sitten
vanhempi
commit
68a4ef98ca
14 muutettua tiedostoa jossa 166 lisäystä ja 76 poistoa
  1. 17 6
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/PayProperties.java
  2. 16 7
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java
  3. 11 7
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
  4. 63 16
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java
  5. 16 2
      yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClientIntegrationTest.java
  6. 29 28
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java
  7. 1 1
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/app/PayAppDO.java
  8. 2 2
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/notify/PayNotifyJob.java
  9. 2 2
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
  10. 2 2
      yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java
  11. 2 1
      yudao-server/src/main/resources/application-local.yaml
  12. 1 1
      yudao-server/src/main/resources/application.yaml
  13. 1 1
      yudao-ui-admin/src/views/pay/app/components/wechatChannelForm.vue
  14. 3 0
      yudao-ui-admin/src/views/pay/cashier/index.vue

+ 17 - 6
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/PayProperties.java

@@ -13,14 +13,25 @@ import javax.validation.constraints.NotEmpty;
 public class PayProperties {
 
     /**
-     * 回调地址
+     * 支付回调地址
      *
-     * 实际上,对应的 PayNotifyController 的 notifyCallback 方法的 URL
+     * 实际上,对应的 PayNotifyController 的 notifyOrder 方法的 URL
      *
-     * 注意,支付渠道统一回调到 payNotifyUrl 地址,由支付模块统一处理;然后,自己的支付模块,在回调 PayAppDO.payNotifyUrl 地址
+     * 回调顺序:支付渠道(支付宝支付、微信支付) => yudao-module-pay 的 orderNotifyUrl 地址 => 业务的 PayAppDO.orderNotifyUrl 地址
      */
-    @NotEmpty(message = "回调地址不能为空")
-    @URL(message = "回调地址的格式必须是 URL")
-    private String callbackUrl;
+    @NotEmpty(message = "支付回调地址不能为空")
+    @URL(message = "支付回调地址的格式必须是 URL")
+    private String orderNotifyUrl;
+
+    /**
+     * 退款回调地址
+     *
+     * 实际上,对应的 PayNotifyController 的 notifyRefund 方法的 URL
+     *
+     * 回调顺序:支付渠道(支付宝支付、微信支付) => yudao-module-pay 的 refundNotifyUrl 地址 => 业务的 PayAppDO.notifyRefundUrl 地址
+     */
+    @NotEmpty(message = "支付回调地址不能为空")
+    @URL(message = "支付回调地址的格式必须是 URL")
+    private String refundNotifyUrl;
 
 }

+ 16 - 7
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClient.java

@@ -22,6 +22,8 @@ public interface PayClient {
      */
     Long getId();
 
+    // ============ 支付相关 ==========
+
     /**
      * 调用支付渠道,统一下单
      *
@@ -31,6 +33,17 @@ public interface PayClient {
     PayOrderUnifiedRespDTO unifiedOrder(PayOrderUnifiedReqDTO reqDTO);
 
     /**
+     * 解析 order 回调数据
+     *
+     * @param params HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数
+     * @param body HTTP 回调接口的 request body
+     * @return 支付订单信息
+     */
+    PayOrderRespDTO parseOrderNotify(Map<String, String> params, String body);
+
+    // ============ 退款相关 ==========
+
+    /**
      * 调用支付渠道,进行退款
      *
      * @param reqDTO  统一退款请求信息
@@ -39,16 +52,12 @@ public interface PayClient {
     PayRefundRespDTO unifiedRefund(PayRefundUnifiedReqDTO reqDTO);
 
     /**
-     * 解析回调数据
+     * 解析 refund 回调数据
      *
      * @param params HTTP 回调接口 content type 为 application/x-www-form-urlencoded 的所有参数
      * @param body HTTP 回调接口的 request body
-     * @return 回调对象
-     *         1. {@link PayRefundRespDTO} 退款通知
-     *         2. {@link PayOrderRespDTO} 支付通知
+     * @return 支付订单信息
      */
-    default Object parseNotify(Map<String, String> params, String body) {
-        throw new UnsupportedOperationException("未实现 parseNotify 方法!");
-    }
+    PayRefundRespDTO parseRefundNotify(Map<String, String> params, String body);
 
 }

+ 11 - 7
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java

@@ -97,13 +97,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
 
     @Override
     @SneakyThrows
-    public Object parseNotify(Map<String, String> params, String body) {
-        // 补充说明:支付宝退款时,没有回调,这点和微信支付是不同的。并且,退款分成部分退款、和全部退款。
-        // ① 部分退款:是会有回调,但是它回调的是订单状态的同步回调,不是退款订单的回调
-        // ② 全部退款:Wap 支付有订单状态的同步回调,但是 PC/扫码又没有
-        // 所以,这里在解析时,即使是退款导致的订单状态同步,我们也忽略不做为“退款同步”,而是订单的回调。
-        // 实际上,支付宝退款只要发起成功,就可以认为退款成功,不需要等待回调。
-
+    public PayOrderRespDTO parseOrderNotify(Map<String, String> params, String body) {
         // 1. 校验回调数据
         Map<String, String> bodyObj = HttpUtil.decodeParamMap(body, StandardCharsets.UTF_8);
         AlipaySignature.rsaCheckV1(bodyObj, config.getAlipayPublicKey(),
@@ -127,6 +121,16 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
                 .build();
     }
 
+    @Override
+    public PayRefundRespDTO parseRefundNotify(Map<String, String> params, String body) {
+        // 补充说明:支付宝退款时,没有回调,这点和微信支付是不同的。并且,退款分成部分退款、和全部退款。
+        // ① 部分退款:是会有回调,但是它回调的是订单状态的同步回调,不是退款订单的回调
+        // ② 全部退款:Wap 支付有订单状态的同步回调,但是 PC/扫码又没有
+        // 所以,这里在解析时,即使是退款导致的订单状态同步,我们也忽略不做为“退款同步”,而是订单的回调。
+        // 实际上,支付宝退款只要发起成功,就可以认为退款成功,不需要等待回调。
+        throw new UnsupportedOperationException("支付宝无退款回调");
+    }
+
     // ========== 各种工具方法 ==========
 
     protected String formatAmount(Integer amount) {

+ 63 - 16
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java

@@ -14,9 +14,11 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
 import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
+import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
 import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
+import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
 import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
 import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
 import com.github.binarywang.wxpay.config.WxPayConfig;
@@ -30,8 +32,7 @@ import java.time.ZoneId;
 import java.util.Map;
 import java.util.Objects;
 
-import static cn.hutool.core.date.DatePattern.PURE_DATETIME_PATTERN;
-import static cn.hutool.core.date.DatePattern.UTC_WITH_XXX_OFFSET_PATTERN;
+import static cn.hutool.core.date.DatePattern.*;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
@@ -61,9 +62,6 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
         WxPayConfig payConfig = new WxPayConfig();
         BeanUtil.copyProperties(config, payConfig, "keyContent");
         payConfig.setTradeType(tradeType);
-//        if (WxPayClientConfig.API_VERSION_V2.equals(config.getApiVersion())) {
-//            payConfig.setSignType(WxPayConstants.SignType.MD5);
-//        }
         // weixin-pay-java 无法设置内容,只允许读取文件,所以这里要创建临时文件来解决
         if (Base64.isBase64(config.getKeyContent())) {
             payConfig.setKeyPath(FileUtils.createTempFile(Base64.decode(config.getKeyContent())).getPath());
@@ -162,8 +160,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
     }
 
     @Override
-    public Object parseNotify(Map<String, String> params, String body) {
-        log.info("[parseNotify][微信支付回调 data 数据: {}]", body);
+    public PayOrderRespDTO parseOrderNotify(Map<String, String> params, String body) {
         try {
             // 微信支付 v2 回调结果处理
             switch (config.getApiVersion()) {
@@ -183,21 +180,24 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
     }
 
     private PayOrderRespDTO parseOrderNotifyV2(String body) throws WxPayException {
-        WxPayOrderNotifyResult notifyResult = client.parseOrderNotifyResult(body);
-        Assert.isTrue(Objects.equals(notifyResult.getResultCode(), "SUCCESS"), "支付结果非 SUCCESS");
-        // 转换结果
-        return PayOrderRespDTO
-                .builder()
-                .outTradeNo(notifyResult.getOutTradeNo())
-                .channelOrderNo(notifyResult.getTransactionId())
-                .channelUserId(notifyResult.getOpenid())
-                .successTime(parseDateV2(notifyResult.getTimeEnd()))
+        // 1. 解析回调
+        WxPayOrderNotifyResult response = client.parseOrderNotifyResult(body);
+        // 2. 构建结果
+        return PayOrderRespDTO.builder()
+                .outTradeNo(response.getOutTradeNo())
+                .channelOrderNo(response.getTransactionId())
+                .channelUserId(response.getOpenid())
+                .status(Objects.equals(response.getResultCode(), "SUCCESS") ?
+                        PayOrderStatusRespEnum.SUCCESS.getStatus() : PayOrderStatusRespEnum.CLOSED.getStatus())
+                .successTime(parseDateV2(response.getTimeEnd()))
+                .rawData(response)
                 .build();
     }
 
     private PayOrderRespDTO parseOrderNotifyV3(String body) throws WxPayException {
         WxPayOrderNotifyV3Result notifyResult = client.parseOrderNotifyV3Result(body, null);
         WxPayOrderNotifyV3Result.DecryptNotifyResult result = notifyResult.getResult();
+        // TODO 芋艿:翻译下 state
         // 转换结果
         Assert.isTrue(Objects.equals(notifyResult.getResult().getTradeState(), "SUCCESS"),
                 "支付结果非 SUCCESS");
@@ -209,6 +209,49 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
                 .build();
     }
 
+    @Override
+    public PayRefundRespDTO parseRefundNotify(Map<String, String> params, String body) {
+        try {
+            // 微信支付 v2 回调结果处理
+            switch (config.getApiVersion()) {
+                case API_VERSION_V2:
+                    return parseRefundNotifyV2(body);
+                case WxPayClientConfig.API_VERSION_V3:
+                    return parseRefundNotifyV3(body);
+                default:
+                    throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
+            }
+        } catch (WxPayException e) {
+            log.error("[parseNotify][params({}) body({}) 解析失败]", params, body, e);
+//            throw buildPayException(e);
+            throw new RuntimeException(e);
+            // TODO 芋艿:缺一个异常翻译
+        }
+    }
+
+    private PayRefundRespDTO parseRefundNotifyV2(String body) throws WxPayException {
+        // 1. 解析回调
+        WxPayRefundNotifyResult response = client.parseRefundNotifyResult(body);
+        WxPayRefundNotifyResult.ReqInfo reqInfo = response.getReqInfo();
+        // 2. 构建结果
+        PayRefundRespDTO notify = new PayRefundRespDTO()
+                .setChannelRefundNo(reqInfo.getRefundId())
+                .setOutRefundNo(reqInfo.getOutRefundNo())
+                .setRawData(response);
+        if (Objects.equals("SUCCESS", reqInfo.getRefundStatus())) {
+            notify.setStatus(PayRefundStatusRespEnum.SUCCESS.getStatus())
+                    .setSuccessTime(parseDateV2B(reqInfo.getSuccessTime()));
+        } else {
+            notify.setStatus(PayRefundStatusRespEnum.FAILURE.getStatus());
+        }
+        return notify;
+    }
+
+    private PayRefundRespDTO parseRefundNotifyV3(String body) throws WxPayException {
+        // TODO 芋艿:未实现
+        return null;
+    }
+
     // ========== 各种工具方法 ==========
 
     /**
@@ -246,6 +289,10 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
         return LocalDateTimeUtil.parse(time, PURE_DATETIME_PATTERN);
     }
 
+    static LocalDateTime parseDateV2B(String time) {
+        return LocalDateTimeUtil.parse(time, NORM_DATETIME_PATTERN);
+    }
+
     static String formatDateV3(LocalDateTime time) {
         return TemporalAccessorUtil.format(time.atZone(ZoneId.systemDefault()), UTC_WITH_XXX_OFFSET_PATTERN);
     }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 16 - 2
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClientIntegrationTest.java


+ 29 - 28
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/notify/PayNotifyController.java

@@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.pay.controller.admin.notify;
 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
-import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
+import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
 import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -18,7 +18,6 @@ import javax.annotation.security.PermitAll;
 import java.util.Map;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_CHANNEL_CLIENT_NOT_FOUND;
 
 @Tag(name = "管理后台 - 支付通知")
@@ -36,22 +35,14 @@ public class PayNotifyController {
     @Resource
     private PayClientFactory payClientFactory;
 
-    /**
-     * 统一的渠道支付回调,支付宝的退款回调
-     *
-     * @param channelId 渠道编号
-     * @param params form 参数
-     * @param body request body
-     * @return 成功返回 "success"
-     */
-    @PostMapping(value = "/callback/{channelId}")
-    @Operation(summary = "支付渠道的统一回调接口 - 包括支付回调,退款回调")
+    @PostMapping(value = "/order/{channelId}")
+    @Operation(summary = "支付渠道的统一【支付】回调")
     @PermitAll
     @OperateLog(enable = false) // 回调地址,无需记录操作日志
-    public String notifyCallback(@PathVariable("channelId") Long channelId,
-                                 @RequestParam(required = false) Map<String, String> params,
-                                 @RequestBody(required = false) String body) {
-        log.info("[notifyCallback][channelId({}) 回调数据({}/{})]", channelId, params, body);
+    public String notifyOrder(@PathVariable("channelId") Long channelId,
+                              @RequestParam(required = false) Map<String, String> params,
+                              @RequestBody(required = false) String body) {
+        log.info("[notifyOrder][channelId({}) 回调数据({}/{})]", channelId, params, body);
         // 1. 校验支付渠道是否存在
         PayClient payClient = payClientFactory.getPayClient(channelId);
         if (payClient == null) {
@@ -60,20 +51,30 @@ public class PayNotifyController {
         }
 
         // 2. 解析通知数据
-        Object notify = payClient.parseNotify(params, body);
+        PayOrderRespDTO notify = payClient.parseOrderNotify(params, body);
+        orderService.notifyOrder(channelId, notify);
+        return "success";
+    }
 
-        // 3. 处理通知
-        // 3.1:退款通知
-        if (notify instanceof PayRefundRespDTO) {
-            refundService.notifyRefund(channelId, (PayRefundRespDTO) notify);
-            return "success";
-        }
-        // 3.2:支付通知
-        if (notify instanceof PayOrderRespDTO) {
-            orderService.notifyOrder(channelId, (PayOrderRespDTO) notify);
-            return "success";
+    @PostMapping(value = "/refund/{channelId}")
+    @Operation(summary = "支付渠道的统一【退款】回调")
+    @PermitAll
+    @OperateLog(enable = false) // 回调地址,无需记录操作日志
+    public String notifyRefund(@PathVariable("channelId") Long channelId,
+                              @RequestParam(required = false) Map<String, String> params,
+                              @RequestBody(required = false) String body) {
+        log.info("[notifyRefund][channelId({}) 回调数据({}/{})]", channelId, params, body);
+        // 1. 校验支付渠道是否存在
+        PayClient payClient = payClientFactory.getPayClient(channelId);
+        if (payClient == null) {
+            log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId);
+            throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND);
         }
-        throw new UnsupportedOperationException("未知通知:" + toJsonString(notify));
+
+        // 2. 解析通知数据
+        PayRefundRespDTO notify = payClient.parseRefundNotify(params, body);
+        refundService.notifyRefund(channelId, notify);
+        return "success";
     }
 
 }

+ 1 - 1
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/app/PayAppDO.java

@@ -48,7 +48,7 @@ public class PayAppDO extends BaseDO {
     /**
      * 支付结果的回调地址
      */
-    private String payNotifyUrl;
+    private String orderNotifyUrl;
     /**
      * 退款结果的回调地址
      */

+ 2 - 2
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/job/notify/PayNotifyJob.java

@@ -20,11 +20,11 @@ import javax.annotation.Resource;
 public class PayNotifyJob implements JobHandler {
 
     @Resource
-    private PayNotifyService payNotifyCoreService;
+    private PayNotifyService payNotifyService;
 
     @Override
     public String execute(String param) throws Exception {
-        int notifyCount = payNotifyCoreService.executeNotify();
+        int notifyCount = payNotifyService.executeNotify();
         return String.format("执行支付通知 %s 个", notifyCount);
     }
 

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

@@ -125,7 +125,7 @@ public class PayOrderServiceImpl implements PayOrderService {
         // 创建支付交易单
         order = PayOrderConvert.INSTANCE.convert(reqDTO).setAppId(app.getId())
                 // 商户相关字段
-                .setNotifyUrl(app.getPayNotifyUrl()).setNotifyStatus(PayOrderNotifyStatusEnum.NO.getStatus())
+                .setNotifyUrl(app.getOrderNotifyUrl()).setNotifyStatus(PayOrderNotifyStatusEnum.NO.getStatus())
                 // 订单相关字段
                 .setStatus(PayOrderStatusEnum.WAITING.getStatus())
                 // 退款相关字段
@@ -206,7 +206,7 @@ public class PayOrderServiceImpl implements PayOrderService {
      * @return 支付渠道的回调地址  配置地址 + "/" + channel id
      */
     private String genChannelPayNotifyUrl(PayChannelDO channel) {
-        return payProperties.getCallbackUrl() + "/" + channel.getId();
+        return payProperties.getOrderNotifyUrl() + "/" + channel.getId();
     }
 
     private String generateOrderExtensionNo() {

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

@@ -134,7 +134,7 @@ public class PayRefundServiceImpl implements PayRefundService {
                 .setRefundPrice(reqDTO.getPrice())
                 .setOutTradeNo(orderExtension.getNo())
                 .setOutRefundNo(refund.getNo())
-                .setNotifyUrl(genChannelPayNotifyUrl(channel)) // TODO 芋艿:优化下 notifyUrl
+                .setNotifyUrl(genChannelPayNotifyUrl(channel))
                 .setReason(reqDTO.getReason());
         PayRefundRespDTO refundRespDTO = client.unifiedRefund(unifiedReqDTO); // TODO 增加一个 channelErrorCode、channelErrorMsg 字段
         // 2.3 处理退款返回
@@ -183,7 +183,7 @@ public class PayRefundServiceImpl implements PayRefundService {
      * @return 支付渠道的回调地址  配置地址 + "/" + channel id
      */
     private String genChannelPayNotifyUrl(PayChannelDO channel) {
-        return payProperties.getCallbackUrl() + "/" + channel.getId();
+        return payProperties.getRefundNotifyUrl() + "/" + channel.getId();
     }
 
     private String generateRefundNo() {

+ 2 - 1
yudao-server/src/main/resources/application-local.yaml

@@ -194,7 +194,8 @@ yudao:
       - ${spring.boot.admin.context-path}/** # 不处理 Spring Boot Admin 的请求
       - ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
   pay:
-    callback-url: http://yunai.natapp1.cc/admin-api/pay/notify/callback
+    order-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/order # 支付渠道的【支付】回调地址
+    refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址
   access-log: # 访问日志的配置项
     enable: false
   error-code: # 错误码相关配置项

+ 1 - 1
yudao-server/src/main/resources/application.yaml

@@ -142,7 +142,7 @@ yudao:
       - /admin-api/system/captcha/check # 校验图片验证码,和租户无关
       - /admin-api/infra/file/*/get/** # 获取图片,和租户无关
       - /admin-api/system/sms/callback/* # 短信回调接口,无法带上租户编号
-      - /admin-api/pay/notify/callback/* # 支付回调通知,不携带租户编号
+      - /admin-api/pay/notify/** # 支付回调通知,不携带租户编号
       - /jmreport/* # 积木报表,无法携带租户编号
       - /admin-api/mp/open/** # 微信公众号开放平台,微信回调接口,无法携带租户编号
     ignore-tables:

+ 1 - 1
yudao-ui-admin/src/views/pay/app/components/wechatChannelForm.vue

@@ -1,7 +1,7 @@
 <template>
   <div>
     <el-dialog :visible.sync="transferParam.wechatOpen" :title="title" @close="close" append-to-body width="800px">
-      <el-form ref="wechatJsApiForm" :model="form" :rules="rules" size="medium" label-width="100px"
+      <el-form ref="wechatJsApiForm" :model="form" :rules="rules" size="medium" label-width="120px"
                v-loading="transferParam.loading">
         <el-form-item label-width="180px" label="渠道费率" prop="feeRate">
           <el-input v-model="form.feeRate" placeholder="请输入渠道费率" clearable :style="{width: '100%'}">

+ 3 - 0
yudao-ui-admin/src/views/pay/cashier/index.vue

@@ -331,6 +331,9 @@ export default {
      *                  ③ close:支付已关闭
      */
     goReturnUrl(payResult) {
+      // 清理任务
+      this.clearQueryInterval();
+
       // 未配置的情况下,只能关闭
       if (!this.returnUrl) {
         this.$tab.closePage();