Commit 7caf8e900f393c051abcc41c4f2abf4be30df87e

Authored by YunaiV
1 parent ecdc3961

mall + pay:

1. 增加微信 bar 和 native 的集成测试,方便调试配置
Showing 13 changed files with 265 additions and 51 deletions
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/refund/PayRefundUnifiedReqDTO.java
... ... @@ -46,11 +46,19 @@ public class PayRefundUnifiedReqDTO {
46 46 private String reason;
47 47  
48 48 /**
  49 + * 支付金额,单位:分
  50 + *
  51 + * 目前微信支付在退款的时候,必须传递该字段
  52 + */
  53 + @NotNull(message = "支付金额不能为空")
  54 + @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
  55 + private Integer payPrice;
  56 + /**
49 57 * 退款金额,单位:分
50 58 */
51 59 @NotNull(message = "退款金额不能为空")
52 60 @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
53   - private Integer price;
  61 + private Integer refundPrice;
54 62  
55 63 /**
56 64 * 退款结果的 notify 回调地址
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
... ... @@ -67,7 +67,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
67 67 AlipayTradeRefundModel model = new AlipayTradeRefundModel();
68 68 model.setOutTradeNo(reqDTO.getOutTradeNo());
69 69 model.setOutRequestNo(reqDTO.getOutRefundNo());
70   - model.setRefundAmount(formatAmount(reqDTO.getPrice()));
  70 + model.setRefundAmount(formatAmount(reqDTO.getRefundPrice()));
71 71 model.setRefundReason(reqDTO.getReason());
72 72 // 1.2 构建 AlipayTradePayRequest 请求
73 73 AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
... ... @@ -75,6 +75,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
75 75 try {
76 76 // 2.1 执行请求
77 77 AlipayTradeRefundResponse response = client.execute(request);
  78 + // 2.2 创建返回结果
78 79 PayRefundRespDTO refund = new PayRefundRespDTO()
79 80 .setOutRefundNo(reqDTO.getOutRefundNo())
80 81 .setRawData(response);
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java
... ... @@ -9,10 +9,15 @@ import cn.iocoder.yudao.framework.common.util.io.FileUtils;
9 9 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
10 10 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
11 11 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
  12 +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
  13 +import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
12 14 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
13 15 import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
  16 +import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
14 17 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
15 18 import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
  19 +import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
  20 +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
16 21 import com.github.binarywang.wxpay.config.WxPayConfig;
17 22 import com.github.binarywang.wxpay.exception.WxPayException;
18 23 import com.github.binarywang.wxpay.service.WxPayService;
... ... @@ -80,6 +85,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
80 85 throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
81 86 }
82 87 } catch (WxPayException e) {
  88 + // todo 芋艿:异常的处理;
83 89 throw buildUnifiedOrderException(reqDTO, e);
84 90 }
85 91 }
... ... @@ -102,6 +108,51 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
102 108 protected abstract PayOrderUnifiedRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO)
103 109 throws WxPayException;
104 110  
  111 + @Override
  112 + protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
  113 + try {
  114 + switch (config.getApiVersion()) {
  115 + case WxPayClientConfig.API_VERSION_V2:
  116 + return doUnifiedRefundV2(reqDTO);
  117 + case WxPayClientConfig.API_VERSION_V3:
  118 + return doUnifiedRefundV3(reqDTO);
  119 + default:
  120 + throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
  121 + }
  122 + } catch (WxPayException e) {
  123 + // todo 芋艿:异常的处理;
  124 + throw buildUnifiedOrderException(null, e);
  125 + }
  126 + }
  127 +
  128 + private PayRefundRespDTO doUnifiedRefundV2(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
  129 + // 1. 构建 WxPayRefundRequest 请求
  130 + WxPayRefundRequest request = new WxPayRefundRequest()
  131 + .setOutTradeNo(reqDTO.getOutTradeNo())
  132 + .setOutRefundNo(reqDTO.getOutRefundNo())
  133 + .setRefundFee(reqDTO.getRefundPrice())
  134 + .setRefundDesc(reqDTO.getReason())
  135 + .setTotalFee(reqDTO.getPayPrice())
  136 + .setNotifyUrl(reqDTO.getNotifyUrl());
  137 + // 2.1 执行请求
  138 + WxPayRefundResult response = client.refundV2(request); // TODO 芋艿:可以分成 V2 和 V3 的退款接口
  139 + // 2.2 创建返回结果
  140 + PayRefundRespDTO refund = new PayRefundRespDTO()
  141 + .setOutRefundNo(reqDTO.getOutRefundNo())
  142 + .setRawData(response);
  143 + if (Objects.equals("SUCCESS", response.getResultCode())) {
  144 + refund.setStatus(PayRefundStatusRespEnum.WAITING.getStatus());
  145 + refund.setChannelRefundNo(response.getRefundId());
  146 + } else {
  147 + refund.setStatus(PayRefundStatusRespEnum.FAILURE.getStatus());
  148 + // TODO 芋艿;异常的处理;
  149 + }
  150 + return refund;
  151 + }
  152 +
  153 + private PayRefundRespDTO doUnifiedRefundV3(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
  154 + return null;
  155 + }
105 156  
106 157 @Override
107 158 public Object parseNotify(Map<String, String> params, String body) {
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxAppPayClient.java
... ... @@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
2 2  
3 3 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
4 4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
5   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
6   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
7 5 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
8 6 import com.github.binarywang.wxpay.constant.WxPayConstants;
9 7 import com.github.binarywang.wxpay.exception.WxPayException;
... ... @@ -21,11 +19,6 @@ public class WxAppPayClient extends AbstractWxPayClient {
21 19 }
22 20  
23 21 @Override
24   - protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
25   - return null;
26   - }
27   -
28   - @Override
29 22 protected PayOrderUnifiedRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
30 23 return null;
31 24 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClient.java
... ... @@ -8,8 +8,6 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
8 8 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
9 9 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
10 10 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
11   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
12   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
13 11 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
14 12 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
15 13 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
... ... @@ -104,11 +102,6 @@ public class WxBarPayClient extends AbstractWxPayClient {
104 102 return doUnifiedOrderV2(reqDTO);
105 103 }
106 104  
107   - @Override
108   - protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
109   - return null;
110   - }
111   -
112 105 // ========== 各种工具方法 ==========
113 106  
114 107 static String getAuthCode(PayOrderUnifiedReqDTO reqDTO) {
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxH5PayClient.java
... ... @@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
2 2  
3 3 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
4 4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
5   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
6   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
7 5 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
8 6 import com.github.binarywang.wxpay.constant.WxPayConstants;
9 7 import com.github.binarywang.wxpay.exception.WxPayException;
... ... @@ -21,11 +19,6 @@ public class WxH5PayClient extends AbstractWxPayClient {
21 19 }
22 20  
23 21 @Override
24   - protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
25   - return null;
26   - }
27   -
28   - @Override
29 22 protected PayOrderUnifiedRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
30 23 return null;
31 24 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClient.java
... ... @@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
2 2  
3 3 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
4 4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
5   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
6   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
7 5 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
8 6 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
9 7 import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
... ... @@ -65,16 +63,11 @@ public class WxNativePayClient extends AbstractWxPayClient {
65 63 request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
66 64 request.setNotifyUrl(reqDTO.getNotifyUrl());
67 65 // 执行请求
68   - WxPayNativeOrderResult response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
  66 + String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
69 67  
70 68 // 转换结果
71 69 return new PayOrderUnifiedRespDTO(PayOrderDisplayModeEnum.QR_CODE.getMode(),
72   - response.getCodeUrl());
73   - }
74   -
75   - @Override
76   - protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
77   - return null;
  70 + response);
78 71 }
79 72  
80 73 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxPubPayClient.java
... ... @@ -5,8 +5,6 @@ import cn.hutool.core.util.StrUtil;
5 5 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
6 6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
7 7 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
8   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
9   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
10 8 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
11 9 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
12 10 import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
... ... @@ -83,12 +81,6 @@ public class WxPubPayClient extends AbstractWxPayClient {
83 81 JsonUtils.toJsonString(response));
84 82 }
85 83  
86   - @Override
87   - protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
88   - // TODO 需要实现
89   - throw new UnsupportedOperationException();
90   - }
91   -
92 84 // ========== 各种工具方法 ==========
93 85  
94 86 static String getOpenid(PayOrderUnifiedReqDTO reqDTO) {
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxBarPayClientIntegrationTest.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
  4 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  5 +import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
  6 +import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
  7 +import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
  8 +import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
  9 +import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
  10 +import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
  11 +import com.github.binarywang.wxpay.config.WxPayConfig;
  12 +import com.github.binarywang.wxpay.constant.WxPayConstants;
  13 +import com.github.binarywang.wxpay.exception.WxPayException;
  14 +import com.github.binarywang.wxpay.service.WxPayService;
  15 +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
  16 +import org.junit.jupiter.api.Disabled;
  17 +import org.junit.jupiter.api.Test;
  18 +
  19 +import java.time.Duration;
  20 +
  21 +import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.AbstractWxPayClient.formatDateV2;
  22 +
  23 +/**
  24 + * {@link WxBarPayClient} 的集成测试,用于快速调试微信条码支付
  25 + *
  26 + * @author 芋道源码
  27 + */
  28 +@Disabled
  29 +public class WxBarPayClientIntegrationTest {
  30 +
  31 + @Test
  32 + public void testPayV2() throws WxPayException {
  33 + // 创建 config 配置
  34 + WxPayConfig config = buildWxPayConfigV2();
  35 + // 创建 WxPayService 客户端
  36 + WxPayService client = new WxPayServiceImpl();
  37 + client.setConfig(config);
  38 +
  39 + // 执行发起支付
  40 + WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder()
  41 + .outTradeNo(String.valueOf(System.currentTimeMillis()))
  42 + .body("测试支付-body")
  43 + .detail("测试支付-detail")
  44 + .totalFee(1) // 单位分
  45 + .timeExpire(formatDateV2(LocalDateTimeUtils.addTime(Duration.ofMinutes(2))))
  46 + .spbillCreateIp("127.0.0.1")
  47 + .authCode("131276541518138032")
  48 + .build();
  49 + System.out.println("========= request ==========");
  50 + System.out.println(JsonUtils.toJsonPrettyString(request));
  51 + WxPayMicropayResult response = client.micropay(request);
  52 + System.out.println("========= response ==========");
  53 + System.out.println(JsonUtils.toJsonPrettyString(response));
  54 + }
  55 +
  56 + @Test
  57 + public void testRefundV2() throws WxPayException {
  58 + // 创建 config 配置
  59 + WxPayConfig config = buildWxPayConfigV2();
  60 + // 创建 WxPayService 客户端
  61 + WxPayService client = new WxPayServiceImpl();
  62 + client.setConfig(config);
  63 +
  64 + // 执行发起退款
  65 + WxPayRefundRequest request = new WxPayRefundRequest()
  66 + .setOutTradeNo("1689504162805")
  67 + .setOutRefundNo(String.valueOf(System.currentTimeMillis()))
  68 + .setRefundFee(1)
  69 + .setRefundDesc("就是想退了")
  70 + .setTotalFee(1);
  71 + System.out.println("========= request ==========");
  72 + System.out.println(JsonUtils.toJsonPrettyString(request));
  73 + WxPayRefundResult response = client.refund(request);
  74 + System.out.println("========= response ==========");
  75 + System.out.println(JsonUtils.toJsonPrettyString(response));
  76 + }
  77 +
  78 + @Test
  79 + public void testRefundV3() throws WxPayException {
  80 + // 创建 config 配置
  81 + WxPayConfig config = buildWxPayConfigV2();
  82 + // 创建 WxPayService 客户端
  83 + WxPayService client = new WxPayServiceImpl();
  84 + client.setConfig(config);
  85 +
  86 + // 执行发起退款
  87 + WxPayRefundV3Request request = new WxPayRefundV3Request()
  88 + .setOutTradeNo("1689506325635")
  89 + .setOutRefundNo(String.valueOf(System.currentTimeMillis()))
  90 + .setAmount(new WxPayRefundV3Request.Amount().setTotal(1).setRefund(1).setCurrency("CNY"))
  91 + .setReason("就是想退了");
  92 + System.out.println("========= request ==========");
  93 + System.out.println(JsonUtils.toJsonPrettyString(request));
  94 + WxPayRefundV3Result response = client.refundV3(request);
  95 + System.out.println("========= response ==========");
  96 + System.out.println(JsonUtils.toJsonPrettyString(response));
  97 + }
  98 +
  99 + private WxPayConfig buildWxPayConfigV2() {
  100 + WxPayConfig config = new WxPayConfig();
  101 + config.setAppId("wx62056c0d5e8db250");
  102 + config.setMchId("1545083881");
  103 + config.setMchKey("dS1ngeN63JLr3NRbvPH9AJy3MyUxZdim");
  104 + config.setSignType(WxPayConstants.SignType.MD5);
  105 + config.setKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.p12");
  106 + config.setPrivateCertPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.pem");
  107 + config.setPrivateKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_key.pem");
  108 + return config;
  109 + }
  110 +
  111 +}
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/test/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/WxNativePayClientIntegrationTest.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
  4 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  5 +import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
  6 +import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
  7 +import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
  8 +import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
  9 +import com.github.binarywang.wxpay.config.WxPayConfig;
  10 +import com.github.binarywang.wxpay.exception.WxPayException;
  11 +import com.github.binarywang.wxpay.service.WxPayService;
  12 +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
  13 +import org.junit.jupiter.api.Disabled;
  14 +import org.junit.jupiter.api.Test;
  15 +
  16 +import java.time.Duration;
  17 +
  18 +import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.AbstractWxPayClient.formatDateV3;
  19 +
  20 +/**
  21 + * {@link WxNativePayClient} 的集成测试,用于快速调试微信扫码支付
  22 + *
  23 + * @author 芋道源码
  24 + */
  25 +@Disabled
  26 +public class WxNativePayClientIntegrationTest {
  27 +
  28 + @Test
  29 + public void testPayV3() throws WxPayException {
  30 + // 创建 config 配置
  31 + WxPayConfig config = buildWxPayConfigV3();
  32 + // 创建 WxPayService 客户端
  33 + WxPayService client = new WxPayServiceImpl();
  34 + client.setConfig(config);
  35 +
  36 + // 执行发起支付
  37 + WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request()
  38 + .setOutTradeNo(String.valueOf(System.currentTimeMillis()))
  39 + .setDescription("测试支付-body")
  40 + .setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(1)) // 单位分
  41 + .setTimeExpire(formatDateV3(LocalDateTimeUtils.addTime(Duration.ofMinutes(2))))
  42 + .setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp("127.0.0.1"))
  43 + .setNotifyUrl("http://127.0.0.1:48080");
  44 + System.out.println("========= request ==========");
  45 + System.out.println(JsonUtils.toJsonPrettyString(request));
  46 + String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
  47 + System.out.println("========= response ==========");
  48 + System.out.println(JsonUtils.toJsonPrettyString(response));
  49 + }
  50 +
  51 + @Test
  52 + public void testRefundV3() throws WxPayException {
  53 + // 创建 config 配置
  54 + WxPayConfig config = buildWxPayConfigV3();
  55 + // 创建 WxPayService 客户端
  56 + WxPayService client = new WxPayServiceImpl();
  57 + client.setConfig(config);
  58 +
  59 + // 执行发起退款
  60 + WxPayRefundV3Request request = new WxPayRefundV3Request()
  61 + .setOutTradeNo("1689506153043")
  62 + .setOutRefundNo(String.valueOf(System.currentTimeMillis()))
  63 + .setAmount(new WxPayRefundV3Request.Amount().setTotal(1).setRefund(1).setCurrency("CNY"))
  64 + .setReason("就是想退了");
  65 + System.out.println("========= request ==========");
  66 + System.out.println(JsonUtils.toJsonPrettyString(request));
  67 + WxPayRefundV3Result response = client.refundV3(request);
  68 + System.out.println("========= response ==========");
  69 + System.out.println(JsonUtils.toJsonPrettyString(response));
  70 + }
  71 +
  72 + private WxPayConfig buildWxPayConfigV3() {
  73 + WxPayConfig config = new WxPayConfig();
  74 + config.setAppId("wx62056c0d5e8db250");
  75 + config.setMchId("1545083881");
  76 + config.setMchKey("dS1ngeN63JLr3NRbvPH9AJy3MyUxZdim");
  77 + config.setApiV3Key("459arNsYHl1mgkiO6H9ZH5KkhFXSxaA4");
  78 +// config.setCertSerialNo(serialNo);
  79 + config.setKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.p12");
  80 + config.setPrivateCertPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.pem");
  81 + config.setPrivateKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_key.pem");
  82 + return config;
  83 + }
  84 +
  85 +}
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceImpl.java
... ... @@ -129,8 +129,9 @@ public class PayRefundServiceImpl implements PayRefundService {
129 129 refundMapper.insert(refund);
130 130 // 2.2 向渠道发起退款申请
131 131 PayOrderExtensionDO orderExtension = orderExtensionService.getOrderExtension(order.getSuccessExtensionId());
132   - PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO();
133   - unifiedReqDTO.setPrice(reqDTO.getPrice())
  132 + PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO()
  133 + .setPayPrice(order.getPrice())
  134 + .setRefundPrice(reqDTO.getPrice())
134 135 .setOutTradeNo(orderExtension.getNo())
135 136 .setOutRefundNo(refund.getNo())
136 137 .setNotifyUrl(genChannelPayNotifyUrl(channel)) // TODO 芋艿:优化下 notifyUrl
... ...
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceTest.java
... ... @@ -87,7 +87,7 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
87 87 o.setSuccessExtensionId(1L);
88 88 o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
89 89 o.setRefundTimes(0);
90   - o.setRefundPrice(0L);
  90 + o.setRefundPrice(0);
91 91 o.setChannelUserId("1008611");
92 92 o.setChannelOrderNo(channelOrderId);
93 93 o.setUpdateTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15));
... ... @@ -155,7 +155,7 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
155 155 o.setSuccessExtensionId(1L);
156 156 o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
157 157 o.setRefundTimes(0);
158   - o.setRefundPrice(0L);
  158 + o.setRefundPrice(0);
