优化完善支付应用和支付渠道代码逻辑,完善单元测试,基于validator完成手动校验config

This commit is contained in:
aquan
2021-11-21 19:31:20 +08:00
parent b18cd457c8
commit 6069a387ea
37 changed files with 1623 additions and 1021 deletions

View File

@ -65,6 +65,8 @@ public class PayClientFactoryImpl implements PayClientFactory {
case WX_APP: return (AbstractPayClient<Config>) new WXPubPayClient(channelId, (WXPayClientConfig) config);
case ALIPAY_WAP: return (AbstractPayClient<Config>) new AlipayWapPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_QR: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_APP: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config);
case ALIPAY_PC: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config);
}
// 创建失败,错误日志 + 抛出异常
log.error("[createSmsClient][配置({}) 找不到合适的客户端实现]", config);

View File

@ -3,7 +3,11 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
// TODO 芋艿:参数校验
/**
* 支付宝的 PayClientConfig 实现类
* 属性主要来自 {@link com.alipay.api.AlipayConfig} 的必要属性
@ -25,11 +29,11 @@ public class AlipayPayClientConfig implements PayClientConfig {
/**
* 公钥类型 - 公钥模式
*/
private static final Integer MODE_PUBLIC_KEY = 1;
public static final Integer MODE_PUBLIC_KEY = 1;
/**
* 公钥类型 - 证书模式
*/
private static final Integer MODE_CERTIFICATE = 2;
public static final Integer MODE_CERTIFICATE = 2;
/**
* 签名算法类型 - RSA
@ -41,18 +45,21 @@ public class AlipayPayClientConfig implements PayClientConfig {
* 1. {@link #SERVER_URL_PROD}
* 2. {@link #SERVER_URL_SANDBOX}
*/
@NotBlank(message = "网关地址不能为空", groups = {ModePublicKey.class, ModeCertificate.class})
private String serverUrl;
/**
* 开放平台上创建的应用的 ID
*/
@NotBlank(message = "开放平台上创建的应用的 ID不能为空", groups = {ModePublicKey.class, ModeCertificate.class})
private String appId;
/**
* 签名算法类型推荐RSA2
*
* <p>
* {@link #SIGN_TYPE_DEFAULT}
*/
@NotBlank(message = "签名算法类型不能为空", groups = {ModePublicKey.class, ModeCertificate.class})
private String signType;
/**
@ -60,30 +67,43 @@ public class AlipayPayClientConfig implements PayClientConfig {
* 1. {@link #MODE_PUBLIC_KEY} 情况privateKey + alipayPublicKey
* 2. {@link #MODE_CERTIFICATE} 情况appCertContent + alipayPublicCertContent + rootCertContent
*/
@NotNull(message = "公钥类型不能为空", groups = {ModePublicKey.class, ModeCertificate.class})
private Integer mode;
// ========== 公钥模式 ==========
/**
* 商户私钥
*/
@NotBlank(message = "商户私钥不能为空", groups = {ModePublicKey.class})
private String privateKey;
/**
* 支付宝公钥字符串
*/
@NotBlank(message = "支付宝公钥字符串不能为空", groups = {ModePublicKey.class})
private String alipayPublicKey;
// ========== 证书模式 ==========
/**
* 指定商户公钥应用证书内容字符串
*/
@NotBlank(message = "指定商户公钥应用证书内容不能为空", groups = {ModeCertificate.class})
private String appCertContent;
/**
* 指定支付宝公钥证书内容字符串
*/
@NotBlank(message = "指定支付宝公钥证书内容不能为空", groups = {ModeCertificate.class})
private String alipayPublicCertContent;
/**
* 指定根证书内容字符串
*/
@NotBlank(message = "指定根证书内容字符串不能为空", groups = {ModeCertificate.class})
private String rootCertContent;
public interface ModePublicKey {
}
public interface ModeCertificate {
}
}

View File

