优化渠道 config 校验和逻辑转换问题

This commit is contained in:
aquan
2021-11-24 11:51:06 +08:00
parent dfde260ebb
commit 1c5544fc9d
15 changed files with 136 additions and 149 deletions

View File

@ -1,7 +1,11 @@
package cn.iocoder.yudao.framework.pay.core.client;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import javax.validation.Validator;
/**
* 支付客户端的配置,本质是支付渠道的配置
* 每个不同的渠道,需要不同的配置,通过子类来定义
@ -13,4 +17,10 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
// 1. 序列化到时数据库时,增加 @class 属性。
// 2. 反序列化到内存对象时,通过 @class 属性,可以创建出正确的类型
public interface PayClientConfig {
/**
* 验证配置参数是否正确
* @param validator 校验对象
*/
void verifyParam(Validator validator);
}

View File

@ -2,9 +2,17 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Set;
import java.util.stream.Collectors;
// TODO 芋艿:参数校验
@ -106,4 +114,18 @@ public class AlipayPayClientConfig implements PayClientConfig {
public interface ModeCertificate {
}
/**
* 验证配置参数是否正确
* @param validator 校验对象
*/
@Override
public void verifyParam(Validator validator) {
// 手动调用validate进行验证
Set<ConstraintViolation<AlipayPayClientConfig>> validate = validator.validate(this,
MODE_PUBLIC_KEY.equals(this.getMode()) ? ModePublicKey.class : ModeCertificate.class);
// 断言没有异常
Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
.collect(Collectors.joining(",")));
}
}

View File

@ -1,17 +1,26 @@
package cn.iocoder.yudao.framework.pay.core.client.impl.wx;
import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import com.alibaba.fastjson.JSON;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotBlank;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Set;
import java.util.stream.Collectors;
// TODO 芋艿:参数校验
// TODO @aquan: 不要全文件格式化哈,去掉下 <p> 看着不太友好哈
/**
* 微信支付的 PayClientConfig 实现类
* 属性主要来自 {@link com.github.binarywang.wxpay.config.WxPayConfig} 的必要属性
@ -24,13 +33,11 @@ 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";
@ -56,7 +63,7 @@ public class WXPayClientConfig implements PayClientConfig {
/**
* 商户密钥
*/
@NotBlank(message = "商户密钥 不能为空", groups = {V2.class})
@NotBlank(message = "商户密钥 不能为空", groups = V2.class)
private String mchKey;
/**
* apiclient_cert.p12 证书文件的绝对路径或者以 classpath: 开头的类路径.
@ -70,11 +77,9 @@ public class WXPayClientConfig implements PayClientConfig {
/**
* apiclient_key.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
* 对应的字符串
* <p>
* 注意,可通过 {@link #main(String[])} 读取
*/
// TODO @aquan对于只有一个值的时候直接 groups = V3.class 即可,简洁。例如说,我们在 Spring MVC 注解url 可以多个,也只写单个,一个道理哈
@NotBlank(message = "apiclient_key 不能为空", groups = {V3.class})
@NotBlank(message = "apiclient_key 不能为空", groups = V3.class)
private String privateKeyContent;
/**
* apiclient_cert.pem 证书文件的绝对路径或者以 classpath: 开头的类路径.
@ -82,21 +87,14 @@ public class WXPayClientConfig implements PayClientConfig {
* <p>
* 注意,可通过 {@link #main(String[])} 读取
*/
@NotBlank(message = "apiclient_cert 不能为空", groups = {V3.class})
@NotBlank(message = "apiclient_cert 不能为空", groups = V3.class)
private String privateCertContent;
/**
* apiV3 秘钥值
*/
@NotBlank(message = "apiV3 秘钥值 不能为空", groups = {V3.class})
@NotBlank(message = "apiV3 秘钥值 不能为空", groups = V3.class)
private String apiV3Key;
public static void main(String[] args) throws FileNotFoundException {
String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.p12";
// String path = "/Users/yunai/Downloads/wx_pay/apiclient_key.pem";
// String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.pem";
System.out.println(IoUtil.readUtf8(new FileInputStream(path)));
}
/**
* 分组校验 v2版本
@ -110,4 +108,26 @@ public class WXPayClientConfig implements PayClientConfig {
public interface V3 {
}
/**
* 验证配置参数是否正确
* @param validator 校验对象
*/
@Override
public void verifyParam(Validator validator) {
// 手动调用validate进行验证
Set<ConstraintViolation<PayClientConfig>> validate = validator.validate(this,
this.getApiVersion().equals(API_VERSION_V2) ? V2.class : V3.class);
// 断言没有异常
Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
.collect(Collectors.joining(",")));
}
public static void main(String[] args) throws FileNotFoundException {
String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.p12";
/// String path = "/Users/yunai/Downloads/wx_pay/apiclient_key.pem";
/// String path = "/Users/yunai/Downloads/wx_pay/apiclient_cert.pem";
System.out.println(IoUtil.readUtf8(new FileInputStream(path)));
}
}

View File

@ -1,6 +1,9 @@
package cn.iocoder.yudao.framework.pay.core.enums;
import cn.hutool.core.util.ArrayUtil;
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
import lombok.AllArgsConstructor;
import lombok.Getter;
@ -49,21 +52,21 @@ public enum PayChannelEnum {
}
/**
* 判断当前渠道是那种支付方式
* @param code
* @return
* 根据编码得到支付类
* @param code 编码
* @return 支付配置类
*/
public static String verifyWechatOrAliPay(String code){
public static Class<? extends PayClientConfig> findByCodeGetClass(String code){
switch (PayChannelEnum.getByCode(code)){
case WX_PUB:
case WX_LITE:
case WX_APP:
return WECHAT;
return WXPayClientConfig.class;
case ALIPAY_PC:
case ALIPAY_WAP:
case ALIPAY_APP:
case ALIPAY_QR:
return ALIPAY;
return AlipayPayClientConfig.class;
}
return null;
}