159 159 o.setChannelUserId("1008611");
160 160 o.setChannelOrderNo(channelOrderId);
161 161 o.setUpdateTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15));
... ...
yudao-module-pay/yudao-module-pay-biz/src/test/java/cn/iocoder/yudao/module/pay/service/refund/PayRefundServiceTest.java
... ... @@ -68,7 +68,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
68 68 o.setNotifyUrl("https://www.cancanzi.com");
69 69 o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
70 70 o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
71   - o.setType(PayOrderRefundStatusEnum.PART.getStatus());
72 71 o.setPayPrice(100);
73 72 o.setRefundPrice(500);
74 73 o.setReason("就是想退款了,你有意见吗");
... ... @@ -93,8 +92,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
93 92 cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
94 93 // 测试 status 不匹配
95 94 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus())));
96   - // 测试 type 不匹配
97   - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayOrderRefundStatusEnum.ALL.getStatus())));
98 95 // 测试 createTime 不匹配
99 96 refundMapper.insert(cloneIgnoreId(dbRefund, o ->
100 97 o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));
... ... @@ -105,7 +102,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
105 102 reqVO.setMerchantRefundNo("MRF0000001");
106 103 reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
107 104 reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
108   - reqVO.setType(PayOrderRefundStatusEnum.PART.getStatus());
109 105 reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)}));
110 106  
111 107 // 调用
... ... @@ -130,7 +126,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
130 126 o.setNotifyUrl("https://www.cancanzi.com");
131 127 o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
132 128 o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
133   - o.setType(PayOrderRefundStatusEnum.PART.getStatus());
134 129 o.setPayPrice(100);
135 130 o.setRefundPrice(500);
136 131 o.setReason("就是想退款了,你有意见吗");
... ... @@ -155,8 +150,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
155 150 cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
156 151 // 测试 status 不匹配
157 152 refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus())));
158   - // 测试 type 不匹配
159   - refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayOrderRefundStatusEnum.ALL.getStatus())));
160 153 // 测试 createTime 不匹配
161 154 refundMapper.insert(cloneIgnoreId(dbRefund, o ->
162 155 o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));
... ...