@ -4,10 +4,12 @@ import cn.hutool.core.io.IoUtil;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
// TODO 芋艿:参数校验
/**
* 微信支付的 PayClientConfig 实现类
* 属性主要来自 {@link com.github.binarywang.wxpay.config.WxPayConfig} 的必要属性
@ -20,13 +22,13 @@ public class WXPayClientConfig implements PayClientConfig {
// TODO 芋艿V2 or V3 客户端
/**
* API 版本 - V2
*
* <p>
* https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_1
*/
public static final String API_VERSION_V2 = "v2";
/**
* API 版本 - V3
*
* <p>
* https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml
*/
public static final String API_VERSION_V3 = "v3";
@ -34,14 +36,17 @@ public class WXPayClientConfig implements PayClientConfig {
/**
* 公众号或者小程序的 appid
*/
@NotBlank(message = "APPID 不能为空", groups = {V2.class, V3.class})
private String appId;
/**
* 商户号
*/
@NotBlank(message = "商户号 不能为空", groups = {V2.class, V3.class})
private String mchId;
/**
* API 版本
*/
@NotBlank(message = "API 版本 不能为空", groups = {V2.class, V3.class})
private String apiVersion;
// ========== V2 版本的参数 ==========
@ -49,33 +54,37 @@ public class WXPayClientConfig implements PayClientConfig {
/**
* 商户密钥
*/
@NotBlank(message = "商户密钥 不能为空", groups = {V2.class})
private String mchKey;
// /**
// * apiclient_cert.p12 证书文件的绝对路径或者以 classpath: 开头的类路径.
// * 对应的字符串
// *
// * 注意,可通过 {@link #main(String[])} 读取
// */
// private String keyContent;
/**
* apiclient_cert.p12 证书文件的绝对路径或者以 classpath: 开头的类路径.
* 对应的字符串
*
* 注意,可通过 {@link #main(String[])} 读取
*/
/// private String keyContent;
// ========== V3 版本的参数 ==========
/**
* apiclient_key.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
* 对应的字符串
*
* <p>
* 注意,可通过 {@link #main(String[])} 读取
*/
@NotBlank(message = "apiclient_key 不能为空", groups = {V3.class})
private String privateKeyContent;
/**
* apiclient_cert.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
* 对应的字符串
*
* <p>
* 注意,可通过 {@link #main(String[])} 读取
*/
@NotBlank(message = "apiclient_cert 不能为空", groups = {V3.class})
private String privateCertContent;
/**
* apiV3 秘钥值
*/
@NotBlank(message = "apiV3 秘钥值 不能为空", groups = {V3.class})
private String apiV3Key;
public static void main(String[] args) throws FileNotFoundException {
@ -85,4 +94,17 @@ public class WXPayClientConfig implements PayClientConfig {
System.out.println(IoUtil.readUtf8(new FileInputStream(path)));
}
/**
* 分组校验 v2版本
*/
public interface V2 {
}
/**
* 分组校验 v3版本
*/
public interface V3 {
}
}

View File

@ -15,8 +15,6 @@ import lombok.Getter;
public enum PayChannelEnum {
WX_PUB("wx_pub", "微信 JSAPI 支付"), // 公众号的网页
// TODO @芋艿 这个地方你写的是 wx_lit 是不是少写了一个e 还是我这里多加了一个e
// TODO @aquan这里就是 lite 哈,轻量
WX_LITE("wx_lite","微信小程序支付"),
WX_APP("wx_app", "微信 App 支付"),
@ -36,8 +34,38 @@ public enum PayChannelEnum {
*/
private String name;
/**
* 微信支付
*/
public static final String WECHAT = "WECHAT";
/**
* 支付宝支付
*/
public static final String ALIPAY = "ALIPAY";
public static PayChannelEnum getByCode(String code) {
return ArrayUtil.firstMatch(o -> o.getCode().equals(code), values());
}
/**
* 判断当前渠道是那种支付方式
* @param code
* @return
*/
public static String verifyWechatOrAliPay(String code){
switch (PayChannelEnum.getByCode(code)){
case WX_PUB:
case WX_LITE:
case WX_APP:
return WECHAT;
case ALIPAY_PC:
case ALIPAY_WAP:
case ALIPAY_APP:
case ALIPAY_QR:
return ALIPAY;
}
return null;
}
}