mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-19 11:40:05 +08:00
优化渠道 config 校验和逻辑转换问题
This commit is contained in:
parent
dfde260ebb
commit
1c5544fc9d
@ -80,7 +80,7 @@ public class PayMerchantController {
|
||||
@ApiImplicitParam(name = "name", value = "商户名称", required = true, example = "芋道", dataTypeClass = Long.class)
|
||||
@PreAuthorize("@ss.hasPermission('pay:merchant:query')")
|
||||
public CommonResult<List<PayMerchantRespVO>> getMerchantListByName(@RequestParam("name") String name) {
|
||||
List<PayMerchantDO> merchantListDO = merchantService.getMerchantListByNameLimit(name);
|
||||
List<PayMerchantDO> merchantListDO = merchantService.getMerchantListByName(name);
|
||||
return success(PayMerchantConvert.INSTANCE.convertList(merchantListDO));
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerch
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@ -48,8 +49,6 @@ public interface PayMerchantMapper extends BaseMapperX<PayMerchantDO> {
|
||||
* @return 商户集合
|
||||
*/
|
||||
default List<PayMerchantDO> getMerchantListByName(String merchantName) {
|
||||
// TODO @aquan:全模糊匹配,暂时不考虑索引的事;另外,可以直接 new Lambada 的 QueryWrapper 实现类呀
|
||||
return this.selectList(new QueryWrapper<PayMerchantDO>()
|
||||
.lambda().likeRight(PayMerchantDO::getName, merchantName));
|
||||
return this.selectList(new LambdaQueryWrapper<PayMerchantDO>().like(PayMerchantDO::getName, merchantName));
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.APP_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
|
||||
@ -72,7 +72,7 @@ public class PayAppServiceImpl implements PayAppService {
|
||||
|
||||
private void validateAppExists(Long id) {
|
||||
if (appMapper.selectById(id) == null) {
|
||||
throw exception(APP_NOT_EXISTS);
|
||||
throw exception(PAY_APP_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ public class PayAppServiceImpl implements PayAppService {
|
||||
}
|
||||
PayAppDO payApp = appMapper.selectById(id);
|
||||
if (payApp == null) {
|
||||
throw exception(APP_NOT_EXISTS);
|
||||
throw exception(PAY_APP_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.service.channel.impl;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelCreateReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelExportReqVO;
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.controller.channel.vo.PayChannelPageReqVO;
|
||||
@ -9,24 +10,20 @@ import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.channel.PayChannelMapp
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.channel.PayChannelService;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.ValidatorFactory;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
@ -44,14 +41,15 @@ public class PayChannelServiceImpl implements PayChannelService {
|
||||
@Resource
|
||||
private PayChannelMapper channelMapper;
|
||||
|
||||
@Resource
|
||||
private Validator validator;
|
||||
|
||||
@Override
|
||||
public Long createChannel(PayChannelCreateReqVO reqVO) {
|
||||
// TODO @aquan:感觉获得那一条比较合适。因为是有唯一性的。注释有错别字哈。
|
||||
// 判断是否有重复的有责无法新增
|
||||
Integer channelCount = this.getChannelCountByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode());
|
||||
if (channelCount > 0) {
|
||||
throw exception(CHANNEL_EXIST_SAME_CHANNEL_ERROR);
|
||||
}
|
||||
|
||||
// 断言是否有重复的
|
||||
PayChannelDO channelDO = this.getChannelByConditions(reqVO.getMerchantId(), reqVO.getAppId(), reqVO.getCode());
|
||||
Assert.isNull(channelDO, CHANNEL_EXIST_SAME_CHANNEL_ERROR.getMsg());
|
||||
|
||||
// 新增渠道
|
||||
PayChannelDO channel = PayChannelConvert.INSTANCE.convert(reqVO);
|
||||
@ -142,24 +140,6 @@ public class PayChannelServiceImpl implements PayChannelService {
|
||||
return this.channelMapper.getChannelByConditions(merchantId, appid, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测微信秘钥参数
|
||||
*
|
||||
* @param config 信秘钥参数
|
||||
*/
|
||||
private void wechatParamCheck(WXPayClientConfig config) {
|
||||
// 针对于 V2 或者 V3 版本的参数校验
|
||||
if (WXPayClientConfig.API_VERSION_V2.equals(config.getApiVersion())) {
|
||||
Assert.notNull(config.getMchKey(), CHANNEL_WECHAT_VERSION_2_MCH_KEY_IS_NULL.getMsg());
|
||||
}
|
||||
if (WXPayClientConfig.API_VERSION_V3.equals(config.getApiVersion())) {
|
||||
Assert.notNull(config.getPrivateKeyContent(), CHANNEL_WECHAT_VERSION_3_PRIVATE_KEY_IS_NULL.getMsg());
|
||||
Assert.notNull(config.getPrivateCertContent(), CHANNEL_WECHAT_VERSION_3_CERT_KEY_IS_NULL.getMsg());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 设置渠道配置以及参数校验
|
||||
*
|
||||
@ -168,48 +148,11 @@ public class PayChannelServiceImpl implements PayChannelService {
|
||||
*/
|
||||
private void settingConfigAndCheckParam(PayChannelDO channel, String configStr) {
|
||||
// 得到这个渠道是微信的还是支付宝的
|
||||
String channelType = PayChannelEnum.verifyWechatOrAliPay(channel.getCode());
|
||||
Assert.notNull(channelType, CHANNEL_NOT_EXISTS.getMsg());
|
||||
|
||||
// 进行验证
|
||||
// TODO @阿全:Spring 可以注入 Validator 哈
|
||||
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
|
||||
Validator validator = validatorFactory.getValidator();
|
||||
|
||||
// 微信的验证
|
||||
// TODO @aquan:这么实现,可扩性不好。@AssertTrue 注解。
|
||||
if (PayChannelEnum.WECHAT.equals(channelType)) {
|
||||
|
||||
WXPayClientConfig config = JSON.parseObject(configStr, WXPayClientConfig.class);
|
||||
// 判断是V2 版本还是 V3 版本
|
||||
Class clazz = config.getApiVersion().equals(WXPayClientConfig.API_VERSION_V2)
|
||||
? WXPayClientConfig.V2.class : WXPayClientConfig.V3.class;
|
||||
// 手动调用validate进行验证
|
||||
Set<ConstraintViolation<WXPayClientConfig>> validate = validator.validate(config,clazz);
|
||||
|
||||
// 断言没有异常
|
||||
Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
|
||||
.collect(Collectors.joining(",")));
|
||||
|
||||
channel.setConfig(config);
|
||||
}
|
||||
|
||||
// 支付宝验证
|
||||
if (PayChannelEnum.ALIPAY.equals(channelType)) {
|
||||
|
||||
AlipayPayClientConfig config = JSON.parseObject(configStr, AlipayPayClientConfig.class);
|
||||
|
||||
// 判断是V2 版本还是 V3 版本
|
||||
Class clazz = config.getMode().equals(AlipayPayClientConfig.MODE_PUBLIC_KEY)
|
||||
? AlipayPayClientConfig.ModePublicKey.class : AlipayPayClientConfig.ModeCertificate.class;
|
||||
// 手动调用validate进行验证
|
||||
Set<ConstraintViolation<AlipayPayClientConfig>> validate = validator.validate(config,clazz);
|
||||
|
||||
// 断言没有异常
|
||||
Assert.isTrue(validate.isEmpty(), validate.stream().map(ConstraintViolation::getMessage)
|
||||
.collect(Collectors.joining(",")));
|
||||
channel.setConfig(config);
|
||||
}
|
||||
|
||||
Class<? extends PayClientConfig> payClass = PayChannelEnum.findByCodeGetClass(channel.getCode());
|
||||
Assert.notNull(payClass, CHANNEL_NOT_EXISTS.getMsg());
|
||||
PayClientConfig config = JSONUtil.toBean(configStr, payClass);
|
||||
// 验证参数
|
||||
config.verifyParam(validator);
|
||||
channel.setConfig(config);
|
||||
}
|
||||
}
|
||||
|
@ -92,14 +92,6 @@ public interface PayMerchantService {
|
||||
*/
|
||||
List<PayMerchantDO> getMerchantListByName(String merchantName);
|
||||
|
||||
// TODO aquan:暂时不用提供这样的检索。商户不多的。
|
||||
/**
|
||||
* 根据商户名称模糊查询一定数量的商户集合
|
||||
* @param merchantName 商户名称
|
||||
* @return 商户集合
|
||||
*/
|
||||
List<PayMerchantDO> getMerchantListByNameLimit(String merchantName);
|
||||
|
||||
/**
|
||||
* 获得指定编号的商户 Map
|
||||
*
|
||||
|
@ -10,8 +10,6 @@ import cn.iocoder.yudao.adminserver.modules.pay.dal.mysql.merchant.PayMerchantMa
|
||||
import cn.iocoder.yudao.adminserver.modules.pay.service.merchant.PayMerchantService;
|
||||
import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -21,7 +19,7 @@ import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.MERCHANT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
/**
|
||||
* 支付商户信息 Service 实现类
|
||||
@ -64,7 +62,7 @@ public class PayMerchantServiceImpl implements PayMerchantService {
|
||||
|
||||
private void validateMerchantExists(Long id) {
|
||||
if (merchantMapper.selectById(id) == null) {
|
||||
throw exception(MERCHANT_NOT_EXISTS);
|
||||
throw exception(PAY_MERCHANT_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -116,22 +114,6 @@ public class PayMerchantServiceImpl implements PayMerchantService {
|
||||
return this.merchantMapper.getMerchantListByName(merchantName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据商户名称模糊查询一定数量的商户集合
|
||||
*
|
||||
* @param merchantName 商户名称
|
||||
* @return 商户集合
|
||||
*/
|
||||
@Override
|
||||
public List<PayMerchantDO> getMerchantListByNameLimit(String merchantName) {
|
||||
// TODO @aquan:mybatis plus 哈
|
||||
LambdaQueryWrapper<PayMerchantDO> queryWrapper = new QueryWrapper<PayMerchantDO>().lambda()
|
||||
.select(PayMerchantDO::getId, PayMerchantDO::getName)
|
||||
.likeRight(PayMerchantDO::getName, merchantName)
|
||||
.last("limit 200");
|
||||
|
||||
return this.merchantMapper.selectList(queryWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查商户是否存在
|
||||
@ -144,7 +126,7 @@ public class PayMerchantServiceImpl implements PayMerchantService {
|
||||
}
|
||||
PayMerchantDO merchant = merchantMapper.selectById(id);
|
||||
if (merchant == null) {
|
||||
throw exception(MERCHANT_NOT_EXISTS);
|
||||
throw exception(PAY_MERCHANT_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ public class PayAppServiceTest extends BaseDbUnitTest {
|
||||
PayAppUpdateReqVO reqVO = randomPojo(PayAppUpdateReqVO.class, o ->
|
||||
o.setStatus((RandomUtil.randomEle(CommonStatusEnum.values()).getStatus())));
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> appService.updateApp(reqVO), APP_NOT_EXISTS);
|
||||
assertServiceException(() -> appService.updateApp(reqVO), PAY_APP_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -116,7 +116,7 @@ public class PayAppServiceTest extends BaseDbUnitTest {
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> appService.deleteApp(id), APP_NOT_EXISTS);
|
||||
assertServiceException(() -> appService.deleteApp(id), PAY_APP_NOT_FOUND);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -0,0 +1,20 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.pay.service.channel;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
|
||||
/**
|
||||
* 用于初始化 validator Bean 对象
|
||||
* @author aquan
|
||||
*/
|
||||
@Configuration
|
||||
public class PayChannelConfig {
|
||||
|
||||
@Bean
|
||||
public Validator validator(){
|
||||
return Validation.buildDefaultValidatorFactory().getValidator();
|
||||
}
|
||||
}
|
@ -34,7 +34,10 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
*
|
||||
* @author 芋艿
|
||||
*/
|
||||
@Import(PayChannelServiceImpl.class)
|
||||
@Import({
|
||||
PayChannelServiceImpl.class,
|
||||
PayChannelConfig.class
|
||||
})
|
||||
public class PayChannelServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
@ -43,7 +46,6 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
|
||||
@Resource
|
||||
private PayChannelMapper channelMapper;
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateWechatVersion2Channel_success() {
|
||||
// 准备参数
|
||||
@ -69,8 +71,7 @@ public class PayChannelServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Test
|
||||
public void testCreateWechatVersion3Channel_success() {
|
||||
// 准备参数 TODO @aquan:多余的空行去掉哈。例如说 74 行。
|
||||
|
||||
// 准备参数
|
||||
WXPayClientConfig v3Config = getV3Config();
|
||||
PayChannelCreateReqVO reqVO = randomPojo(PayChannelCreateReqVO.class, o -> {
|
||||
o.setCode(PayChannelEnum.WX_PUB.getCode());
|
||||
|
@ -18,7 +18,7 @@ import org.springframework.context.annotation.Import;
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.MERCHANT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.PAY_MERCHANT_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.buildTime;
|
||||
@ -79,7 +79,7 @@ public class PayMerchantServiceTest extends BaseDbUnitTest {
|
||||
PayMerchantUpdateReqVO reqVO = randomPojo(PayMerchantUpdateReqVO.class);
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> merchantService.updateMerchant(reqVO), MERCHANT_NOT_EXISTS);
|
||||
assertServiceException(() -> merchantService.updateMerchant(reqVO), PAY_MERCHANT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -103,7 +103,7 @@ public class PayMerchantServiceTest extends BaseDbUnitTest {
|
||||
Long id = randomLongId();
|
||||
|
||||
// 调用, 并断言异常
|
||||
assertServiceException(() -> merchantService.deleteMerchant(id), MERCHANT_NOT_EXISTS);
|
||||
assertServiceException(() -> merchantService.deleteMerchant(id), PAY_MERCHANT_NOT_EXISTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -22,7 +22,6 @@ public interface PayErrorCodeCoreConstants {
|
||||
ErrorCode PAY_CHANNEL_IS_DISABLE = new ErrorCode(1007001001, "支付渠道已经禁用");
|
||||
ErrorCode PAY_CHANNEL_CLIENT_NOT_FOUND = new ErrorCode(1007001002, "支付渠道的客户端不存在");
|
||||
ErrorCode CHANNEL_NOT_EXISTS = new ErrorCode(1007001003, "支付渠道不存在");
|
||||
ErrorCode CHANNEL_KEY_READ_ERROR = new ErrorCode(1007001004, "支付渠道秘钥文件读取失败");
|
||||
ErrorCode CHANNEL_EXIST_SAME_CHANNEL_ERROR = new ErrorCode(1007001005, "已存在相同的渠道");
|
||||
ErrorCode CHANNEL_WECHAT_VERSION_2_MCH_KEY_IS_NULL = new ErrorCode(1007001006,"微信渠道v2版本中商户密钥不可为空");
|
||||
ErrorCode CHANNEL_WECHAT_VERSION_3_PRIVATE_KEY_IS_NULL = new ErrorCode(1007001006,"微信渠道v3版本apiclient_key.pem不可为空");
|
||||
@ -49,18 +48,14 @@ public interface PayErrorCodeCoreConstants {
|
||||
ErrorCode PAY_REFUND_CHN_ORDER_NO_IS_NULL = new ErrorCode(1007006002, "该订单的渠道订单为空");
|
||||
ErrorCode PAY_REFUND_POST_HANDLER_NOT_FOUND = new ErrorCode(1007006003, "未找到对应的退款后置处理类");
|
||||
ErrorCode PAY_REFUND_NOT_FOUND = new ErrorCode(1007006004, "支付退款单不存在");
|
||||
// TODO @aquan:下面还两个要合并上去哈。另外一般中英文之间要有空格。例如说, 新建一个 order 数据;这样可读性更好。
|
||||
|
||||
/**
|
||||
* ========== 支付商户信息 1-007-004-000 ==========
|
||||
*/
|
||||
ErrorCode MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在");
|
||||
ErrorCode PAY_MERCHANT_NOT_EXISTS = new ErrorCode(1007004000, "支付商户信息不存在");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ========== 支付应用信息 1-007-005-000 ==========
|
||||
*/
|
||||
ErrorCode APP_NOT_EXISTS = new ErrorCode(1007005000, "支付应用信息不存在");
|
||||
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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(",")));
|
||||
}
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user