mall + pay:

1. 增加微信 bar 和 native 的集成测试,方便调试配置
This commit is contained in:
YunaiV 2023-07-16 19:24:29 +08:00
parent ecdc39612f
commit 7caf8e900f
13 changed files with 265 additions and 51 deletions

View File

@ -45,12 +45,20 @@ public class PayRefundUnifiedReqDTO {
@NotEmpty(message = "退款原因不能为空") @NotEmpty(message = "退款原因不能为空")
private String reason; private String reason;
/**
* 支付金额单位
*
* 目前微信支付在退款的时候必须传递该字段
*/
@NotNull(message = "支付金额不能为空")
@DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
private Integer payPrice;
/** /**
* 退款金额单位 * 退款金额单位
*/ */
@NotNull(message = "退款金额不能为空") @NotNull(message = "退款金额不能为空")
@DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零") @DecimalMin(value = "0", inclusive = false, message = "支付金额必须大于零")
private Integer price; private Integer refundPrice;
/** /**
* 退款结果的 notify 回调地址 * 退款结果的 notify 回调地址

View File

@ -67,7 +67,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
AlipayTradeRefundModel model = new AlipayTradeRefundModel(); AlipayTradeRefundModel model = new AlipayTradeRefundModel();
model.setOutTradeNo(reqDTO.getOutTradeNo()); model.setOutTradeNo(reqDTO.getOutTradeNo());
model.setOutRequestNo(reqDTO.getOutRefundNo()); model.setOutRequestNo(reqDTO.getOutRefundNo());
model.setRefundAmount(formatAmount(reqDTO.getPrice())); model.setRefundAmount(formatAmount(reqDTO.getRefundPrice()));
model.setRefundReason(reqDTO.getReason()); model.setRefundReason(reqDTO.getReason());
// 1.2 构建 AlipayTradePayRequest 请求 // 1.2 构建 AlipayTradePayRequest 请求
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
@ -75,6 +75,7 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient<AlipayPa
try { try {
// 2.1 执行请求 // 2.1 执行请求
AlipayTradeRefundResponse response = client.execute(request); AlipayTradeRefundResponse response = client.execute(request);
// 2.2 创建返回结果
PayRefundRespDTO refund = new PayRefundRespDTO() PayRefundRespDTO refund = new PayRefundRespDTO()
.setOutRefundNo(reqDTO.getOutRefundNo()) .setOutRefundNo(reqDTO.getOutRefundNo())
.setRawData(response); .setRawData(response);

View File

@ -9,10 +9,15 @@ import cn.iocoder.yudao.framework.common.util.io.FileUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
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.client.impl.AbstractPayClient;
import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants; import cn.iocoder.yudao.framework.pay.core.enums.PayFrameworkErrorCodeConstants;
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.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyV3Result;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.service.WxPayService;
@ -80,6 +85,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion())); throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
} }
} catch (WxPayException e) { } catch (WxPayException e) {
// todo 芋艿异常的处理
throw buildUnifiedOrderException(reqDTO, e); throw buildUnifiedOrderException(reqDTO, e);
} }
} }
@ -102,6 +108,51 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
protected abstract PayOrderUnifiedRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO) protected abstract PayOrderUnifiedRespDTO doUnifiedOrderV3(PayOrderUnifiedReqDTO reqDTO)
throws WxPayException; throws WxPayException;
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
try {
switch (config.getApiVersion()) {
case WxPayClientConfig.API_VERSION_V2:
return doUnifiedRefundV2(reqDTO);
case WxPayClientConfig.API_VERSION_V3:
return doUnifiedRefundV3(reqDTO);
default:
throw new IllegalArgumentException(String.format("未知的 API 版本(%s)", config.getApiVersion()));
}
} catch (WxPayException e) {
// todo 芋艿异常的处理
throw buildUnifiedOrderException(null, e);
}
}
private PayRefundRespDTO doUnifiedRefundV2(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
// 1. 构建 WxPayRefundRequest 请求
WxPayRefundRequest request = new WxPayRefundRequest()
.setOutTradeNo(reqDTO.getOutTradeNo())
.setOutRefundNo(reqDTO.getOutRefundNo())
.setRefundFee(reqDTO.getRefundPrice())
.setRefundDesc(reqDTO.getReason())
.setTotalFee(reqDTO.getPayPrice())
.setNotifyUrl(reqDTO.getNotifyUrl());
// 2.1 执行请求
WxPayRefundResult response = client.refundV2(request); // TODO 芋艿可以分成 V2 V3 的退款接口
// 2.2 创建返回结果
PayRefundRespDTO refund = new PayRefundRespDTO()
.setOutRefundNo(reqDTO.getOutRefundNo())
.setRawData(response);
if (Objects.equals("SUCCESS", response.getResultCode())) {
refund.setStatus(PayRefundStatusRespEnum.WAITING.getStatus());
refund.setChannelRefundNo(response.getRefundId());
} else {
refund.setStatus(PayRefundStatusRespEnum.FAILURE.getStatus());
// TODO 芋艿异常的处理
}
return refund;
}
private PayRefundRespDTO doUnifiedRefundV3(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
return null;
}
@Override @Override
public Object parseNotify(Map<String, String> params, String body) { public Object parseNotify(Map<String, String> params, String body) {

View File

@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
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.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import com.github.binarywang.wxpay.constant.WxPayConstants; import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.exception.WxPayException;
@ -20,11 +18,6 @@ public class WxAppPayClient extends AbstractWxPayClient {
super.doInit(WxPayConstants.TradeType.APP); super.doInit(WxPayConstants.TradeType.APP);
} }
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
return null;
}
@Override @Override
protected PayOrderUnifiedRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { protected PayOrderUnifiedRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
return null; return null;

View File

@ -8,8 +8,6 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
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.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
@ -104,11 +102,6 @@ public class WxBarPayClient extends AbstractWxPayClient {
return doUnifiedOrderV2(reqDTO); return doUnifiedOrderV2(reqDTO);
} }
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
return null;
}
// ========== 各种工具方法 ========== // ========== 各种工具方法 ==========
static String getAuthCode(PayOrderUnifiedReqDTO reqDTO) { static String getAuthCode(PayOrderUnifiedReqDTO reqDTO) {

View File

@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
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.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import com.github.binarywang.wxpay.constant.WxPayConstants; import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.exception.WxPayException;
@ -20,11 +18,6 @@ public class WxH5PayClient extends AbstractWxPayClient {
super.doInit(WxPayConstants.TradeType.MWEB); super.doInit(WxPayConstants.TradeType.MWEB);
} }
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
return null;
}
@Override @Override
protected PayOrderUnifiedRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException { protected PayOrderUnifiedRespDTO doUnifiedOrderV2(PayOrderUnifiedReqDTO reqDTO) throws WxPayException {
return null; return null;

View File

@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
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.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult; import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
@ -65,16 +63,11 @@ public class WxNativePayClient extends AbstractWxPayClient {
request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp())); request.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp(reqDTO.getUserIp()));
request.setNotifyUrl(reqDTO.getNotifyUrl()); request.setNotifyUrl(reqDTO.getNotifyUrl());
// 执行请求 // 执行请求
WxPayNativeOrderResult response = client.createOrderV3(TradeTypeEnum.NATIVE, request); String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
// 转换结果 // 转换结果
return new PayOrderUnifiedRespDTO(PayOrderDisplayModeEnum.QR_CODE.getMode(), return new PayOrderUnifiedRespDTO(PayOrderDisplayModeEnum.QR_CODE.getMode(),
response.getCodeUrl()); response);
}
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
return null;
} }
} }

View File

@ -5,8 +5,6 @@ import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO;
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.enums.channel.PayChannelEnum; import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum; import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
@ -83,12 +81,6 @@ public class WxPubPayClient extends AbstractWxPayClient {
JsonUtils.toJsonString(response)); JsonUtils.toJsonString(response));
} }
@Override
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
// TODO 需要实现
throw new UnsupportedOperationException();
}
// ========== 各种工具方法 ========== // ========== 各种工具方法 ==========
static String getOpenid(PayOrderUnifiedReqDTO reqDTO) { static String getOpenid(PayOrderUnifiedReqDTO reqDTO) {

View File

@ -0,0 +1,111 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.AbstractWxPayClient.formatDateV2;
/**
* {@link WxBarPayClient} 的集成测试用于快速调试微信条码支付
*
* @author 芋道源码
*/
@Disabled
public class WxBarPayClientIntegrationTest {
@Test
public void testPayV2() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV2();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起支付
WxPayMicropayRequest request = WxPayMicropayRequest.newBuilder()
.outTradeNo(String.valueOf(System.currentTimeMillis()))
.body("测试支付-body")
.detail("测试支付-detail")
.totalFee(1) // 单位分
.timeExpire(formatDateV2(LocalDateTimeUtils.addTime(Duration.ofMinutes(2))))
.spbillCreateIp("127.0.0.1")
.authCode("131276541518138032")
.build();
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
WxPayMicropayResult response = client.micropay(request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
@Test
public void testRefundV2() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV2();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起退款
WxPayRefundRequest request = new WxPayRefundRequest()
.setOutTradeNo("1689504162805")
.setOutRefundNo(String.valueOf(System.currentTimeMillis()))
.setRefundFee(1)
.setRefundDesc("就是想退了")
.setTotalFee(1);
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
WxPayRefundResult response = client.refund(request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
@Test
public void testRefundV3() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV2();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起退款
WxPayRefundV3Request request = new WxPayRefundV3Request()
.setOutTradeNo("1689506325635")
.setOutRefundNo(String.valueOf(System.currentTimeMillis()))
.setAmount(new WxPayRefundV3Request.Amount().setTotal(1).setRefund(1).setCurrency("CNY"))
.setReason("就是想退了");
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
WxPayRefundV3Result response = client.refundV3(request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
private WxPayConfig buildWxPayConfigV2() {
WxPayConfig config = new WxPayConfig();
config.setAppId("wx62056c0d5e8db250");
config.setMchId("1545083881");
config.setMchKey("dS1ngeN63JLr3NRbvPH9AJy3MyUxZdim");
config.setSignType(WxPayConstants.SignType.MD5);
config.setKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.p12");
config.setPrivateCertPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.pem");
config.setPrivateKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_key.pem");
return config;
}
}

View File

@ -0,0 +1,85 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderV3Request;
import com.github.binarywang.wxpay.bean.result.WxPayRefundV3Result;
import com.github.binarywang.wxpay.bean.result.enums.TradeTypeEnum;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.time.Duration;
import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.AbstractWxPayClient.formatDateV3;
/**
* {@link WxNativePayClient} 的集成测试用于快速调试微信扫码支付
*
* @author 芋道源码
*/
@Disabled
public class WxNativePayClientIntegrationTest {
@Test
public void testPayV3() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV3();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起支付
WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request()
.setOutTradeNo(String.valueOf(System.currentTimeMillis()))
.setDescription("测试支付-body")
.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(1)) // 单位分
.setTimeExpire(formatDateV3(LocalDateTimeUtils.addTime(Duration.ofMinutes(2))))
.setSceneInfo(new WxPayUnifiedOrderV3Request.SceneInfo().setPayerClientIp("127.0.0.1"))
.setNotifyUrl("http://127.0.0.1:48080");
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
String response = client.createOrderV3(TradeTypeEnum.NATIVE, request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
@Test
public void testRefundV3() throws WxPayException {
// 创建 config 配置
WxPayConfig config = buildWxPayConfigV3();
// 创建 WxPayService 客户端
WxPayService client = new WxPayServiceImpl();
client.setConfig(config);
// 执行发起退款
WxPayRefundV3Request request = new WxPayRefundV3Request()
.setOutTradeNo("1689506153043")
.setOutRefundNo(String.valueOf(System.currentTimeMillis()))
.setAmount(new WxPayRefundV3Request.Amount().setTotal(1).setRefund(1).setCurrency("CNY"))
.setReason("就是想退了");
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
WxPayRefundV3Result response = client.refundV3(request);
System.out.println("========= response ==========");
System.out.println(JsonUtils.toJsonPrettyString(response));
}
private WxPayConfig buildWxPayConfigV3() {
WxPayConfig config = new WxPayConfig();
config.setAppId("wx62056c0d5e8db250");
config.setMchId("1545083881");
config.setMchKey("dS1ngeN63JLr3NRbvPH9AJy3MyUxZdim");
config.setApiV3Key("459arNsYHl1mgkiO6H9ZH5KkhFXSxaA4");
// config.setCertSerialNo(serialNo);
config.setKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.p12");
config.setPrivateCertPath("/Users/yunai/Downloads/wx_pay/apiclient_cert.pem");
config.setPrivateKeyPath("/Users/yunai/Downloads/wx_pay/apiclient_key.pem");
return config;
}
}

View File

@ -129,8 +129,9 @@ public class PayRefundServiceImpl implements PayRefundService {
refundMapper.insert(refund); refundMapper.insert(refund);
// 2.2 向渠道发起退款申请 // 2.2 向渠道发起退款申请
PayOrderExtensionDO orderExtension = orderExtensionService.getOrderExtension(order.getSuccessExtensionId()); PayOrderExtensionDO orderExtension = orderExtensionService.getOrderExtension(order.getSuccessExtensionId());
PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO(); PayRefundUnifiedReqDTO unifiedReqDTO = new PayRefundUnifiedReqDTO()
unifiedReqDTO.setPrice(reqDTO.getPrice()) .setPayPrice(order.getPrice())
.setRefundPrice(reqDTO.getPrice())
.setOutTradeNo(orderExtension.getNo()) .setOutTradeNo(orderExtension.getNo())
.setOutRefundNo(refund.getNo()) .setOutRefundNo(refund.getNo())
.setNotifyUrl(genChannelPayNotifyUrl(channel)) // TODO 芋艿优化下 notifyUrl .setNotifyUrl(genChannelPayNotifyUrl(channel)) // TODO 芋艿优化下 notifyUrl

View File

@ -87,7 +87,7 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
o.setSuccessExtensionId(1L); o.setSuccessExtensionId(1L);
o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus()); o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
o.setRefundTimes(0); o.setRefundTimes(0);
o.setRefundPrice(0L); o.setRefundPrice(0);
o.setChannelUserId("1008611"); o.setChannelUserId("1008611");
o.setChannelOrderNo(channelOrderId); o.setChannelOrderNo(channelOrderId);
o.setUpdateTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15)); o.setUpdateTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15));
@ -155,7 +155,7 @@ public class PayOrderServiceTest extends BaseDbUnitTest {
o.setSuccessExtensionId(1L); o.setSuccessExtensionId(1L);
o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus()); o.setRefundStatus(PayOrderRefundStatusEnum.NO.getStatus());
o.setRefundTimes(0); o.setRefundTimes(0);
o.setRefundPrice(0L); o.setRefundPrice(0);
o.setChannelUserId("1008611"); o.setChannelUserId("1008611");
o.setChannelOrderNo(channelOrderId); o.setChannelOrderNo(channelOrderId);
o.setUpdateTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15)); o.setUpdateTime(LocalDateTime.of(2018, 1, 1, 10, 10, 15));

