mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-23 23:45:08 +08:00
优化完善支付应用和支付渠道代码逻辑,完善单元测试,基于validator完成手动校验config
This commit is contained in:
@ -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);
|
||||
|
@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user