diff --git a/framework/pom.xml b/framework/pom.xml
index bfcd88a3..2b359058 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -468,6 +468,11 @@
runtime
osx-aarch_64
+
+ com.github.wechatpay-apiv3
+ wechatpay-java
+ 0.2.15
+
diff --git a/framework/src/main/java/cn/lili/common/utils/CurrencyUtil.java b/framework/src/main/java/cn/lili/common/utils/CurrencyUtil.java
index aa030d6e..1b731c61 100644
--- a/framework/src/main/java/cn/lili/common/utils/CurrencyUtil.java
+++ b/framework/src/main/java/cn/lili/common/utils/CurrencyUtil.java
@@ -125,13 +125,21 @@ public final class CurrencyUtil {
return (int) price;
}
+ public static Long getFenLong(Double money) {
+ BigDecimal bigDecimalValue = BigDecimal.valueOf(money);
+ // 乘以 100 并四舍五入到最接近的整数
+ BigDecimal fenValue = bigDecimalValue.multiply(BigDecimal.valueOf(100)).setScale(0, RoundingMode.HALF_UP);
+
+ return fenValue.longValue();
+ }
+
/**
* 金额转分
*
* @param money 金额
* @return double类型分
*/
- public static double reversalFen(Double money) {
+ public static double reversalFen(Integer money) {
return div(money, 100);
}
}
\ No newline at end of file
diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/PayKit.java b/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/PayKit.java
index 3b2d9d09..626a1b2f 100644
--- a/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/PayKit.java
+++ b/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/PayKit.java
@@ -327,6 +327,24 @@ public class PayKit {
return RsaKit.encryptByPrivateKey(signMessage, privateKey);
}
+ /**
+ * v3 接口创建签名
+ *
+ * @param signMessage 待签名的参数
+ * @param key key.pem 证书
+ * @return 生成 v3 签名
+ * @throws Exception 异常信息
+ */
+ public static String createPublicSign(String signMessage, String key) throws Exception {
+ if (StrUtil.isEmpty(signMessage)) {
+ return null;
+ }
+ //获取商户私钥
+ PrivateKey privateKey = PayKit.getPublicKey(key);
+ //生成签名
+ return RsaKit.encryptByPrivateKey(signMessage, privateKey);
+ }
+
/**
* v3 接口创建签名
*
@@ -392,6 +410,23 @@ public class PayKit {
return RsaKit.loadPrivateKey(privateKey);
}
+ /**
+ * 获取商户公钥
+ *
+ * @param key 商户私钥证书
+ * @return {@link PrivateKey} 商户私钥
+ * @throws Exception 异常信息
+ */
+ public static PrivateKey getPublicKey(String key) throws Exception {
+// String originalKey = FileUtil.readUtf8String(keyPath);
+ String privateKey = key
+ .replace("-----BEGIN PUBLIC KEY-----", "")
+ .replace("-----END PUBLIC KEY-----", "")
+ .replaceAll("\\s+", "");
+
+ return RsaKit.loadPrivateKey(privateKey);
+ }
+
/**
* 获取证书
*
diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/RsaKit.java b/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/RsaKit.java
index e045ea41..e9c10595 100644
--- a/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/RsaKit.java
+++ b/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/RsaKit.java
@@ -312,13 +312,18 @@ public class RsaKit {
*/
public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception {
try {
+
+
byte[] buffer = Base64.decode(privateKeyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
return keyFactory.generatePrivate(keySpec);
+
+
} catch (NoSuchAlgorithmException e) {
throw new Exception("无此算法");
} catch (InvalidKeySpecException e) {
+ e.printStackTrace();
throw new Exception("私钥非法");
} catch (NullPointerException e) {
throw new Exception("私钥数据为空");
diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/WxPayKit.java b/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/WxPayKit.java
index c9ec5e53..da918bad 100644
--- a/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/WxPayKit.java
+++ b/framework/src/main/java/cn/lili/modules/payment/kit/core/kit/WxPayKit.java
@@ -450,6 +450,7 @@ public class WxPayKit {
* @param mchId 商户Id
* @param serialNo 商户 API 证书序列号
* @param key key.pem 证书
+ * @param publicKey 公钥证书
* @param body 接口请求参数
* @param nonceStr 随机字符库
* @param timestamp 时间戳
@@ -458,11 +459,12 @@ public class WxPayKit {
* @throws Exception 异常信息
*/
public static String buildAuthorization(RequestMethodEnums method, String urlSuffix, String mchId,
- String serialNo, String key, String body, String nonceStr,
+ String serialNo, String key, String publicKey ,String body, String nonceStr,
long timestamp, String authType) throws Exception {
//构建签名参数
String buildSignMessage = PayKit.buildSignMessage(method, urlSuffix, timestamp, nonceStr, body);
- String signature = PayKit.createSign(buildSignMessage, key);
+ String publicKeySignature = PayKit.createPublicSign(buildSignMessage, publicKey);
+ String signature = PayKit.createSign(publicKeySignature, key);
//根据平台规则生成请求头 authorization
return PayKit.getAuthorization(mchId, serialNo, nonceStr, String.valueOf(timestamp), signature, authType);
}
@@ -492,27 +494,27 @@ public class WxPayKit {
return PayKit.getAuthorization(mchId, serialNo, nonceStr, String.valueOf(timestamp), signature, authType);
}
- /**
- * 构建 v3 接口所需的 Authorization
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlSuffix 可通过 WxApiType 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param keyPath key.pem 证书路径
- * @param body 接口请求参数
- * @return {@link String} 返回 v3 所需的 Authorization
- * @throws Exception 异常信息
- */
- public static String buildAuthorization(RequestMethodEnums method, String urlSuffix, String mchId,
- String serialNo, String keyPath, String body) throws Exception {
-
- long timestamp = System.currentTimeMillis() / 1000;
- String authType = "WECHATPAY2-SHA256-RSA2048";
- String nonceStr = IdUtil.fastSimpleUUID();
-
- return buildAuthorization(method, urlSuffix, mchId, serialNo, keyPath, body, nonceStr, timestamp, authType);
- }
+// /**
+// * 构建 v3 接口所需的 Authorization
+// *
+// * @param method {@link RequestMethodEnums} 请求方法
+// * @param urlSuffix 可通过 WxApiType 来获取,URL挂载参数需要自行拼接
+// * @param mchId 商户Id
+// * @param serialNo 商户 API 证书序列号
+// * @param keyPath key.pem 证书路径
+// * @param body 接口请求参数
+// * @return {@link String} 返回 v3 所需的 Authorization
+// * @throws Exception 异常信息
+// */
+// public static String buildAuthorization(RequestMethodEnums method, String urlSuffix, String mchId,
+// String serialNo, String keyPath, String body) throws Exception {
+//
+// long timestamp = System.currentTimeMillis() / 1000;
+// String authType = "WECHATPAY2-SHA256-RSA2048";
+// String nonceStr = IdUtil.fastSimpleUUID();
+//
+// return buildAuthorization(method, urlSuffix, mchId, serialNo, keyPath, body, nonceStr, timestamp, authType);
+// }
/**
* 构建 v3 接口所需的 Authorization
diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatApi.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatApi.java
index 240a658a..e2752820 100644
--- a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatApi.java
+++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatApi.java
@@ -1,859 +1,862 @@
-package cn.lili.modules.payment.kit.plugin.wechat;
-
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.ContentType;
-import cn.lili.modules.payment.kit.core.PaymentHttpResponse;
-import cn.lili.modules.payment.kit.core.enums.RequestMethodEnums;
-import cn.lili.modules.payment.kit.core.kit.HttpKit;
-import cn.lili.modules.payment.kit.core.kit.PayKit;
-import cn.lili.modules.payment.kit.core.kit.WxPayKit;
-import cn.lili.modules.payment.kit.plugin.wechat.enums.WechatApiEnum;
-import cn.lili.modules.payment.kit.plugin.wechat.enums.WechatDomain;
-
-import java.io.File;
-import java.io.InputStream;
-import java.security.PrivateKey;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 微信支付相关接口
- *
- * @author Chopper
- * @since 2021/1/26 15:25
- */
-
-public class WechatApi {
-
- private WechatApi() {
- }
-
- /**
- * 获取接口请求的 URL
- *
- * @param wechatApiEnum {@link WechatApiEnum} 支付 API 接口枚举
- * @return {@link String} 返回完整的接口请求URL
- */
- public static String getReqUrl(WechatApiEnum wechatApiEnum) {
- return getReqUrl(wechatApiEnum, null, false);
- }
-
- /**
- * 获取接口请求的 URL
- *
- * @param wechatApiEnum {@link WechatApiEnum} 支付 API 接口枚举
- * @param isSandBox 是否是沙箱环境
- * @return {@link String} 返回完整的接口请求URL
- */
- public static String getReqUrl(WechatApiEnum wechatApiEnum, boolean isSandBox) {
- return getReqUrl(wechatApiEnum, null, isSandBox);
- }
-
- /**
- * 获取接口请求的 URL
- *
- * @param wechatApiEnum {@link WechatApiEnum} 支付 API 接口枚举
- * @param wechatDomain {@link WechatDomain} 支付 API 接口域名枚举
- * @param isSandBox 是否是沙箱环境
- * @return {@link String} 返回完整的接口请求URL
- */
- public static String getReqUrl(WechatApiEnum wechatApiEnum, WechatDomain wechatDomain, boolean isSandBox) {
- if (wechatDomain == null) {
- wechatDomain = WechatDomain.CHINA;
- }
- return wechatDomain.getType()
- .concat(isSandBox ? WechatApiEnum.SAND_BOX_NEW.getUrl() : "")
- .concat(wechatApiEnum.getUrl());
- }
-
- /**
- * 发起请求
- *
- * @param apiUrl 接口 URL
- * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
- * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
- * @param params 接口请求参数
- * @return {@link String} 请求返回的结果
- */
- public static String execution(String apiUrl, Map params) {
- return doPost(apiUrl, params);
- }
-
- /**
- * 发起请求
- *
- * @param apiUrl 接口 URL
- * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
- * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
- * @param params 接口请求参数
- * @return {@link String} 请求返回的结果
- */
- public static String executionByGet(String apiUrl, Map params) {
- return doGet(apiUrl, params);
- }
-
- /**
- * 发起请求
- *
- * @param apiUrl 接口 URL
- * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
- * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
- * @param params 接口请求参数
- * @param certPath 证书文件路径
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String execution(String apiUrl, Map params, String certPath, String certPass) {
- return doPostSsl(apiUrl, params, certPath, certPass);
- }
-
- /**
- * 发起请求
- *
- * @param apiUrl 接口 URL
- * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
- * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
- * @param params 接口请求参数
- * @param certPath 证书文件路径
- * @return {@link String} 请求返回的结果
- */
- public static String execution(String apiUrl, Map params, String certPath) {
- return doPostSsl(apiUrl, params, certPath);
- }
-
- /**
- * 发起请求
- *
- * @param apiUrl 接口 URL
- * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
- * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
- * @param params 接口请求参数
- * @param certFile 证书文件输入流
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String execution(String apiUrl, Map params, InputStream certFile, String certPass) {
- return doPostSsl(apiUrl, params, certFile, certPass);
- }
-
- /**
- * 发起请求
- *
- * @param apiUrl 接口 URL
- * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
- * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
- * @param params 接口请求参数
- * @param certFile 证书文件输入流
- * @return {@link String} 请求返回的结果
- */
- public static String execution(String apiUrl, Map params, InputStream certFile) {
- return doPostSsl(apiUrl, params, certFile);
- }
-
- public static String execution(String apiUrl, Map params,
- String certPath, String certPass, String filePath) {
- return doUploadSsl(apiUrl, params, certPath, certPass, filePath);
- }
-
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号,接口中包含敏感信息时必传
- * @param keyPath apiclient_key.pem 证书
- * @param body 接口请求参数
- * @param nonceStr 随机字符库
- * @param timestamp 时间戳
- * @param authType 认证类型
- * @param file 文件
- * @return {@link PaymentHttpResponse} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix,
- String mchId, String serialNo, String platSerialNo, String key,
- String body, String nonceStr, long timestamp, String authType,
- File file) throws Exception {
- //构建 Authorization
- String authorization = WxPayKit.buildAuthorization(method, urlSuffix, mchId, serialNo,
- key, body, nonceStr, timestamp, authType);
-
- if (StrUtil.isEmpty(platSerialNo)) {
- platSerialNo = serialNo;
- }
- if (method == RequestMethodEnums.GET) {
- return get(urlPrefix.concat(urlSuffix), authorization, platSerialNo, null);
- } else if (method == RequestMethodEnums.POST) {
- return post(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
- } else if (method == RequestMethodEnums.DELETE) {
- return delete(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
- } else if (method == RequestMethodEnums.UPLOAD) {
- return upload(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body, file);
- } else if (method == RequestMethodEnums.PUT) {
- return put(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
- }
- return null;
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号,接口中包含敏感信息时必传
- * @param privateKey 商户私钥
- * @param body 接口请求参数
- * @param nonceStr 随机字符库
- * @param timestamp 时间戳
- * @param authType 认证类型
- * @param file 文件
- * @return {@link PaymentHttpResponse} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix,
- String mchId, String serialNo, String platSerialNo, PrivateKey privateKey,
- String body, String nonceStr, long timestamp, String authType,
- File file) throws Exception {
- //构建 Authorization
- String authorization = WxPayKit.buildAuthorization(method, urlSuffix, mchId, serialNo,
- privateKey, body, nonceStr, timestamp, authType);
-
- if (StrUtil.isEmpty(platSerialNo)) {
- platSerialNo = serialNo;
- }
-
- if (method == RequestMethodEnums.GET) {
- return get(urlPrefix.concat(urlSuffix), authorization, platSerialNo, null);
- } else if (method == RequestMethodEnums.POST) {
- return post(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
- } else if (method == RequestMethodEnums.DELETE) {
- return delete(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
- } else if (method == RequestMethodEnums.UPLOAD) {
- return upload(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body, file);
- } else if (method == RequestMethodEnums.PUT) {
- return put(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
- }
- return null;
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号
- * @param key apiclient_key.pem 证书
- * @param body 接口请求参数
- * @return {@link PaymentHttpResponse} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix, String mchId,
- String serialNo, String platSerialNo, String key, String body) throws Exception {
- long timestamp = System.currentTimeMillis() / 1000;
- String authType = "WECHATPAY2-SHA256-RSA2048";
- String nonceStr = WxPayKit.generateStr();
- return v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, key, body, nonceStr, timestamp, authType, null);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号
- * @param privateKey 商户私钥
- * @param body 接口请求参数
- * @return {@link PaymentHttpResponse} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix, String mchId,
- String serialNo, String platSerialNo, PrivateKey privateKey, String body) throws Exception {
- long timestamp = System.currentTimeMillis() / 1000;
- String authType = "WECHATPAY2-SHA256-RSA2048";
- String nonceStr = WxPayKit.generateStr();
- return v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, privateKey, body, nonceStr, timestamp, authType, null);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号
- * @param keyPath apiclient_key.pem 证书路径
- * @param params Get 接口请求参数
- * @return {@link PaymentHttpResponse} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix,
- String mchId, String serialNo, String platSerialNo, String keyPath,
- Map params) throws Exception {
- long timestamp = System.currentTimeMillis() / 1000;
- String authType = "WECHATPAY2-SHA256-RSA2048";
- String nonceStr = WxPayKit.generateStr();
- if (null != params && !params.keySet().isEmpty()) {
- urlSuffix = urlSuffix.concat("?").concat(PayKit.createLinkString(params, true));
- }
- return v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, "", nonceStr, timestamp, authType, null);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号
- * @param privateKey 商户私钥
- * @param params Get 接口请求参数
- * @return {@link PaymentHttpResponse} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix,
- String mchId, String serialNo, String platSerialNo, PrivateKey privateKey,
- Map params) throws Exception {
- long timestamp = System.currentTimeMillis() / 1000;
- String authType = "WECHATPAY2-SHA256-RSA2048";
- String nonceStr = WxPayKit.generateStr();
- if (null != params && !params.keySet().isEmpty()) {
- urlSuffix = urlSuffix.concat("?").concat(PayKit.createLinkString(params, true));
- }
- return v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, privateKey, "", nonceStr, timestamp, authType, null);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号
- * @param keyPath apiclient_key.pem 证书路径
- * @param body 接口请求参数
- * @param file 文件
- * @return {@link PaymentHttpResponse} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- public static PaymentHttpResponse v3(String urlPrefix, String urlSuffix, String mchId, String serialNo, String platSerialNo, String keyPath, String body, File file) throws Exception {
- long timestamp = System.currentTimeMillis() / 1000;
- String authType = "WECHATPAY2-SHA256-RSA2048";
- String nonceStr = WxPayKit.generateStr();
- return v3(RequestMethodEnums.UPLOAD, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, body, nonceStr, timestamp, authType, file);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号
- * @param privateKey 商户私钥
- * @param body 接口请求参数
- * @param file 文件
- * @return {@link PaymentHttpResponse} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- public static PaymentHttpResponse v3(String urlPrefix, String urlSuffix, String mchId, String serialNo,
- String platSerialNo, PrivateKey privateKey, String body, File file) throws Exception {
- long timestamp = System.currentTimeMillis() / 1000;
- String authType = "WECHATPAY2-SHA256-RSA2048";
- String nonceStr = WxPayKit.generateStr();
- return v3(RequestMethodEnums.UPLOAD, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, privateKey, body, nonceStr, timestamp, authType, file);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号,接口中包含敏感信息时必传
- * @param keyPath apiclient_key.pem 证书路径
- * @param body 接口请求参数
- * @param nonceStr 随机字符库
- * @param timestamp 时间戳
- * @param authType 认证类型
- * @param file 文件
- * @return {@link Map} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- @Deprecated
- public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix,
- String mchId, String serialNo, String platSerialNo, String keyPath,
- String body, String nonceStr, long timestamp, String authType,
- File file) throws Exception {
- PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, body, nonceStr, timestamp, authType, file);
- return buildResMap(response);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param keyPath apiclient_key.pem 证书路径
- * @param body 接口请求参数
- * @return {@link Map} 请求返回的结果
- */
- @Deprecated
- public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix, String mchId,
- String serialNo, String keyPath, String body) throws Exception {
- PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, null, keyPath, body);
- return buildResMap(response);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号
- * @param keyPath apiclient_key.pem 证书路径
- * @param body 接口请求参数
- * @return {@link Map} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- @Deprecated
- public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix, String mchId,
- String serialNo, String platSerialNo, String keyPath, String body) throws Exception {
- PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, body);
- return buildResMap(response);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号
- * @param keyPath apiclient_key.pem 证书路径
- * @param params Get 接口请求参数
- * @return {@link Map} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- @Deprecated
- public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix,
- String mchId, String serialNo, String platSerialNo, String keyPath,
- Map params) throws Exception {
- PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, params);
- return buildResMap(response);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param method {@link RequestMethodEnums} 请求方法
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param keyPath apiclient_key.pem 证书路径
- * @param params Get 接口请求参数
- * @return {@link Map} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- @Deprecated
- public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix,
- String mchId, String serialNo, String keyPath,
- Map params) throws Exception {
- PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, null, keyPath, params);
- return buildResMap(response);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param platSerialNo 平台序列号
- * @param keyPath apiclient_key.pem 证书路径
- * @param body 接口请求参数
- * @param file 文件
- * @return {@link Map} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- @Deprecated
- public static Map v3Upload(String urlPrefix, String urlSuffix, String mchId, String serialNo, String platSerialNo, String keyPath, String body, File file) throws Exception {
- PaymentHttpResponse response = v3(urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, body, file);
- return buildResMap(response);
- }
-
- /**
- * V3 接口统一执行入口
- *
- * @param urlPrefix 可通过 {@link WechatDomain}来获取
- * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
- * @param mchId 商户Id
- * @param serialNo 商户 API 证书序列号
- * @param keyPath apiclient_key.pem 证书路径
- * @param body 接口请求参数
- * @param file 文件
- * @return {@link Map} 请求返回的结果
- * @throws Exception 接口执行异常
- */
- @Deprecated
- public static Map v3Upload(String urlPrefix, String urlSuffix, String mchId, String serialNo, String keyPath, String body, File file) throws Exception {
- return v3Upload(urlPrefix, urlSuffix, mchId, serialNo, null, keyPath, body, file);
- }
-
- /**
- * 发放企业红包
- *
- * @param params 请求参数
- * @param certPath 证书文件路径
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String sendWorkWxRedPack(Map params, String certPath, String certPass) {
- return execution(getReqUrl(WechatApiEnum.SEND_WORK_WX_RED_PACK), params, certPath, certPass);
- }
-
- /**
- * 发放企业红包
- *
- * @param params 请求参数
- * @param certFile 证书文件的 InputStream
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String sendWorkWxRedPack(Map params, InputStream certFile, String certPass) {
- return execution(getReqUrl(WechatApiEnum.SEND_WORK_WX_RED_PACK), params, certFile, certPass);
- }
-
- /**
- * 查询向员工付款记录
- *
- * @param params 请求参数
- * @param certPath 证书文件路径
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String queryWorkWxRedPack(Map params, String certPath, String certPass) {
- return execution(getReqUrl(WechatApiEnum.QUERY_WORK_WX_RED_PACK), params, certPath, certPass);
- }
-
- /**
- * 查询向员工付款记录
- *
- * @param params 请求参数
- * @param certFile 证书文件的 InputStream
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String queryWorkWxRedPack(Map params, InputStream certFile, String certPass) {
- return execution(getReqUrl(WechatApiEnum.QUERY_WORK_WX_RED_PACK), params, certFile, certPass);
- }
-
- /**
- * 向员工付款
- *
- * @param params 请求参数
- * @param certPath 证书文件路径
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String trans2pocket(Map params, String certPath, String certPass) {
- return execution(getReqUrl(WechatApiEnum.PAY_WWS_TRANS_2_POCKET), params, certPath, certPass);
- }
-
- /**
- * 向员工付款
- *
- * @param params 请求参数
- * @param certFile 证书文件的 InputStream
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String trans2pocket(Map params, InputStream certFile, String certPass) {
- return execution(getReqUrl(WechatApiEnum.PAY_WWS_TRANS_2_POCKET), params, certFile, certPass);
- }
-
- /**
- * 查询向员工付款记录
- *
- * @param params 请求参数
- * @param certPath 证书文件路径
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String queryTrans2pocket(Map params, String certPath, String certPass) {
- return execution(getReqUrl(WechatApiEnum.QUERY_WWS_TRANS_2_POCKET), params, certPath, certPass);
- }
-
- /**
- * 查询向员工付款记录
- *
- * @param params 请求参数
- * @param certFile 证书文件的 InputStream
- * @param certPass 证书密码
- * @return {@link String} 请求返回的结果
- */
- public static String queryTrans2pocket(Map params, InputStream certFile, String certPass) {
- return execution(getReqUrl(WechatApiEnum.QUERY_WWS_TRANS_2_POCKET), params, certFile, certPass);
- }
-
- /**
- * @param url 请求url
- * @param params 请求参数
- * @return {@link String} 请求返回的结果
- */
- public static String doGet(String url, Map params) {
- return HttpKit.getDelegate().get(url, params);
- }
-
- /**
- * get 请求
- *
- * @param url 请求url
- * @param params 请求参数
- * @param headers 请求头
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse get(String url, Map params, Map headers) {
- return HttpKit.getDelegate().get(url, params, headers);
- }
-
- /**
- * get 请求
- *
- * @param url 请求url
- * @param authorization 授权信息
- * @param serialNumber 公钥证书序列号
- * @param params 请求参数
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse get(String url, String authorization, String serialNumber, Map params) {
- return get(url, params, getHeaders(authorization, serialNumber));
- }
-
- /**
- * post 请求
- *
- * @param url 请求url
- * @param data 请求参数
- * @param headers 请求头
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse post(String url, String data, Map headers) {
- return HttpKit.getDelegate().post(url, data, headers);
- }
-
- /**
- * post 请求
- *
- * @param url 请求url
- * @param authorization 授权信息
- * @param serialNumber 公钥证书序列号
- * @param data 请求参数
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse post(String url, String authorization, String serialNumber, String data) {
- return post(url, data, getHeaders(authorization, serialNumber));
- }
-
- /**
- * delete 请求
- *
- * @param url 请求url
- * @param data 请求参数
- * @param headers 请求头
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse delete(String url, String data, Map headers) {
- return HttpKit.getDelegate().delete(url, data, headers);
- }
-
- /**
- * delete 请求
- *
- * @param url 请求url
- * @param authorization 授权信息
- * @param serialNumber 公钥证书序列号
- * @param data 请求参数
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse delete(String url, String authorization, String serialNumber, String data) {
- return delete(url, data, getHeaders(authorization, serialNumber));
- }
-
- /**
- * upload 请求
- *
- * @param url 请求url
- * @param params 请求参数
- * @param headers 请求头
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse upload(String url, Map params, Map headers) {
- return HttpKit.getDelegate().post(url, params, headers);
- }
-
- /**
- * upload 请求
- *
- * @param url 请求url
- * @param authorization 授权信息
- * @param serialNumber 公钥证书序列号
- * @param data 请求参数
- * @param file 上传文件
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse upload(String url, String authorization, String serialNumber, String data, File file) {
- Map paramMap = new HashMap<>(2);
- paramMap.put("file", file);
- paramMap.put("meta", data);
- return upload(url, paramMap, getUploadHeaders(authorization, serialNumber));
- }
-
-
- /**
- * put 请求
- *
- * @param url 请求url
- * @param data 请求参数
- * @param headers 请求头
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse put(String url, String data, Map headers) {
- return HttpKit.getDelegate().put(url, data, headers);
- }
-
- /**
- * put 请求
- *
- * @param url 请求url
- * @param authorization 授权信息
- * @param serialNumber 公钥证书序列号
- * @param data 请求参数
- * @return {@link PaymentHttpResponse} 请求返回的结果
- */
- public static PaymentHttpResponse put(String url, String authorization, String serialNumber, String data) {
- return put(url, data, getHeaders(authorization, serialNumber));
- }
-
- public static String doPost(String url, Map params) {
- return HttpKit.getDelegate().post(url, WxPayKit.toXml(params));
- }
-
- public static String doPostSsl(String url, Map params, String certPath, String certPass) {
- return HttpKit.getDelegate().post(url, WxPayKit.toXml(params), certPath, certPass);
- }
-
- public static String doPostSsl(String url, Map params, InputStream certFile, String certPass) {
- return HttpKit.getDelegate().post(url, WxPayKit.toXml(params), certFile, certPass);
- }
-
- public static String doPostSsl(String url, Map params, String certPath) {
- if (params.isEmpty() || !params.containsKey("mch_id")) {
- throw new RuntimeException("请求参数中必须包含 mch_id,如接口参考中不包 mch_id, 请使用其他同名构造方法。");
- }
- String certPass = params.get("mch_id");
- return doPostSsl(url, params, certPath, certPass);
- }
-
- public static String doPostSsl(String url, Map params, InputStream certFile) {
- if (params.isEmpty() || !params.containsKey("mch_id")) {
- throw new RuntimeException("请求参数中必须包含 mch_id,如接口参考中不包 mch_id, 请使用其他同名构造方法。");
- }
- String certPass = params.get("mch_id");
- return doPostSsl(url, params, certFile, certPass);
- }
-
- public static String doUploadSsl(String url, Map params, String certPath, String certPass, String filePath) {
- return HttpKit.getDelegate().upload(url, WxPayKit.toXml(params), certPath, certPass, filePath);
- }
-
- public static String doUploadSsl(String url, Map params, String certPath, String filePath) {
- if (params.isEmpty() || !params.containsKey("mch_id")) {
- throw new RuntimeException("请求参数中必须包含 mch_id,如接口参考中不包 mch_id, 请使用其他同名构造方法。");
- }
- String certPass = params.get("mch_id");
- return doUploadSsl(url, params, certPath, certPass, filePath);
- }
-
-
- public static Map getBaseHeaders(String authorization) {
- Map headers = new HashMap<>(5);
- headers.put("Accept", ContentType.JSON.toString());
- headers.put("Authorization", authorization);
- return headers;
- }
-
- public static Map getHeaders(String authorization, String serialNumber) {
- Map headers = getBaseHeaders(authorization);
- headers.put("Content-Type", ContentType.JSON.toString());
- if (StrUtil.isNotEmpty(serialNumber)) {
- headers.put("Wechatpay-Serial", serialNumber);
- }
- return headers;
- }
-
- public static Map getUploadHeaders(String authorization, String serialNumber) {
- Map headers = getBaseHeaders(authorization);
- headers.put("Content-Type", "multipart/form-data;boundary=\"boundary\"");
- if (StrUtil.isNotEmpty(serialNumber)) {
- headers.put("Wechatpay-Serial", serialNumber);
- }
- return headers;
- }
-
- /**
- * 构建返回参数
- *
- * @param response {@link PaymentHttpResponse}
- * @return {@link Map}
- */
- public static Map buildResMap(PaymentHttpResponse response) {
- if (response == null) {
- return null;
- }
- Map map = new HashMap<>(6);
- String timestamp = response.getHeader("Wechatpay-Timestamp");
- String nonceStr = response.getHeader("Wechatpay-Nonce");
- String serialNo = response.getHeader("Wechatpay-Serial");
- String signature = response.getHeader("Wechatpay-Signature");
- String body = response.getBody();
- int status = response.getStatus();
- map.put("timestamp", timestamp);
- map.put("nonceStr", nonceStr);
- map.put("serialNumber", serialNo);
- map.put("signature", signature);
- map.put("body", body);
- map.put("status", status);
- return map;
- }
-}
+//package cn.lili.modules.payment.kit.plugin.wechat;
+//
+//import cn.hutool.core.util.StrUtil;
+//import cn.hutool.http.ContentType;
+//import cn.lili.modules.payment.kit.core.PaymentHttpResponse;
+//import cn.lili.modules.payment.kit.core.enums.RequestMethodEnums;
+//import cn.lili.modules.payment.kit.core.kit.HttpKit;
+//import cn.lili.modules.payment.kit.core.kit.PayKit;
+//import cn.lili.modules.payment.kit.core.kit.WxPayKit;
+//import cn.lili.modules.payment.kit.plugin.wechat.enums.WechatApiEnum;
+//import cn.lili.modules.payment.kit.plugin.wechat.enums.WechatDomain;
+//
+//import java.io.File;
+//import java.io.InputStream;
+//import java.security.PrivateKey;
+//import java.util.HashMap;
+//import java.util.Map;
+//
+///**
+// * 微信支付相关接口
+// *
+// * @author Chopper
+// * @since 2021/1/26 15:25
+// */
+//
+//public class WechatApi {
+//
+// private WechatApi() {
+// }
+//
+// /**
+// * 获取接口请求的 URL
+// *
+// * @param wechatApiEnum {@link WechatApiEnum} 支付 API 接口枚举
+// * @return {@link String} 返回完整的接口请求URL
+// */
+// public static String getReqUrl(WechatApiEnum wechatApiEnum) {
+// return getReqUrl(wechatApiEnum, null, false);
+// }
+//
+// /**
+// * 获取接口请求的 URL
+// *
+// * @param wechatApiEnum {@link WechatApiEnum} 支付 API 接口枚举
+// * @param isSandBox 是否是沙箱环境
+// * @return {@link String} 返回完整的接口请求URL
+// */
+// public static String getReqUrl(WechatApiEnum wechatApiEnum, boolean isSandBox) {
+// return getReqUrl(wechatApiEnum, null, isSandBox);
+// }
+//
+// /**
+// * 获取接口请求的 URL
+// *
+// * @param wechatApiEnum {@link WechatApiEnum} 支付 API 接口枚举
+// * @param wechatDomain {@link WechatDomain} 支付 API 接口域名枚举
+// * @param isSandBox 是否是沙箱环境
+// * @return {@link String} 返回完整的接口请求URL
+// */
+// public static String getReqUrl(WechatApiEnum wechatApiEnum, WechatDomain wechatDomain, boolean isSandBox) {
+// if (wechatDomain == null) {
+// wechatDomain = WechatDomain.CHINA;
+// }
+// return wechatDomain.getType()
+// .concat(isSandBox ? WechatApiEnum.SAND_BOX_NEW.getUrl() : "")
+// .concat(wechatApiEnum.getUrl());
+// }
+//
+// /**
+// * 发起请求
+// *
+// * @param apiUrl 接口 URL
+// * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
+// * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
+// * @param params 接口请求参数
+// * @return {@link String} 请求返回的结果
+// */
+// public static String execution(String apiUrl, Map params) {
+// return doPost(apiUrl, params);
+// }
+//
+// /**
+// * 发起请求
+// *
+// * @param apiUrl 接口 URL
+// * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
+// * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
+// * @param params 接口请求参数
+// * @return {@link String} 请求返回的结果
+// */
+// public static String executionByGet(String apiUrl, Map params) {
+// return doGet(apiUrl, params);
+// }
+//
+// /**
+// * 发起请求
+// *
+// * @param apiUrl 接口 URL
+// * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
+// * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
+// * @param params 接口请求参数
+// * @param certPath 证书文件路径
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String execution(String apiUrl, Map params, String certPath, String certPass) {
+// return doPostSsl(apiUrl, params, certPath, certPass);
+// }
+//
+// /**
+// * 发起请求
+// *
+// * @param apiUrl 接口 URL
+// * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
+// * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
+// * @param params 接口请求参数
+// * @param certPath 证书文件路径
+// * @return {@link String} 请求返回的结果
+// */
+// public static String execution(String apiUrl, Map params, String certPath) {
+// return doPostSsl(apiUrl, params, certPath);
+// }
+//
+// /**
+// * 发起请求
+// *
+// * @param apiUrl 接口 URL
+// * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
+// * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
+// * @param params 接口请求参数
+// * @param certFile 证书文件输入流
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String execution(String apiUrl, Map params, InputStream certFile, String certPass) {
+// return doPostSsl(apiUrl, params, certFile, certPass);
+// }
+//
+// /**
+// * 发起请求
+// *
+// * @param apiUrl 接口 URL
+// * 通过 {@link WechatApi#getReqUrl(WechatApiEnum)}
+// * 或者 {@link WechatApi#getReqUrl(WechatApiEnum, WechatDomain, boolean)} 来获取
+// * @param params 接口请求参数
+// * @param certFile 证书文件输入流
+// * @return {@link String} 请求返回的结果
+// */
+// public static String execution(String apiUrl, Map params, InputStream certFile) {
+// return doPostSsl(apiUrl, params, certFile);
+// }
+//
+// public static String execution(String apiUrl, Map params,
+// String certPath, String certPass, String filePath) {
+// return doUploadSsl(apiUrl, params, certPath, certPass, filePath);
+// }
+//
+//
+// /**
+// * V3 接口统一执行入口
+// *
+// * @param method {@link RequestMethodEnums} 请求方法
+// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+// * @param mchId 商户Id
+// * @param serialNo 商户 API 证书序列号
+// * @param platSerialNo 平台序列号,接口中包含敏感信息时必传
+// * @param key apiclient_key.pem 证书
+//
+// * @param publicKey 公钥证书
+// * @param body 接口请求参数
+// * @param nonceStr 随机字符库
+// * @param timestamp 时间戳
+// * @param authType 认证类型
+// * @param file 文件
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// * @throws Exception 接口执行异常
+// */
+// public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix,
+// String mchId, String serialNo, String platSerialNo, String key,String publicKey ,
+// String body, String nonceStr, long timestamp, String authType,
+// File file) throws Exception {
+// //构建 Authorization
+// String authorization = WxPayKit.buildAuthorization(method, urlSuffix, mchId, serialNo,
+// key,publicKey,body, nonceStr, timestamp, authType);
+//
+// if (StrUtil.isEmpty(platSerialNo)) {
+// platSerialNo = serialNo;
+// }
+// if (method == RequestMethodEnums.GET) {
+// return get(urlPrefix.concat(urlSuffix), authorization, platSerialNo, null);
+// } else if (method == RequestMethodEnums.POST) {
+// return post(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
+// } else if (method == RequestMethodEnums.DELETE) {
+// return delete(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
+// } else if (method == RequestMethodEnums.UPLOAD) {
+// return upload(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body, file);
+// } else if (method == RequestMethodEnums.PUT) {
+// return put(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
+// }
+// return null;
+// }
+//
+// /**
+// * V3 接口统一执行入口
+// *
+// * @param method {@link RequestMethodEnums} 请求方法
+// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+// * @param mchId 商户Id
+// * @param serialNo 商户 API 证书序列号
+// * @param platSerialNo 平台序列号,接口中包含敏感信息时必传
+// * @param privateKey 商户私钥
+// * @param body 接口请求参数
+// * @param nonceStr 随机字符库
+// * @param timestamp 时间戳
+// * @param authType 认证类型
+// * @param file 文件
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// * @throws Exception 接口执行异常
+// */
+// public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix,
+// String mchId, String serialNo, String platSerialNo, PrivateKey privateKey,
+// String body, String nonceStr, long timestamp, String authType,
+// File file) throws Exception {
+// //构建 Authorization
+// String authorization = WxPayKit.buildAuthorization(method, urlSuffix, mchId, serialNo,
+// privateKey, body, nonceStr, timestamp, authType);
+//
+// if (StrUtil.isEmpty(platSerialNo)) {
+// platSerialNo = serialNo;
+// }
+//
+// if (method == RequestMethodEnums.GET) {
+// return get(urlPrefix.concat(urlSuffix), authorization, platSerialNo, null);
+// } else if (method == RequestMethodEnums.POST) {
+// return post(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
+// } else if (method == RequestMethodEnums.DELETE) {
+// return delete(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
+// } else if (method == RequestMethodEnums.UPLOAD) {
+// return upload(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body, file);
+// } else if (method == RequestMethodEnums.PUT) {
+// return put(urlPrefix.concat(urlSuffix), authorization, platSerialNo, body);
+// }
+// return null;
+// }
+//
+// /**
+// * V3 接口统一执行入口
+// *
+// * @param method {@link RequestMethodEnums} 请求方法
+// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+// * @param mchId 商户Id
+// * @param serialNo 商户 API 证书序列号
+// * @param platSerialNo 平台序列号
+// * @param key apiclient_key.pem 证书
+// * @param publicKey 公钥证书
+// * @param body 接口请求参数
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// * @throws Exception 接口执行异常
+// */
+// public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix, String mchId,
+// String serialNo, String platSerialNo, String key, String publicKey ,String body) throws Exception {
+// long timestamp = System.currentTimeMillis() / 1000;
+// String authType = "WECHATPAY2-SHA256-RSA2048";
+// String nonceStr = WxPayKit.generateStr();
+// return v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, key,publicKey,body, nonceStr, timestamp, authType, null);
+// }
+//
+// /**
+// * V3 接口统一执行入口
+// *
+// * @param method {@link RequestMethodEnums} 请求方法
+// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+// * @param mchId 商户Id
+// * @param serialNo 商户 API 证书序列号
+// * @param platSerialNo 平台序列号
+// * @param privateKey 商户私钥
+// * @param body 接口请求参数
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// * @throws Exception 接口执行异常
+// */
+// public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix, String mchId,
+// String serialNo, String platSerialNo, PrivateKey privateKey, String body) throws Exception {
+// long timestamp = System.currentTimeMillis() / 1000;
+// String authType = "WECHATPAY2-SHA256-RSA2048";
+// String nonceStr = WxPayKit.generateStr();
+// return v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, privateKey, body, nonceStr, timestamp, authType, null);
+// }
+//
+//// /**
+//// * V3 接口统一执行入口
+//// *
+//// * @param method {@link RequestMethodEnums} 请求方法
+//// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+//// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+//// * @param mchId 商户Id
+//// * @param serialNo 商户 API 证书序列号
+//// * @param platSerialNo 平台序列号
+//// * @param keyPath apiclient_key.pem 证书路径
+//// * @param params Get 接口请求参数
+//// * @return {@link PaymentHttpResponse} 请求返回的结果
+//// * @throws Exception 接口执行异常
+//// */
+//// public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix,
+//// String mchId, String serialNo, String platSerialNo, String keyPath,
+//// Map params) throws Exception {
+//// long timestamp = System.currentTimeMillis() / 1000;
+//// String authType = "WECHATPAY2-SHA256-RSA2048";
+//// String nonceStr = WxPayKit.generateStr();
+//// if (null != params && !params.keySet().isEmpty()) {
+//// urlSuffix = urlSuffix.concat("?").concat(PayKit.createLinkString(params, true));
+//// }
+//// return v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, "", nonceStr, timestamp, authType, null);
+//// }
+//
+// /**
+// * V3 接口统一执行入口
+// *
+// * @param method {@link RequestMethodEnums} 请求方法
+// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+// * @param mchId 商户Id
+// * @param serialNo 商户 API 证书序列号
+// * @param platSerialNo 平台序列号
+// * @param privateKey 商户私钥
+// * @param params Get 接口请求参数
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// * @throws Exception 接口执行异常
+// */
+// public static PaymentHttpResponse v3(RequestMethodEnums method, String urlPrefix, String urlSuffix,
+// String mchId, String serialNo, String platSerialNo, PrivateKey privateKey,
+// Map params) throws Exception {
+// long timestamp = System.currentTimeMillis() / 1000;
+// String authType = "WECHATPAY2-SHA256-RSA2048";
+// String nonceStr = WxPayKit.generateStr();
+// if (null != params && !params.keySet().isEmpty()) {
+// urlSuffix = urlSuffix.concat("?").concat(PayKit.createLinkString(params, true));
+// }
+// return v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, privateKey, "", nonceStr, timestamp, authType, null);
+// }
+//
+//// /**
+//// * V3 接口统一执行入口
+//// *
+//// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+//// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+//// * @param mchId 商户Id
+//// * @param serialNo 商户 API 证书序列号
+//// * @param platSerialNo 平台序列号
+//// * @param keyPath apiclient_key.pem 证书路径
+//// * @param body 接口请求参数
+//// * @param file 文件
+//// * @return {@link PaymentHttpResponse} 请求返回的结果
+//// * @throws Exception 接口执行异常
+//// */
+//// public static PaymentHttpResponse v3(String urlPrefix, String urlSuffix, String mchId, String serialNo, String platSerialNo, String keyPath, String body, File file) throws Exception {
+//// long timestamp = System.currentTimeMillis() / 1000;
+//// String authType = "WECHATPAY2-SHA256-RSA2048";
+//// String nonceStr = WxPayKit.generateStr();
+//// return v3(RequestMethodEnums.UPLOAD, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, body, nonceStr, timestamp, authType, file);
+//// }
+//
+// /**
+// * V3 接口统一执行入口
+// *
+// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+// * @param mchId 商户Id
+// * @param serialNo 商户 API 证书序列号
+// * @param platSerialNo 平台序列号
+// * @param privateKey 商户私钥
+// * @param body 接口请求参数
+// * @param file 文件
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// * @throws Exception 接口执行异常
+// */
+// public static PaymentHttpResponse v3(String urlPrefix, String urlSuffix, String mchId, String serialNo,
+// String platSerialNo, PrivateKey privateKey, String body, File file) throws Exception {
+// long timestamp = System.currentTimeMillis() / 1000;
+// String authType = "WECHATPAY2-SHA256-RSA2048";
+// String nonceStr = WxPayKit.generateStr();
+// return v3(RequestMethodEnums.UPLOAD, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, privateKey, body, nonceStr, timestamp, authType, file);
+// }
+//
+//// /**
+//// * V3 接口统一执行入口
+//// *
+//// * @param method {@link RequestMethodEnums} 请求方法
+//// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+//// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+//// * @param mchId 商户Id
+//// * @param serialNo 商户 API 证书序列号
+//// * @param platSerialNo 平台序列号,接口中包含敏感信息时必传
+//// * @param keyPath apiclient_key.pem 证书路径
+//// * @param body 接口请求参数
+//// * @param nonceStr 随机字符库
+//// * @param timestamp 时间戳
+//// * @param authType 认证类型
+//// * @param file 文件
+//// * @return {@link Map} 请求返回的结果
+//// * @throws Exception 接口执行异常
+//// */
+//// @Deprecated
+//// public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix,
+//// String mchId, String serialNo, String platSerialNo, String keyPath,
+//// String body, String nonceStr, long timestamp, String authType,
+//// File file) throws Exception {
+//// PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, body, nonceStr, timestamp, authType, file);
+//// return buildResMap(response);
+//// }
+//
+//// /**
+//// * V3 接口统一执行入口
+//// *
+//// * @param method {@link RequestMethodEnums} 请求方法
+//// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+//// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+//// * @param mchId 商户Id
+//// * @param serialNo 商户 API 证书序列号
+//// * @param keyPath apiclient_key.pem 证书路径
+//// * @param body 接口请求参数
+//// * @return {@link Map} 请求返回的结果
+//// */
+//// @Deprecated
+//// public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix, String mchId,
+//// String serialNo, String keyPath, String body) throws Exception {
+//// PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, null, keyPath, body);
+//// return buildResMap(response);
+//// }
+//
+//// /**
+//// * V3 接口统一执行入口
+//// *
+//// * @param method {@link RequestMethodEnums} 请求方法
+//// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+//// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+//// * @param mchId 商户Id
+//// * @param serialNo 商户 API 证书序列号
+//// * @param platSerialNo 平台序列号
+//// * @param keyPath apiclient_key.pem 证书路径
+//// * @param body 接口请求参数
+//// * @return {@link Map} 请求返回的结果
+//// * @throws Exception 接口执行异常
+//// */
+//// @Deprecated
+//// public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix, String mchId,
+//// String serialNo, String platSerialNo, String keyPath, String body) throws Exception {
+//// PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, body);
+//// return buildResMap(response);
+//// }
+//
+//// /**
+//// * V3 接口统一执行入口
+//// *
+//// * @param method {@link RequestMethodEnums} 请求方法
+//// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+//// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+//// * @param mchId 商户Id
+//// * @param serialNo 商户 API 证书序列号
+//// * @param platSerialNo 平台序列号
+//// * @param keyPath apiclient_key.pem 证书路径
+//// * @param params Get 接口请求参数
+//// * @return {@link Map} 请求返回的结果
+//// * @throws Exception 接口执行异常
+//// */
+//// @Deprecated
+//// public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix,
+//// String mchId, String serialNo, String platSerialNo, String keyPath,
+//// Map params) throws Exception {
+//// PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, params);
+//// return buildResMap(response);
+//// }
+//
+//// /**
+//// * V3 接口统一执行入口
+//// *
+//// * @param method {@link RequestMethodEnums} 请求方法
+//// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+//// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+//// * @param mchId 商户Id
+//// * @param serialNo 商户 API 证书序列号
+//// * @param keyPath apiclient_key.pem 证书路径
+//// * @param params Get 接口请求参数
+//// * @return {@link Map} 请求返回的结果
+//// * @throws Exception 接口执行异常
+//// */
+//// @Deprecated
+//// public static Map v3Execution(RequestMethodEnums method, String urlPrefix, String urlSuffix,
+//// String mchId, String serialNo, String keyPath,
+//// Map params) throws Exception {
+//// PaymentHttpResponse response = v3(method, urlPrefix, urlSuffix, mchId, serialNo, null, keyPath, params);
+//// return buildResMap(response);
+//// }
+//
+//// /**
+//// * V3 接口统一执行入口
+//// *
+//// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+//// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+//// * @param mchId 商户Id
+//// * @param serialNo 商户 API 证书序列号
+//// * @param platSerialNo 平台序列号
+//// * @param keyPath apiclient_key.pem 证书路径
+//// * @param body 接口请求参数
+//// * @param file 文件
+//// * @return {@link Map} 请求返回的结果
+//// * @throws Exception 接口执行异常
+//// */
+//// @Deprecated
+//// public static Map v3Upload(String urlPrefix, String urlSuffix, String mchId, String serialNo, String platSerialNo, String keyPath, String body, File file) throws Exception {
+//// PaymentHttpResponse response = v3(urlPrefix, urlSuffix, mchId, serialNo, platSerialNo, keyPath, body, file);
+//// return buildResMap(response);
+//// }
+//
+//// /**
+//// * V3 接口统一执行入口
+//// *
+//// * @param urlPrefix 可通过 {@link WechatDomain}来获取
+//// * @param urlSuffix 可通过 {@link WechatApiEnum} 来获取,URL挂载参数需要自行拼接
+//// * @param mchId 商户Id
+//// * @param serialNo 商户 API 证书序列号
+//// * @param keyPath apiclient_key.pem 证书路径
+//// * @param body 接口请求参数
+//// * @param file 文件
+//// * @return {@link Map} 请求返回的结果
+//// * @throws Exception 接口执行异常
+//// */
+//// @Deprecated
+//// public static Map v3Upload(String urlPrefix, String urlSuffix, String mchId, String serialNo, String keyPath, String body, File file) throws Exception {
+//// return v3Upload(urlPrefix, urlSuffix, mchId, serialNo, null, keyPath, body, file);
+//// }
+//
+// /**
+// * 发放企业红包
+// *
+// * @param params 请求参数
+// * @param certPath 证书文件路径
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String sendWorkWxRedPack(Map params, String certPath, String certPass) {
+// return execution(getReqUrl(WechatApiEnum.SEND_WORK_WX_RED_PACK), params, certPath, certPass);
+// }
+//
+// /**
+// * 发放企业红包
+// *
+// * @param params 请求参数
+// * @param certFile 证书文件的 InputStream
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String sendWorkWxRedPack(Map params, InputStream certFile, String certPass) {
+// return execution(getReqUrl(WechatApiEnum.SEND_WORK_WX_RED_PACK), params, certFile, certPass);
+// }
+//
+// /**
+// * 查询向员工付款记录
+// *
+// * @param params 请求参数
+// * @param certPath 证书文件路径
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String queryWorkWxRedPack(Map params, String certPath, String certPass) {
+// return execution(getReqUrl(WechatApiEnum.QUERY_WORK_WX_RED_PACK), params, certPath, certPass);
+// }
+//
+// /**
+// * 查询向员工付款记录
+// *
+// * @param params 请求参数
+// * @param certFile 证书文件的 InputStream
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String queryWorkWxRedPack(Map params, InputStream certFile, String certPass) {
+// return execution(getReqUrl(WechatApiEnum.QUERY_WORK_WX_RED_PACK), params, certFile, certPass);
+// }
+//
+// /**
+// * 向员工付款
+// *
+// * @param params 请求参数
+// * @param certPath 证书文件路径
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String trans2pocket(Map params, String certPath, String certPass) {
+// return execution(getReqUrl(WechatApiEnum.PAY_WWS_TRANS_2_POCKET), params, certPath, certPass);
+// }
+//
+// /**
+// * 向员工付款
+// *
+// * @param params 请求参数
+// * @param certFile 证书文件的 InputStream
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String trans2pocket(Map params, InputStream certFile, String certPass) {
+// return execution(getReqUrl(WechatApiEnum.PAY_WWS_TRANS_2_POCKET), params, certFile, certPass);
+// }
+//
+// /**
+// * 查询向员工付款记录
+// *
+// * @param params 请求参数
+// * @param certPath 证书文件路径
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String queryTrans2pocket(Map params, String certPath, String certPass) {
+// return execution(getReqUrl(WechatApiEnum.QUERY_WWS_TRANS_2_POCKET), params, certPath, certPass);
+// }
+//
+// /**
+// * 查询向员工付款记录
+// *
+// * @param params 请求参数
+// * @param certFile 证书文件的 InputStream
+// * @param certPass 证书密码
+// * @return {@link String} 请求返回的结果
+// */
+// public static String queryTrans2pocket(Map params, InputStream certFile, String certPass) {
+// return execution(getReqUrl(WechatApiEnum.QUERY_WWS_TRANS_2_POCKET), params, certFile, certPass);
+// }
+//
+// /**
+// * @param url 请求url
+// * @param params 请求参数
+// * @return {@link String} 请求返回的结果
+// */
+// public static String doGet(String url, Map params) {
+// return HttpKit.getDelegate().get(url, params);
+// }
+//
+// /**
+// * get 请求
+// *
+// * @param url 请求url
+// * @param params 请求参数
+// * @param headers 请求头
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse get(String url, Map params, Map headers) {
+// return HttpKit.getDelegate().get(url, params, headers);
+// }
+//
+// /**
+// * get 请求
+// *
+// * @param url 请求url
+// * @param authorization 授权信息
+// * @param serialNumber 公钥证书序列号
+// * @param params 请求参数
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse get(String url, String authorization, String serialNumber, Map params) {
+// return get(url, params, getHeaders(authorization, serialNumber));
+// }
+//
+// /**
+// * post 请求
+// *
+// * @param url 请求url
+// * @param data 请求参数
+// * @param headers 请求头
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse post(String url, String data, Map headers) {
+// return HttpKit.getDelegate().post(url, data, headers);
+// }
+//
+// /**
+// * post 请求
+// *
+// * @param url 请求url
+// * @param authorization 授权信息
+// * @param serialNumber 公钥证书序列号
+// * @param data 请求参数
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse post(String url, String authorization, String serialNumber, String data) {
+// return post(url, data, getHeaders(authorization, serialNumber));
+// }
+//
+// /**
+// * delete 请求
+// *
+// * @param url 请求url
+// * @param data 请求参数
+// * @param headers 请求头
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse delete(String url, String data, Map headers) {
+// return HttpKit.getDelegate().delete(url, data, headers);
+// }
+//
+// /**
+// * delete 请求
+// *
+// * @param url 请求url
+// * @param authorization 授权信息
+// * @param serialNumber 公钥证书序列号
+// * @param data 请求参数
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse delete(String url, String authorization, String serialNumber, String data) {
+// return delete(url, data, getHeaders(authorization, serialNumber));
+// }
+//
+// /**
+// * upload 请求
+// *
+// * @param url 请求url
+// * @param params 请求参数
+// * @param headers 请求头
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse upload(String url, Map params, Map headers) {
+// return HttpKit.getDelegate().post(url, params, headers);
+// }
+//
+// /**
+// * upload 请求
+// *
+// * @param url 请求url
+// * @param authorization 授权信息
+// * @param serialNumber 公钥证书序列号
+// * @param data 请求参数
+// * @param file 上传文件
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse upload(String url, String authorization, String serialNumber, String data, File file) {
+// Map paramMap = new HashMap<>(2);
+// paramMap.put("file", file);
+// paramMap.put("meta", data);
+// return upload(url, paramMap, getUploadHeaders(authorization, serialNumber));
+// }
+//
+//
+// /**
+// * put 请求
+// *
+// * @param url 请求url
+// * @param data 请求参数
+// * @param headers 请求头
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse put(String url, String data, Map headers) {
+// return HttpKit.getDelegate().put(url, data, headers);
+// }
+//
+// /**
+// * put 请求
+// *
+// * @param url 请求url
+// * @param authorization 授权信息
+// * @param serialNumber 公钥证书序列号
+// * @param data 请求参数
+// * @return {@link PaymentHttpResponse} 请求返回的结果
+// */
+// public static PaymentHttpResponse put(String url, String authorization, String serialNumber, String data) {
+// return put(url, data, getHeaders(authorization, serialNumber));
+// }
+//
+// public static String doPost(String url, Map params) {
+// return HttpKit.getDelegate().post(url, WxPayKit.toXml(params));
+// }
+//
+// public static String doPostSsl(String url, Map params, String certPath, String certPass) {
+// return HttpKit.getDelegate().post(url, WxPayKit.toXml(params), certPath, certPass);
+// }
+//
+// public static String doPostSsl(String url, Map params, InputStream certFile, String certPass) {
+// return HttpKit.getDelegate().post(url, WxPayKit.toXml(params), certFile, certPass);
+// }
+//
+// public static String doPostSsl(String url, Map params, String certPath) {
+// if (params.isEmpty() || !params.containsKey("mch_id")) {
+// throw new RuntimeException("请求参数中必须包含 mch_id,如接口参考中不包 mch_id, 请使用其他同名构造方法。");
+// }
+// String certPass = params.get("mch_id");
+// return doPostSsl(url, params, certPath, certPass);
+// }
+//
+// public static String doPostSsl(String url, Map params, InputStream certFile) {
+// if (params.isEmpty() || !params.containsKey("mch_id")) {
+// throw new RuntimeException("请求参数中必须包含 mch_id,如接口参考中不包 mch_id, 请使用其他同名构造方法。");
+// }
+// String certPass = params.get("mch_id");
+// return doPostSsl(url, params, certFile, certPass);
+// }
+//
+// public static String doUploadSsl(String url, Map params, String certPath, String certPass, String filePath) {
+// return HttpKit.getDelegate().upload(url, WxPayKit.toXml(params), certPath, certPass, filePath);
+// }
+//
+// public static String doUploadSsl(String url, Map params, String certPath, String filePath) {
+// if (params.isEmpty() || !params.containsKey("mch_id")) {
+// throw new RuntimeException("请求参数中必须包含 mch_id,如接口参考中不包 mch_id, 请使用其他同名构造方法。");
+// }
+// String certPass = params.get("mch_id");
+// return doUploadSsl(url, params, certPath, certPass, filePath);
+// }
+//
+//
+// public static Map getBaseHeaders(String authorization) {
+// Map headers = new HashMap<>(5);
+// headers.put("Accept", ContentType.JSON.toString());
+// headers.put("Authorization", authorization);
+// return headers;
+// }
+//
+// public static Map getHeaders(String authorization, String serialNumber) {
+// Map headers = getBaseHeaders(authorization);
+// headers.put("Content-Type", ContentType.JSON.toString());
+// if (StrUtil.isNotEmpty(serialNumber)) {
+// headers.put("Wechatpay-Serial", serialNumber);
+// }
+// return headers;
+// }
+//
+// public static Map getUploadHeaders(String authorization, String serialNumber) {
+// Map headers = getBaseHeaders(authorization);
+// headers.put("Content-Type", "multipart/form-data;boundary=\"boundary\"");
+// if (StrUtil.isNotEmpty(serialNumber)) {
+// headers.put("Wechatpay-Serial", serialNumber);
+// }
+// return headers;
+// }
+//
+// /**
+// * 构建返回参数
+// *
+// * @param response {@link PaymentHttpResponse}
+// * @return {@link Map}
+// */
+// public static Map buildResMap(PaymentHttpResponse response) {
+// if (response == null) {
+// return null;
+// }
+// Map map = new HashMap<>(6);
+// String timestamp = response.getHeader("Wechatpay-Timestamp");
+// String nonceStr = response.getHeader("Wechatpay-Nonce");
+// String serialNo = response.getHeader("Wechatpay-Serial");
+// String signature = response.getHeader("Wechatpay-Signature");
+// String body = response.getBody();
+// int status = response.getStatus();
+// map.put("timestamp", timestamp);
+// map.put("nonceStr", nonceStr);
+// map.put("serialNumber", serialNo);
+// map.put("signature", signature);
+// map.put("body", body);
+// map.put("status", status);
+// return map;
+// }
+//}
diff --git a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatPlugin.java b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatPlugin.java
index 5a27dbf9..cf467e7f 100644
--- a/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatPlugin.java
+++ b/framework/src/main/java/cn/lili/modules/payment/kit/plugin/wechat/WechatPlugin.java
@@ -1,16 +1,14 @@
package cn.lili.modules.payment.kit.plugin.wechat;
+import cn.hutool.core.convert.Convert;
import cn.hutool.core.net.URLDecoder;
import cn.hutool.core.net.URLEncoder;
-import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.lili.cache.Cache;
-import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.ResultUtil;
import cn.lili.common.exception.ServiceException;
-import cn.lili.common.properties.ApiProperties;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.CurrencyUtil;
import cn.lili.common.utils.SnowFlake;
@@ -29,7 +27,9 @@ import cn.lili.modules.payment.kit.Payment;
import cn.lili.modules.payment.kit.core.PaymentHttpResponse;
import cn.lili.modules.payment.kit.core.enums.RequestMethodEnums;
import cn.lili.modules.payment.kit.core.enums.SignType;
-import cn.lili.modules.payment.kit.core.kit.*;
+import cn.lili.modules.payment.kit.core.kit.HttpKit;
+import cn.lili.modules.payment.kit.core.kit.IpKit;
+import cn.lili.modules.payment.kit.core.kit.WxPayKit;
import cn.lili.modules.payment.kit.core.utils.DateTimeZoneUtil;
import cn.lili.modules.payment.kit.dto.PayParam;
import cn.lili.modules.payment.kit.dto.PaymentSuccessParams;
@@ -51,6 +51,30 @@ import cn.lili.modules.wallet.entity.dto.TransferResultDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.gson.Gson;
+import com.wechat.pay.java.core.Config;
+import com.wechat.pay.java.core.RSAAutoCertificateConfig;
+import com.wechat.pay.java.core.RSAPublicKeyConfig;
+import com.wechat.pay.java.core.exception.ValidationException;
+import com.wechat.pay.java.core.notification.NotificationConfig;
+import com.wechat.pay.java.core.notification.NotificationParser;
+import com.wechat.pay.java.core.notification.RequestParam;
+import com.wechat.pay.java.core.util.StringUtil;
+import com.wechat.pay.java.service.payments.app.AppService;
+import com.wechat.pay.java.service.payments.h5.H5Service;
+import com.wechat.pay.java.service.payments.jsapi.JsapiService;
+import com.wechat.pay.java.service.payments.model.Transaction;
+import com.wechat.pay.java.service.payments.nativepay.NativePayService;
+import com.wechat.pay.java.service.payments.nativepay.model.Amount;
+import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
+import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
+import com.wechat.pay.java.service.refund.RefundService;
+import com.wechat.pay.java.service.refund.model.AmountReq;
+import com.wechat.pay.java.service.refund.model.CreateRequest;
+import com.wechat.pay.java.service.refund.model.Refund;
+import com.wechat.pay.java.service.transferbatch.TransferBatchService;
+import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferRequest;
+import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse;
+import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -58,8 +82,6 @@ import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -141,31 +163,28 @@ public class WechatPlugin implements Payment {
if (appid == null) {
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
}
- UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
- .setAppid(appid)
- .setMchid(setting.getMchId())
- .setDescription(cashierParam.getDetail())
- .setOut_trade_no(outOrderNo)
- .setTime_expire(timeExpire)
- .setAttach(attach)
- .setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(),PaymentMethodEnum.WECHAT))
- .setAmount(new Amount().setTotal(fen)).setScene_info(sceneInfo);
- log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
- PaymentHttpResponse response = WechatApi.v3(
- RequestMethodEnums.POST,
- WechatDomain.CHINA.toString(),
- WechatApiEnum.H5_PAY.toString(),
- setting.getMchId(),
- setting.getSerialNumber(),
- null,
- setting.getApiclient_key(),
- JSONUtil.toJsonStr(unifiedOrderModel)
- );
+ Config config =this.getConfig(setting);
+ // 构建service
+ H5Service service = new H5Service.Builder().config(config).build();
+ com.wechat.pay.java.service.payments.h5.model.PrepayRequest prepayRequest = new com.wechat.pay.java.service.payments.h5.model.PrepayRequest();
+ com.wechat.pay.java.service.payments.h5.model.Amount amount = new com.wechat.pay.java.service.payments.h5.model.Amount();
+ amount.setTotal(fen);
+ prepayRequest.setAmount(amount);
+ prepayRequest.setAppid(appid);
+ prepayRequest.setMchid(setting.getMchId());
+ prepayRequest.setDescription(cashierParam.getDetail());
+ prepayRequest.setNotifyUrl(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT));
+ prepayRequest.setAttach(attach);
+ prepayRequest.setTimeExpire(timeExpire);
+ prepayRequest.setOutTradeNo(outOrderNo);
+
+ // 调用下单方法,得到应答
+ com.wechat.pay.java.service.payments.h5.model.PrepayResponse response = service.prepay(prepayRequest);
updateOrderPayNo(payParam,outOrderNo);
- return ResultUtil.data(JSONUtil.toJsonStr(response.getBody()));
+ return ResultUtil.data(response.getH5Url());
} catch (Exception e) {
log.error("微信H5支付错误", e);
throw new ServiceException(ResultCode.PAY_ERROR);
@@ -183,8 +202,7 @@ public class WechatPlugin implements Payment {
return null;
}
- Payer payer = new Payer();
- payer.setOpenid(connect.getUnionId());
+
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
@@ -202,46 +220,33 @@ public class WechatPlugin implements Payment {
if (appid == null) {
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
}
- UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
- .setAppid(appid)
- .setMchid(setting.getMchId())
- .setDescription(cashierParam.getDetail())
- .setOut_trade_no(outOrderNo)
- .setTime_expire(timeExpire)
- .setAttach(attach)
- .setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT))
- .setAmount(new Amount().setTotal(fen))
- .setPayer(payer);
- log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
- PaymentHttpResponse response = WechatApi.v3(
- RequestMethodEnums.POST,
- WechatDomain.CHINA.toString(),
- WechatApiEnum.JS_API_PAY.toString(),
- setting.getMchId(),
- setting.getSerialNumber(),
- null,
- setting.getApiclient_key(),
- JSONUtil.toJsonStr(unifiedOrderModel)
- );
- //根据证书序列号查询对应的证书来验证签名结果
- boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert());
- log.info("verifySignature: {}", verifySignature);
- log.info("统一下单响应 {}", response);
+ Config config =this.getConfig(setting);
+ // 构建service
+ JsapiService service = new JsapiService.Builder().config(config).build();
- if (verifySignature) {
- String body = response.getBody();
- JSONObject jsonObject = JSONUtil.parseObj(body);
- String prepayId = jsonObject.getStr("prepay_id");
- Map map = WxPayKit.jsApiCreateSign(appid, prepayId, setting.getApiclient_key());
- log.info("唤起支付参数:{}", map);
+ com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest prepayRequest = new com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest();
+ com.wechat.pay.java.service.payments.jsapi.model.Amount amount = new com.wechat.pay.java.service.payments.jsapi.model.Amount();
- updateOrderPayNo(payParam,outOrderNo);
+ com.wechat.pay.java.service.payments.jsapi.model.Payer payer = new com.wechat.pay.java.service.payments.jsapi.model.Payer();
+ payer.setOpenid(connect.getUnionId());
+ amount.setTotal(fen);
+ prepayRequest.setAmount(amount);
+ prepayRequest.setAppid(appid);
+ prepayRequest.setMchid(setting.getMchId());
+ prepayRequest.setDescription(cashierParam.getDetail());
+ prepayRequest.setNotifyUrl(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT));
+ prepayRequest.setAttach(attach);
+ prepayRequest.setTimeExpire(timeExpire);
+ prepayRequest.setOutTradeNo(outOrderNo);
+ prepayRequest.setPayer(payer);
+ // 调用下单方法,得到应答
+ com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse response = service.prepay(prepayRequest);
+ updateOrderPayNo(payParam,outOrderNo);
- return ResultUtil.data(map);
- }
- log.error("微信支付参数验证错误,请及时处理");
- throw new ServiceException(ResultCode.PAY_ERROR);
+ Map map = WxPayKit.jsApiCreateSign(appid, response.getPrepayId(), setting.getApiclientKey());
+ log.info("唤起支付参数:{}", map);
+ return ResultUtil.data(map);
} catch (Exception e) {
log.error("支付异常", e);
throw new ServiceException(ResultCode.PAY_ERROR);
@@ -269,48 +274,34 @@ public class WechatPlugin implements Payment {
if (appid == null) {
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
}
- UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
- .setAppid(appid)
- .setMchid(setting.getMchId())
- .setDescription(cashierParam.getDetail())
- .setOut_trade_no(outOrderNo)
- .setTime_expire(timeExpire)
- .setAttach(attach)
- .setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT))
- .setAmount(new Amount().setTotal(fen));
+ Config config =this.getConfig(setting);
+ // 构建service
+ AppService service = new AppService.Builder().config(config).build();
- log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
- PaymentHttpResponse response = WechatApi.v3(
- RequestMethodEnums.POST,
- WechatDomain.CHINA.toString(),
- WechatApiEnum.APP_PAY.toString(),
+ com.wechat.pay.java.service.payments.app.model.PrepayRequest prepayRequest = new com.wechat.pay.java.service.payments.app.model.PrepayRequest();
+ com.wechat.pay.java.service.payments.app.model.Amount amount = new com.wechat.pay.java.service.payments.app.model.Amount();
+ amount.setTotal(fen);
+ prepayRequest.setAmount(amount);
+ prepayRequest.setAppid(appid);
+ prepayRequest.setMchid(setting.getMchId());
+ prepayRequest.setDescription(cashierParam.getDetail());
+ prepayRequest.setNotifyUrl(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT));
+ prepayRequest.setAttach(attach);
+ prepayRequest.setTimeExpire(timeExpire);
+ prepayRequest.setOutTradeNo(outOrderNo);
+
+ // 调用下单方法,得到应答
+ com.wechat.pay.java.service.payments.app.model.PrepayResponse response = service.prepay(prepayRequest);
+ updateOrderPayNo(payParam,outOrderNo);
+ Map map = WxPayKit.appPrepayIdCreateSign(appid,
setting.getMchId(),
- setting.getSerialNumber(),
- null,
- setting.getApiclient_key(),
- JSONUtil.toJsonStr(unifiedOrderModel)
- );
- //根据证书序列号查询对应的证书来验证签名结果
- boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert());
- log.info("verifySignature: {}", verifySignature);
- log.info("统一下单响应 {}", response);
-
- if (verifySignature) {
- JSONObject jsonObject = JSONUtil.parseObj(response.getBody());
- String prepayId = jsonObject.getStr("prepay_id");
- Map map = WxPayKit.appPrepayIdCreateSign(appid,
- setting.getMchId(),
- prepayId,
- setting.getApiclient_key(), SignType.MD5);
- log.info("唤起支付参数:{}", map);
-
- updateOrderPayNo(payParam,outOrderNo);
-
- return ResultUtil.data(map);
- }
- log.error("微信支付参数验证错误,请及时处理");
- throw new ServiceException(ResultCode.PAY_ERROR);
+ response.getPrepayId(),
+ setting.getApiclientKey(), SignType.MD5);
+ log.info("唤起支付参数:{}", map);
+ //修改付款单号
+ updateOrderPayNo(payParam,outOrderNo);
+ return ResultUtil.data(map);
} catch (Exception e) {
log.error("支付异常", e);
throw new ServiceException(ResultCode.PAY_ERROR);
@@ -339,41 +330,28 @@ public class WechatPlugin implements Payment {
if (appid == null) {
throw new ServiceException(ResultCode.WECHAT_PAYMENT_NOT_SETTING);
}
- UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
- .setAppid(appid)
- .setMchid(setting.getMchId())
- .setDescription(cashierParam.getDetail())
- .setOut_trade_no(outOrderNo)
- .setTime_expire(timeExpire)
- //回传参数
- .setAttach(attach)
- .setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT))
- .setAmount(new Amount().setTotal(fen));
- log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
- PaymentHttpResponse response = WechatApi.v3(
- RequestMethodEnums.POST,
- WechatDomain.CHINA.toString(),
- WechatApiEnum.NATIVE_PAY.toString(),
- setting.getMchId(),
- setting.getSerialNumber(),
- null,
- setting.getApiclient_key(),
- JSONUtil.toJsonStr(unifiedOrderModel)
- );
- log.info("统一下单响应 {}", response);
- //根据证书序列号查询对应的证书来验证签名结果
- boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert());
- log.info("verifySignature: {}", verifySignature);
+ Config config =this.getConfig(setting);
+ // 构建service
+ NativePayService service = new NativePayService.Builder().config(config).build();
- if (verifySignature) {
- updateOrderPayNo(payParam,outOrderNo);
+ PrepayRequest prepayRequest = new PrepayRequest();
+ Amount amount = new Amount();
+ amount.setTotal(fen);
+ prepayRequest.setAmount(amount);
+ prepayRequest.setAppid(appid);
+ prepayRequest.setMchid(setting.getMchId());
+ prepayRequest.setDescription(cashierParam.getDetail());
+ prepayRequest.setNotifyUrl(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT));
+ prepayRequest.setAttach(attach);
+ prepayRequest.setTimeExpire(timeExpire);
+ prepayRequest.setOutTradeNo(outOrderNo);
+
+ // 调用下单方法,得到应答
+ PrepayResponse response = service.prepay(prepayRequest);
+ updateOrderPayNo(payParam,outOrderNo);
+ return ResultUtil.data(response.getCodeUrl());
- return ResultUtil.data(new JSONObject(response.getBody()).getStr("code_url"));
- } else {
- log.error("微信支付参数验证错误,请及时处理");
- throw new ServiceException(ResultCode.PAY_ERROR);
- }
} catch (ServiceException e) {
log.error("支付异常", e);
throw new ServiceException(ResultCode.PAY_ERROR);
@@ -381,6 +359,7 @@ public class WechatPlugin implements Payment {
log.error("支付异常", e);
throw new ServiceException(ResultCode.PAY_ERROR);
}
+
}
@Override
@@ -394,7 +373,7 @@ public class WechatPlugin implements Payment {
return null;
}
- Payer payer = new Payer();
+ com.wechat.pay.java.service.payments.jsapi.model.Payer payer = new com.wechat.pay.java.service.payments.jsapi.model.Payer();
payer.setOpenid(connect.getUnionId());
CashierParam cashierParam = cashierSupport.cashierParam(payParam);
@@ -415,44 +394,32 @@ public class WechatPlugin implements Payment {
String attach = URLEncoder.createDefault().encode(JSONUtil.toJsonStr(payParam), StandardCharsets.UTF_8);
WechatPaymentSetting setting = wechatPaymentSetting();
- UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
- .setAppid(appid)
- .setMchid(setting.getMchId())
- .setDescription(cashierParam.getDetail())
- .setOut_trade_no(outOrderNo)
- .setTime_expire(timeExpire)
- .setAttach(attach)
- .setNotify_url(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT))
- .setAmount(new Amount().setTotal(fen))
- .setPayer(payer);
- log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
- PaymentHttpResponse response = WechatApi.v3(
- RequestMethodEnums.POST,
- WechatDomain.CHINA.toString(),
- WechatApiEnum.JS_API_PAY.toString(),
- setting.getMchId(),
- setting.getSerialNumber(),
- null,
- setting.getApiclient_key(),
- JSONUtil.toJsonStr(unifiedOrderModel)
- );
- //根据证书序列号查询对应的证书来验证签名结果
- boolean verifySignature = WxPayKit.verifySignature(response, getPlatformCert());
- log.info("verifySignature: {}", verifySignature);
- log.info("统一下单响应 {}", response);
+ Config config =this.getConfig(setting);
+ // 构建service
+ JsapiService service = new JsapiService.Builder().config(config).build();
+
+ com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest prepayRequest = new com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest();
+ com.wechat.pay.java.service.payments.jsapi.model.Amount amount = new com.wechat.pay.java.service.payments.jsapi.model.Amount();
+ amount.setTotal(fen);
+ prepayRequest.setAmount(amount);
+ prepayRequest.setAppid(appid);
+ prepayRequest.setMchid(setting.getMchId());
+ prepayRequest.setDescription(cashierParam.getDetail());
+ prepayRequest.setNotifyUrl(notifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT));
+ prepayRequest.setAttach(attach);
+ prepayRequest.setTimeExpire(timeExpire);
+ prepayRequest.setOutTradeNo(outOrderNo);
+ prepayRequest.setPayer(payer);
+ // 调用下单方法,得到应答
+ com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse response = service.prepay(prepayRequest);
+ updateOrderPayNo(payParam,outOrderNo);
+
+ Map map = WxPayKit.jsApiCreateSign(appid, response.getPrepayId(), setting.getApiclientKey());
+ log.info("唤起支付参数:{}", map);
+
+ return ResultUtil.data(map);
- if (verifySignature) {
- String body = response.getBody();
- JSONObject jsonObject = JSONUtil.parseObj(body);
- String prepayId = jsonObject.getStr("prepay_id");
- Map map = WxPayKit.jsApiCreateSign(appid, prepayId, setting.getApiclient_key());
- log.info("唤起支付参数:{}", map);
- updateOrderPayNo(payParam,outOrderNo);
- return ResultUtil.data(map);
- }
- log.error("微信支付参数验证错误,请及时处理");
- throw new ServiceException(ResultCode.PAY_ERROR);
} catch (Exception e) {
log.error("支付异常", e);
throw new ServiceException(ResultCode.PAY_ERROR);
@@ -514,48 +481,46 @@ public class WechatPlugin implements Payment {
}
}
- //获取微信设置
- WechatPaymentSetting wechatPaymentSetting = wechatPaymentSetting();
+
+
//获取用户openId
Connect connect = connectService.queryConnect(
ConnectQueryDTO.builder().userId(memberWithdrawApply.getMemberId())
.unionType(source).build()
);
- //构建提现,发起申请
- TransferModel transferModel = new TransferModel()
- .setAppid(withdrawalSetting.getWechatAppId())
- .setOut_batch_no(SnowFlake.createStr("T"))
- .setBatch_name("用户提现")
- .setBatch_remark("用户提现")
- .setTotal_amount(CurrencyUtil.fen(memberWithdrawApply.getApplyMoney()))
- .setTotal_num(1)
- .setTransfer_scene_id("1000");
+ //获取微信设置
+ WechatPaymentSetting setting = wechatPaymentSetting();
+
+ Config config =this.getConfig(setting);
+ // 构建service
+ TransferBatchService service = new TransferBatchService.Builder().config(config).build();
+
+ InitiateBatchTransferRequest request = new InitiateBatchTransferRequest();
+ request.setAppid(withdrawalSetting.getWechatAppId());
+ request.setOutBatchNo(SnowFlake.createStr("T"));
+ request.setBatchName("用户提现");
+ request.setBatchRemark("用户提现");
+ request.setTotalAmount(CurrencyUtil.getFenLong(memberWithdrawApply.getApplyMoney()));
+ request.setTotalNum(1);
+ request.setTransferSceneId("1000");
+
List transferDetailListList = new ArrayList<>();
{
TransferDetailInput transferDetailInput = new TransferDetailInput();
- transferDetailInput.setOut_detail_no(SnowFlake.createStr("TD"));
- transferDetailInput.setTransfer_amount(CurrencyUtil.fen(memberWithdrawApply.getApplyMoney()));
- transferDetailInput.setTransfer_remark("用户提现");
+ transferDetailInput.setOutDetailNo(SnowFlake.createStr("TD"));
+ transferDetailInput.setTransferAmount(CurrencyUtil.getFenLong(memberWithdrawApply.getApplyMoney()));
+ transferDetailInput.setTransferRemark("用户提现");
transferDetailInput.setOpenid(connect.getUnionId());
transferDetailListList.add(transferDetailInput);
}
- transferModel.setTransfer_detail_list(transferDetailListList);
+ request.setTransferDetailList(transferDetailListList);
- PaymentHttpResponse response = WechatApi.v3(
- RequestMethodEnums.POST,
- WechatDomain.CHINA.toString(),
- WechatApiEnum.TRANSFER_BATCHES.toString(),
- wechatPaymentSetting.getMchId(),
- wechatPaymentSetting.getSerialNumber(),
- null,
- wechatPaymentSetting.getApiclient_key(),
- JSONUtil.toJsonStr(transferModel)
- );
+ // 调用下单方法,得到应答
+ InitiateBatchTransferResponse response = service.initiateBatchTransfer(request);
log.info("微信提现响应 {}", response);
- String body = response.getBody();
- JSONObject jsonObject = JSONUtil.parseObj(body);
- return TransferResultDTO.builder().result(jsonObject.getStr("batch_id") != null).response(body).build();
+
+ return TransferResultDTO.builder().result(response.getBatchId()!= null).build();
//根据自身业务进行接下来的任务处理
} catch (Exception e) {
e.printStackTrace();
@@ -572,41 +537,51 @@ public class WechatPlugin implements Payment {
*/
private void verifyNotify(HttpServletRequest request) throws Exception {
- String timestamp = request.getHeader("Wechatpay-Timestamp");
- String nonce = request.getHeader("Wechatpay-Nonce");
- String serialNo = request.getHeader("Wechatpay-Serial");
- String signature = request.getHeader("Wechatpay-Signature");
-
- log.info("timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);
- String result = HttpKit.readData(request);
- log.info("微信支付通知密文 {}", result);
+ // 构造 RequestParam
+ RequestParam requestParam = new RequestParam.Builder()
+ .serialNumber(request.getHeader("Wechatpay-Serial"))
+ .nonce(request.getHeader("Wechatpay-Nonce"))
+ .signature(request.getHeader("Wechatpay-Signature"))
+ .timestamp(request.getHeader("Wechatpay-Timestamp"))
+ .body(HttpKit.readData(request))
+ .build();
WechatPaymentSetting setting = wechatPaymentSetting();
- //校验服务器端响应¬
- String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,
- setting.getApiKey3(), Objects.requireNonNull(getPlatformCert()));
- log.info("微信支付通知明文 {}", plainText);
-
- JSONObject jsonObject = JSONUtil.parseObj(plainText);
-
- String payParamStr = jsonObject.getStr("attach");
- String payParamJson = URLDecoder.decode(payParamStr, StandardCharsets.UTF_8);
- PayParam payParam = JSONUtil.toBean(payParamJson, PayParam.class);
+ NotificationConfig config = new RSAAutoCertificateConfig.Builder()
+ .merchantId(setting.getMchId())
+ .privateKey(setting.getApiclientKey())
+ .merchantSerialNumber(setting.getSerialNumber())
+ .apiV3Key(setting.getApiKey3())
+ .build();
- String tradeNo = jsonObject.getStr("transaction_id");
- Double totalAmount = CurrencyUtil.reversalFen(jsonObject.getJSONObject("amount").getDouble("total"));
+ // 初始化 NotificationParser
+ NotificationParser parser = new NotificationParser(config);
- PaymentSuccessParams paymentSuccessParams = new PaymentSuccessParams(
- PaymentMethodEnum.WECHAT.name(),
- tradeNo,
- totalAmount,
- payParam
- );
+ try {
+ // 以支付通知回调为例,验签、解密并转换成 Transaction
+ Transaction transaction = parser.parse(requestParam, Transaction.class);
+
+ String payParamJson = URLDecoder.decode(transaction.getAttach(), StandardCharsets.UTF_8);
+ PayParam payParam = JSONUtil.toBean(payParamJson, PayParam.class);
+
+ Double totalAmount = CurrencyUtil.reversalFen(transaction.getAmount().getTotal());
+
+ PaymentSuccessParams paymentSuccessParams = new PaymentSuccessParams(
+ PaymentMethodEnum.WECHAT.name(),
+ transaction.getTransactionId(),
+ totalAmount,
+ payParam
+ );
+
+ paymentService.success(paymentSuccessParams);
+ } catch (ValidationException e) {
+ // 签名验证失败,返回 401 UNAUTHORIZED 状态码
+ log.error("sign verification failed", e);
+
+ }
- paymentService.success(paymentSuccessParams);
- log.info("微信支付回调:支付成功{}", plainText);
}
@Override
@@ -614,39 +589,28 @@ public class WechatPlugin implements Payment {
try {
- Amount amount = new Amount().setRefund(CurrencyUtil.fen(refundLog.getTotalAmount()))
- .setTotal(CurrencyUtil.fen(orderService.getPaymentTotal(refundLog.getOrderSn())));
-
- //退款参数准备
- RefundModel refundModel = new RefundModel()
- .setTransaction_id(refundLog.getPaymentReceivableNo())
- .setOut_refund_no(refundLog.getOutOrderNo())
- .setReason(refundLog.getRefundReason())
- .setAmount(amount)
- .setNotify_url(refundNotifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT));
-
+ AmountReq amount = new AmountReq();
+ amount.setRefund(CurrencyUtil.getFenLong(refundLog.getTotalAmount()));
+ amount.setTotal(CurrencyUtil.getFenLong(orderService.getPaymentTotal(refundLog.getOrderSn())));
+ amount.setCurrency("CNY");
+ //获取微信设置
WechatPaymentSetting setting = wechatPaymentSetting();
- log.info("微信退款参数 {}", JSONUtil.toJsonStr(refundModel));
- PaymentHttpResponse response = WechatApi.v3(
- RequestMethodEnums.POST,
- WechatDomain.CHINA.toString(),
- WechatApiEnum.DOMESTIC_REFUNDS.toString(),
- setting.getMchId(),
- setting.getSerialNumber(),
- null,
- setting.getApiclient_key(),
- JSONUtil.toJsonStr(refundModel)
- );
- log.info("微信退款响应 {}", response);
- //退款申请成功
- if (response.getStatus() == 200) {
- refundLogService.save(refundLog);
- } else {
- //退款申请失败
- refundLog.setErrorMessage(response.getBody());
- refundLogService.save(refundLog);
- }
+ Config config =this.getConfig(setting);
+ // 构建service
+ RefundService refundService = new RefundService.Builder().config(config).build();
+
+ CreateRequest request = new CreateRequest();
+ request.setTransactionId(refundLog.getPaymentReceivableNo());
+ request.setAmount(amount);
+ request.setOutRefundNo(refundLog.getOutOrderNo());
+ request.setReason(refundLog.getRefundReason());
+ request.setNotifyUrl(refundNotifyUrl(wechatPaymentSetting().getCallbackUrl(), PaymentMethodEnum.WECHAT));
+
+ Refund refund=refundService.create(request);
+
+ log.info("微信退款响应 {}", refund);
+ refundLogService.save(refundLog);
} catch (Exception e) {
log.error("微信退款申请失败", e);
}
@@ -664,10 +628,10 @@ public class WechatPlugin implements Payment {
String result = HttpKit.readData(request);
log.info("微信退款通知密文 {}", result);
JSONObject ciphertext = JSONUtil.parseObj(result);
-
+ WechatPaymentSetting setting = wechatPaymentSetting();
try { //校验服务器端响应¬
String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,
- wechatPaymentSetting().getApiKey3(), Objects.requireNonNull(getPlatformCert()));
+ wechatPaymentSetting().getApiKey3(), Objects.requireNonNull(setting.getPublicKey()));
log.info("微信退款通知明文 {}", plainText);
if (("REFUND.SUCCESS").equals(ciphertext.getStr("event_type"))) {
@@ -721,78 +685,22 @@ public class WechatPlugin implements Payment {
}
/**
- * 获取平台公钥
- *
- * @return 平台公钥
+ * 获取微信支付配置
+ * @param setting
+ * @return
*/
- private X509Certificate getPlatformCert() {
- //获取缓存中的平台公钥,如果有则直接返回,否则去微信请求
- String publicCert = cache.getString(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix());
- if (!StringUtils.isEmpty(publicCert)) {
- return PayKit.getCertificate(publicCert);
- }
- //获取平台证书列表
- try {
-
- WechatPaymentSetting setting = wechatPaymentSetting();
-
- PaymentHttpResponse response = WechatApi.v3(
- RequestMethodEnums.GET,
- WechatDomain.CHINA.toString(),
- WechatApiEnum.GET_CERTIFICATES.toString(),
- setting.getMchId(),
- setting.getSerialNumber(),
- null,
- setting.getApiclient_key(),
- ""
- );
- String body = response.getBody();
- log.info("获取微信平台证书body: {}", body);
- if (response.getStatus() == 200) {
- JSONObject jsonObject = JSONUtil.parseObj(body);
- JSONArray dataArray = jsonObject.getJSONArray("data");
- //默认认为只有一个平台证书
- JSONObject encryptObject = dataArray.getJSONObject(0);
- JSONObject encryptCertificate = encryptObject.getJSONObject("encrypt_certificate");
- String associatedData = encryptCertificate.getStr("associated_data");
- String cipherText = encryptCertificate.getStr("ciphertext");
- String nonce = encryptCertificate.getStr("nonce");
- publicCert = getPlatformCertStr(associatedData, nonce, cipherText);
- long second = (PayKit.getCertificate(publicCert).getNotAfter().getTime() - System.currentTimeMillis()) / 1000;
- cache.put(CachePrefix.WECHAT_PLAT_FORM_CERT.getPrefix(), publicCert, second);
- } else {
- log.error("证书获取失败:{}" + body);
- throw new ServiceException(ResultCode.WECHAT_CERT_ERROR);
- }
- return PayKit.getCertificate(publicCert);
- } catch (Exception e) {
- log.error("证书获取失败", e);
- }
- return null;
+ private RSAPublicKeyConfig getConfig(WechatPaymentSetting setting){
+ return
+ new RSAPublicKeyConfig.Builder()
+ .merchantId(setting.getMchId())
+ .privateKey(setting.getApiclientKey())
+ .publicKey(setting.getPublicKey())
+ .publicKeyId(setting.getPublicId())
+ .merchantSerialNumber(setting.getSerialNumber())
+ .apiV3Key(setting.getApiKey3())
+ .build();
}
- /**
- * 获取平台证书缓存的字符串
- * 下列各个密钥参数
- *
- * @param associatedData 密钥参数
- * @param nonce 密钥参数
- * @param cipherText 密钥参数
- * @return platform key
- * @throws GeneralSecurityException 密钥获取异常
- */
- private String getPlatformCertStr(String associatedData, String nonce, String cipherText) throws GeneralSecurityException {
-
-
- AesUtil aesUtil = new AesUtil(wechatPaymentSetting().getApiKey3().getBytes(StandardCharsets.UTF_8));
- //平台证书密文解密
- //encrypt_certificate 中的 associated_data nonce ciphertext
- return aesUtil.decryptToString(
- associatedData.getBytes(StandardCharsets.UTF_8),
- nonce.getBytes(StandardCharsets.UTF_8),
- cipherText
- );
- }
/**
* 修改订单支付单号
diff --git a/framework/src/main/java/cn/lili/modules/system/entity/dto/payment/WechatPaymentSetting.java b/framework/src/main/java/cn/lili/modules/system/entity/dto/payment/WechatPaymentSetting.java
index b26efad0..3b40db2a 100644
--- a/framework/src/main/java/cn/lili/modules/system/entity/dto/payment/WechatPaymentSetting.java
+++ b/framework/src/main/java/cn/lili/modules/system/entity/dto/payment/WechatPaymentSetting.java
@@ -37,10 +37,22 @@ public class WechatPaymentSetting {
* 商户号
*/
private String mchId;
+ /**
+ * 商户证书序列号
+ */
+ private String serialNumber;
/**
* 私钥
*/
- private String apiclient_key;
+ private String apiclientKey;
+ /**
+ * 公钥ID
+ */
+ private String publicId;
+ /**
+ * 公钥
+ */
+ private String publicKey;
// /**
// * pem 证书
// */
@@ -49,10 +61,7 @@ public class WechatPaymentSetting {
// * p12 证书
// */
// private String apiclient_cert_p12;
- /**
- * 商户证书序列号
- */
- private String serialNumber;
+
/**
* apiv3私钥
*/