View File

@ -68,7 +68,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
o.setNotifyUrl("https://www.cancanzi.com"); o.setNotifyUrl("https://www.cancanzi.com");
o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
o.setType(PayOrderRefundStatusEnum.PART.getStatus());
o.setPayPrice(100); o.setPayPrice(100);
o.setRefundPrice(500); o.setRefundPrice(500);
o.setReason("就是想退款了,你有意见吗"); o.setReason("就是想退款了,你有意见吗");
@ -93,8 +92,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
// 测试 status 不匹配 // 测试 status 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus()))); refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus())));
// 测试 type 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayOrderRefundStatusEnum.ALL.getStatus())));
// 测试 createTime 不匹配 // 测试 createTime 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> refundMapper.insert(cloneIgnoreId(dbRefund, o ->
o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10)))); o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));
@ -105,7 +102,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
reqVO.setMerchantRefundNo("MRF0000001"); reqVO.setMerchantRefundNo("MRF0000001");
reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); reqVO.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); reqVO.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
reqVO.setType(PayOrderRefundStatusEnum.PART.getStatus());
reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)})); reqVO.setCreateTime((new LocalDateTime[]{LocalDateTime.of(2021, 1, 1, 10, 10, 10), LocalDateTime.of(2021, 1, 1, 10, 10, 12)}));
// 调用 // 调用
@ -130,7 +126,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
o.setNotifyUrl("https://www.cancanzi.com"); o.setNotifyUrl("https://www.cancanzi.com");
o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus()); o.setNotifyStatus(PayOrderNotifyStatusEnum.SUCCESS.getStatus());
o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus()); o.setStatus(PayRefundStatusEnum.SUCCESS.getStatus());
o.setType(PayOrderRefundStatusEnum.PART.getStatus());
o.setPayPrice(100); o.setPayPrice(100);
o.setRefundPrice(500); o.setRefundPrice(500);
o.setReason("就是想退款了,你有意见吗"); o.setReason("就是想退款了,你有意见吗");
@ -155,8 +150,6 @@ public class PayRefundServiceTest extends BaseDbUnitTest {
cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus()))); cloneIgnoreId(dbRefund, o -> o.setNotifyStatus(PayOrderNotifyStatusEnum.FAILURE.getStatus())));
// 测试 status 不匹配 // 测试 status 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus()))); refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setStatus(PayRefundStatusEnum.FAILURE.getStatus())));
// 测试 type 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> o.setType(PayOrderRefundStatusEnum.ALL.getStatus())));
// 测试 createTime 不匹配 // 测试 createTime 不匹配
refundMapper.insert(cloneIgnoreId(dbRefund, o -> refundMapper.insert(cloneIgnoreId(dbRefund, o ->
o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10)))); o.setCreateTime(LocalDateTime.of(2022, 1, 1, 10, 10, 10))));