mall + pay:

1. 微信支付配置,补全 apiclient_cert.p12 证书
This commit is contained in:
YunaiV
2023-07-17 07:56:33 +08:00
parent 7caf8e900f
commit 66ed61c641
6 changed files with 121 additions and 60 deletions

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.weixin;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.date.TemporalAccessorUtil;
import cn.hutool.core.lang.Assert;
@ -34,6 +35,7 @@ import static cn.hutool.core.date.DatePattern.UTC_WITH_XXX_OFFSET_PATTERN;
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;
import static cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig.API_VERSION_V2;
/**
* 微信支付抽象类,实现微信统一的接口、以及部分实现(退款)
@ -59,12 +61,17 @@ 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());
}
if (StrUtil.isNotEmpty(config.getPrivateKeyContent())) {
// weixin-pay-java 存在 BUG无法直接设置内容所以创建临时文件来解决
payConfig.setPrivateKeyPath(FileUtils.createTempFile(config.getPrivateKeyContent()).getPath());
}
if (StrUtil.isNotEmpty(config.getPrivateCertContent())) {
// weixin-pay-java 存在 BUG无法直接设置内容所以创建临时文件来解决
payConfig.setPrivateCertPath(FileUtils.createTempFile(config.getPrivateCertContent()).getPath());
}
@ -77,7 +84,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
protected PayOrderUnifiedRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Exception {
try {
switch (config.getApiVersion()) {
case WxPayClientConfig.API_VERSION_V2:
case API_VERSION_V2:
return doUnifiedOrderV2(reqDTO);
case WxPayClientConfig.API_VERSION_V3:
return doUnifiedOrderV3(reqDTO);
@ -112,7 +119,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) throws Throwable {
try {
switch (config.getApiVersion()) {
case WxPayClientConfig.API_VERSION_V2:
case API_VERSION_V2:
return doUnifiedRefundV2(reqDTO);
case WxPayClientConfig.API_VERSION_V3:
return doUnifiedRefundV3(reqDTO);
@ -160,7 +167,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient<WxPayClientC
try {
// 微信支付 v2 回调结果处理
switch (config.getApiVersion()) {
case WxPayClientConfig.API_VERSION_V2:
case API_VERSION_V2:
return parseOrderNotifyV2(body);
case WxPayClientConfig.API_VERSION_V3:
return parseOrderNotifyV3(body);

View File

@ -37,16 +37,17 @@ public class WxPayClientConfig implements PayClientConfig {
*
* 只有公众号或小程序需要该字段
*/
@NotBlank(message = "APPID 不能为空", groups = {V2.class, V3.class})
private String appId;
/**
* 商户号
*/
@NotBlank(message = "商户号 不能为空", groups = {V2.class, V3.class})
@NotBlank(message = "商户号不能为空", groups = {V2.class, V3.class})
private String mchId;
/**
* API 版本
*/
@NotBlank(message = "API 版本 不能为空", groups = {V2.class, V3.class})
@NotBlank(message = "API 版本不能为空", groups = {V2.class, V3.class})
private String apiVersion;
// ========== V2 版本的参数 ==========
@ -54,36 +55,31 @@ public class WxPayClientConfig implements PayClientConfig {
/**
* 商户密钥
*/
@NotBlank(message = "商户密钥 不能为空", groups = V2.class)
@NotBlank(message = "商户密钥不能为空", groups = V2.class)
private String mchKey;
/**
* apiclient_cert.p12 证书文件的绝对路径或者以 classpath: 开头的类路径.
* 对应的字符串
* apiclient_cert.p12 证书文件的对应字符串【base64 格式】
*
* 注意,可通过 {@link #main(String[])} 读取
* 为什么采用 base64 格式?因为 p12 读取后是二进制,需要转换成 base64 格式才好传输和存储
*/
/// private String keyContent;
@NotBlank(message = "apiclient_cert.p12 不能为空", groups = V2.class)
private String keyContent;
// ========== V3 版本的参数 ==========
/**
* apiclient_key.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
* 对应的字符串
* 注意,可通过 {@link #main(String[])} 读取
* apiclient_key.pem 证书文件的对应字符串
*/
@NotBlank(message = "apiclient_key 不能为空", groups = V3.class)
private String privateKeyContent;
/**
* apiclient_cert.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
* 对应的字符串
* <p>
* 注意,可通过 {@link #main(String[])} 读取
* apiclient_cert.pem 证书文件的对应的字符串
*/
@NotBlank(message = "apiclient_cert 不能为空", groups = V3.class)
private String privateCertContent;
/**
* apiV3 密钥值
*/
@NotBlank(message = "apiV3 密钥值 不能为空", groups = V3.class)
@NotBlank(message = "apiV3 密钥值不能为空", groups = V3.class)
private String apiV3Key;
/**

View File

@ -44,7 +44,7 @@ public class WxBarPayClientIntegrationTest {
.totalFee(1) // 单位分
.timeExpire(formatDateV2(LocalDateTimeUtils.addTime(Duration.ofMinutes(2))))
.spbillCreateIp("127.0.0.1")
.authCode("131276541518138032")
.authCode("134298744426278497")
.build();
System.out.println("========= request ==========");
System.out.println(JsonUtils.toJsonPrettyString(request));
@ -63,7 +63,7 @@ public class WxBarPayClientIntegrationTest {
// 执行发起退款
WxPayRefundRequest request = new WxPayRefundRequest()
.setOutTradeNo("1689504162805")
.setOutTradeNo("1689545667276")
.setOutRefundNo(String.valueOf(System.currentTimeMillis()))
.setRefundFee(1)
.setRefundDesc("就是想退了")
@ -103,8 +103,6 @@ public class WxBarPayClientIntegrationTest {
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

@ -58,7 +58,7 @@ public class WxNativePayClientIntegrationTest {
// 执行发起退款
WxPayRefundV3Request request = new WxPayRefundV3Request()
.setOutTradeNo("1689506153043")
.setOutTradeNo("1689545729695")
.setOutRefundNo(String.valueOf(System.currentTimeMillis()))
.setAmount(new WxPayRefundV3Request.Amount().setTotal(1).setRefund(1).setCurrency("CNY"))
.setReason("就是想退了");
@ -73,10 +73,8 @@ public class WxNativePayClientIntegrationTest {
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;