perf 支付通道支持启停用功能

This commit is contained in:
DaxPay
2024-10-09 17:30:39 +08:00
parent b2cda61f02
commit 389665de70
19 changed files with 67 additions and 65 deletions

View File

@@ -3,9 +3,9 @@
- 优化: - 优化:
- [x] 增加延时队列的可视页面 - [x] 增加延时队列的可视页面
- [ ] 增加首页驾驶舱功能 - [ ] 增加首页驾驶舱功能
- [ ] 定时同步任务频次不要太高, 预防产生过多的数据
- [x] 转账接收方类型优化 - [x] 转账接收方类型优化
- [x] 支付/退款/转账商户订单号查询时根据AppId做隔离 - [x] 支付/退款/转账商户订单号查询时根据AppId做隔离
- [x] 支付通道支持启停用功能
- [ ] 云闪付支付通道对接 - [ ] 云闪付支付通道对接
- [ ] 分账功能 - [ ] 分账功能
- [x] 分账接收方配置 - [x] 分账接收方配置
@@ -15,3 +15,8 @@
- [ ] 网关配套移动端开发 - [ ] 网关配套移动端开发
- [x] OpenId获取页 - [x] OpenId获取页
- [ ] 同步回调页 - [ ] 同步回调页
## 任务池
- [ ] 商户应用应该要有一个类似删除的功能, 实现停用冻结, 但不影响数据的关联
- [ ] 商户应用增加启停用状态
- [ ] 定时同步任务频次不要太高, 预防产生过多的数据

View File

@@ -17,6 +17,7 @@ import org.dromara.daxpay.channel.alipay.entity.config.AliPayConfig;
import org.dromara.daxpay.channel.alipay.param.config.AliPayConfigParam; import org.dromara.daxpay.channel.alipay.param.config.AliPayConfigParam;
import org.dromara.daxpay.channel.alipay.result.config.AlipayConfigResult; import org.dromara.daxpay.channel.alipay.result.config.AlipayConfigResult;
import org.dromara.daxpay.core.enums.ChannelEnum; import org.dromara.daxpay.core.enums.ChannelEnum;
import org.dromara.daxpay.core.exception.ChannelNotEnableException;
import org.dromara.daxpay.core.exception.ConfigNotEnableException; import org.dromara.daxpay.core.exception.ConfigNotEnableException;
import org.dromara.daxpay.core.exception.DataErrorException; import org.dromara.daxpay.core.exception.DataErrorException;
import org.dromara.daxpay.service.common.cache.ChannelConfigCacheService; import org.dromara.daxpay.service.common.cache.ChannelConfigCacheService;
@@ -104,13 +105,22 @@ public class AliPayConfigService {
return AliPayConfig.convertConfig(channelConfig); return AliPayConfig.convertConfig(channelConfig);
} }
/**
* 获取并检查支付配置
*/
public AliPayConfig getAndCheckConfig() {
var payConfig = this.getAliPayConfig();
if (!payConfig.getEnable()){
throw new ChannelNotEnableException("支付宝支付通道未启用");
}
return payConfig;
}
/** /**
* 获取支付宝SDK的配置 * 获取支付宝SDK的配置
*/ */
public AlipayClient getAlipayClient(){ public AlipayClient getAlipayClient(){
MchAppLocal mchAppInfo = PaymentContextLocal.get().getMchAppInfo(); AliPayConfig aliPayConfig = this.getAndCheckConfig();
ChannelConfig channelConfig = channelConfigCacheService.get(mchAppInfo.getAppId(), ChannelEnum.ALI.getCode());
AliPayConfig aliPayConfig = AliPayConfig.convertConfig(channelConfig);
return this.getAlipayClient(aliPayConfig); return this.getAlipayClient(aliPayConfig);
} }

View File

@@ -1,13 +1,10 @@
package org.dromara.daxpay.channel.wechat.bo.reconcile; package org.dromara.daxpay.channel.wechat.entity.reconcile;
import cn.hutool.core.annotation.Alias; import cn.hutool.core.annotation.Alias;
import cn.hutool.core.util.StrUtil;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Field;
/** /**
* 微信交易对账解析文件 * 微信交易对账解析文件
* @author xxm * @author xxm
@@ -129,23 +126,4 @@ public class WechatReconcileBillDetail {
@Alias("费率备注") @Alias("费率备注")
private String feeRemark; private String feeRemark;
/**
* 去除前缀的 ` 符号
*/
public void removeStartSymbol() {
Field[] fields = this.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.getType() == String.class) {
field.setAccessible(true);
try {
String value = (String) field.get(this);
if (StrUtil.startWith(value, "`")) {
field.set(this, StrUtil.replaceFirst(value, "`", ""));
}
} catch (IllegalAccessException e) {
log.warn("去除前缀错误错误", e);
}
}
}
}
} }

View File

@@ -69,7 +69,7 @@ public class WechatAuthService {
* 获取微信公众号API的Service * 获取微信公众号API的Service
*/ */
private WxMpService getWxMpService() { private WxMpService getWxMpService() {
WechatPayConfig config = wechatPayConfigService.getWechatPayConfig(); WechatPayConfig config = wechatPayConfigService.getAndCheckConfig();
WxMpService wxMpService = new WxMpServiceImpl(); WxMpService wxMpService = new WxMpServiceImpl();
WxMpDefaultConfigImpl wxMpConfig = new WxMpDefaultConfigImpl(); WxMpDefaultConfigImpl wxMpConfig = new WxMpDefaultConfigImpl();
wxMpConfig.setAppId(config.getWxAppId()); // 设置微信公众号的appid wxMpConfig.setAppId(config.getWxAppId()); // 设置微信公众号的appid

View File

@@ -69,7 +69,7 @@ public class WechatPayCallbackService {
// 设置类型和通道 // 设置类型和通道
callbackInfo.setCallbackType(TradeTypeEnum.PAY).setChannel(ChannelEnum.WECHAT.getCode()); callbackInfo.setCallbackType(TradeTypeEnum.PAY).setChannel(ChannelEnum.WECHAT.getCode());
WechatPayConfig config = wechatPayConfigService.getWechatPayConfig(); WechatPayConfig config = wechatPayConfigService.getAndCheckConfig();
WxPayService wxPayService = wechatPayConfigService.wxJavaSdk(config); WxPayService wxPayService = wechatPayConfigService.wxJavaSdk(config);
// v2 或 v3 // v2 或 v3
if (Objects.equals(config.getApiVersion(), WechatPayCode.API_V2)) { if (Objects.equals(config.getApiVersion(), WechatPayCode.API_V2)) {

View File

@@ -71,7 +71,7 @@ public class WechatRefundCallbackService {
// 设置类型和通道 // 设置类型和通道
callbackInfo.setCallbackType(TradeTypeEnum.REFUND).setChannel(ChannelEnum.WECHAT.getCode()); callbackInfo.setCallbackType(TradeTypeEnum.REFUND).setChannel(ChannelEnum.WECHAT.getCode());
WechatPayConfig config = wechatPayConfigService.getWechatPayConfig(); WechatPayConfig config = wechatPayConfigService.getAndCheckConfig();
WxPayService wxPayService = wechatPayConfigService.wxJavaSdk(config); WxPayService wxPayService = wechatPayConfigService.wxJavaSdk(config);
// v2 或 v3 // v2 或 v3
if (Objects.equals(config.getApiVersion(), WechatPayCode.API_V2)) { if (Objects.equals(config.getApiVersion(), WechatPayCode.API_V2)) {

View File

@@ -66,7 +66,7 @@ public class WechatTransferCallbackService {
CallbackLocal callbackInfo = PaymentContextLocal.get().getCallbackInfo(); CallbackLocal callbackInfo = PaymentContextLocal.get().getCallbackInfo();
callbackInfo.setChannel(ChannelEnum.WECHAT.getCode()) callbackInfo.setChannel(ChannelEnum.WECHAT.getCode())
.setCallbackType(TradeTypeEnum.TRANSFER); .setCallbackType(TradeTypeEnum.TRANSFER);
WechatPayConfig config = wechatPayConfigService.getWechatPayConfig(); WechatPayConfig config = wechatPayConfigService.getAndCheckConfig();
WxPayService wxPayService = wechatPayConfigService.wxJavaSdk(config); WxPayService wxPayService = wechatPayConfigService.wxJavaSdk(config);
// V3 回调接收处理 // V3 回调接收处理
String body = JakartaServletUtil.getBody(request); String body = JakartaServletUtil.getBody(request);

View File

@@ -13,6 +13,7 @@ import org.dromara.daxpay.channel.wechat.entity.config.WechatPayConfig;
import org.dromara.daxpay.channel.wechat.param.config.WechatPayConfigParam; import org.dromara.daxpay.channel.wechat.param.config.WechatPayConfigParam;
import org.dromara.daxpay.channel.wechat.result.config.WechatPayConfigResult; import org.dromara.daxpay.channel.wechat.result.config.WechatPayConfigResult;
import org.dromara.daxpay.core.enums.ChannelEnum; import org.dromara.daxpay.core.enums.ChannelEnum;
import org.dromara.daxpay.core.exception.ChannelNotEnableException;
import org.dromara.daxpay.core.exception.ConfigNotEnableException; import org.dromara.daxpay.core.exception.ConfigNotEnableException;
import org.dromara.daxpay.core.exception.DataErrorException; import org.dromara.daxpay.core.exception.DataErrorException;
import org.dromara.daxpay.service.common.cache.ChannelConfigCacheService; import org.dromara.daxpay.service.common.cache.ChannelConfigCacheService;
@@ -88,15 +89,6 @@ public class WechatPayConfigService {
channelConfigManager.updateById(channelConfig); channelConfigManager.updateById(channelConfig);
} }
/**
* 获取微信支付配置
*/
public WechatPayConfig getWechatPayConfig(){
MchAppLocal mchAppInfo = PaymentContextLocal.get().getMchAppInfo();
ChannelConfig channelConfig = channelConfigCacheService.get(mchAppInfo.getAppId(), ChannelEnum.WECHAT.getCode());
return WechatPayConfig.convertConfig(channelConfig);
}
/** /**
* 获取支付异步通知地址 * 获取支付异步通知地址
*/ */
@@ -124,6 +116,27 @@ public class WechatPayConfigService {
return StrUtil.format("{}/unipay/callback/{}/{}/wechat/transfer",platformInfo.getGatewayServiceUrl(), mchAppInfo.getAppId()); return StrUtil.format("{}/unipay/callback/{}/{}/wechat/transfer",platformInfo.getGatewayServiceUrl(), mchAppInfo.getAppId());
} }
/**
* 获取并检查支付配置
*/
public WechatPayConfig getAndCheckConfig(){
var payConfig = this.getWechatPayConfig();
if (!payConfig.getEnable()){
throw new ChannelNotEnableException("支付宝支付通道未启用");
}
return payConfig;
}
/**
* 获取微信支付配置
*/
public WechatPayConfig getWechatPayConfig(){
MchAppLocal mchAppInfo = PaymentContextLocal.get().getMchAppInfo();
ChannelConfig channelConfig = channelConfigCacheService.get(mchAppInfo.getAppId(), ChannelEnum.WECHAT.getCode());
return WechatPayConfig.convertConfig(channelConfig);
}
/** /**
* wxjava 支付开发包 * wxjava 支付开发包
*/ */

View File

@@ -77,7 +77,7 @@ public class WechatPayCashierService {
* 获取微信公众号API的Service * 获取微信公众号API的Service
*/ */
private WxMpService getWxMpService() { private WxMpService getWxMpService() {
WechatPayConfig config = wechatPayConfigService.getWechatPayConfig(); WechatPayConfig config = wechatPayConfigService.getAndCheckConfig();
WxMpService wxMpService = new WxMpServiceImpl(); WxMpService wxMpService = new WxMpServiceImpl();
WxMpDefaultConfigImpl wxMpConfig = new WxMpDefaultConfigImpl(); WxMpDefaultConfigImpl wxMpConfig = new WxMpDefaultConfigImpl();
wxMpConfig.setAppId(config.getWxAppId()); // 设置微信公众号的appid wxMpConfig.setAppId(config.getWxAppId()); // 设置微信公众号的appid

View File

@@ -1,6 +1,6 @@
package org.dromara.daxpay.channel.wechat.service.reconcile; package org.dromara.daxpay.channel.wechat.service.reconcile;
import org.dromara.daxpay.channel.wechat.bo.reconcile.WechatReconcileBillDetail; import org.dromara.daxpay.channel.wechat.entity.reconcile.WechatReconcileBillDetail;
import org.dromara.daxpay.channel.wechat.entity.config.WechatPayConfig; import org.dromara.daxpay.channel.wechat.entity.config.WechatPayConfig;
import org.dromara.daxpay.channel.wechat.service.config.WechatPayConfigService; import org.dromara.daxpay.channel.wechat.service.config.WechatPayConfigService;
import org.dromara.daxpay.core.enums.TradeStatusEnum; import org.dromara.daxpay.core.enums.TradeStatusEnum;
@@ -56,7 +56,7 @@ public class WechatPayReconcileService {
@SneakyThrows @SneakyThrows
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ReconcileResolveResultBo downAndResolve(ReconcileStatement statement, String date) { public ReconcileResolveResultBo downAndResolve(ReconcileStatement statement, String date) {
WechatPayConfig config = wechatPayConfigService.getWechatPayConfig(); WechatPayConfig config = wechatPayConfigService.getAndCheckConfig();
WxPayService wxPayService = wechatPayConfigService.wxJavaSdk(config); WxPayService wxPayService = wechatPayConfigService.wxJavaSdk(config);
var request = new WxPayApplyTradeBillV3Request(); var request = new WxPayApplyTradeBillV3Request();
request.setBillDate(date); request.setBillDate(date);
@@ -124,7 +124,7 @@ public class WechatPayReconcileService {
if (Objects.equals(billDetail.getTradeState(), WxPayConstants.WxpayTradeStatus.SUCCESS)) { if (Objects.equals(billDetail.getTradeState(), WxPayConstants.WxpayTradeStatus.SUCCESS)) {
tradeBo.setTradeType(TradeTypeEnum.PAY.getCode()) tradeBo.setTradeType(TradeTypeEnum.PAY.getCode())
.setAmount(new BigDecimal(billDetail.getTotalFee())) .setAmount(new BigDecimal(billDetail.getTotalFee()))
.setTradeStatus(TradeStatusEnum.SUCCESS.getCode()); .setTradeStatus(TradeStatusEnum.SUCCESS.getCode());
} }
// 退款覆盖更新对应的字段 // 退款覆盖更新对应的字段
@@ -133,7 +133,6 @@ public class WechatPayReconcileService {
.setTradeNo(billDetail.getRefundId()) .setTradeNo(billDetail.getRefundId())
.setAmount(new BigDecimal(billDetail.getRefundFee())) .setAmount(new BigDecimal(billDetail.getRefundFee()))
.setTradeType(TradeTypeEnum.REFUND.getCode()); .setTradeType(TradeTypeEnum.REFUND.getCode());
tradeBo.setTradeType(TradeTypeEnum.REFUND.getCode());
// 状态 // 状态
switch (billDetail.getRefundStatus()) { switch (billDetail.getRefundStatus()) {
case WxPayConstants.RefundStatus.SUCCESS -> tradeBo.setTradeStatus(TradeStatusEnum.SUCCESS.getCode()); case WxPayConstants.RefundStatus.SUCCESS -> tradeBo.setTradeStatus(TradeStatusEnum.SUCCESS.getCode());
@@ -145,8 +144,8 @@ public class WechatPayReconcileService {
} }
// 撤销状态 // 撤销状态
if (Objects.equals(billDetail.getTradeState(), WxPayConstants.WxpayTradeStatus.REVOKED)) { if (Objects.equals(billDetail.getTradeState(), WxPayConstants.WxpayTradeStatus.REVOKED)) {
tradeBo.setTradeType(TradeTypeEnum.PAY.getCode()); tradeBo.setTradeType(TradeTypeEnum.PAY.getCode())
tradeBo.setTradeStatus(TradeStatusEnum.REVOKED.getCode()); .setTradeStatus(TradeStatusEnum.REVOKED.getCode());
} }
return tradeBo; return tradeBo;
@@ -155,8 +154,8 @@ public class WechatPayReconcileService {
/** /**
* 保存下载的原始对账文件 * 保存下载的原始对账文件
*/ */
private String saveOriginalFile(ReconcileStatement reconcileOrder, byte[] bytes) { private String saveOriginalFile(ReconcileStatement statement, byte[] bytes) {
String date = LocalDateTimeUtil.format(reconcileOrder.getDate(), DatePattern.PURE_DATE_PATTERN); String date = LocalDateTimeUtil.format(statement.getDate(), DatePattern.PURE_DATE_PATTERN);
// 将原始文件进行保存 通道-日期 // 将原始文件进行保存 通道-日期
String fileName = StrUtil.format("交易对账单-微信-{}.csv",date); String fileName = StrUtil.format("交易对账单-微信-{}.csv",date);
var uploadPretreatment = fileStorageService.of(bytes); var uploadPretreatment = fileStorageService.of(bytes);

View File

@@ -63,7 +63,7 @@ public class WechatPayAllocReceiverStrategy extends AbsAllocReceiverStrategy {
@Override @Override
public void doBeforeHandler(){ public void doBeforeHandler(){
this.config = wechatPayConfigService.getWechatPayConfig(); this.config = wechatPayConfigService.getAndCheckConfig();
} }

View File

@@ -52,7 +52,7 @@ public class WechatPayCloseStrategy extends AbsPayCloseStrategy {
if (this.isUseCancel() && !order.getMethod().equals(PayMethodEnum.BARCODE.getCode())){ if (this.isUseCancel() && !order.getMethod().equals(PayMethodEnum.BARCODE.getCode())){
throw new ValidationFailedException("该订单不支持撤销操作"); throw new ValidationFailedException("该订单不支持撤销操作");
} }
this.config = wechatPayConfigService.getWechatPayConfig(); this.config = wechatPayConfigService.getAndCheckConfig();
} }
/** /**

View File

@@ -1,16 +1,15 @@
package org.dromara.daxpay.channel.wechat.strategy; package org.dromara.daxpay.channel.wechat.strategy;
import org.dromara.daxpay.channel.wechat.service.config.WechatPayConfigService;
import org.dromara.daxpay.channel.wechat.service.reconcile.WechatPayReconcileService;
import org.dromara.daxpay.core.enums.ChannelEnum;
import org.dromara.daxpay.service.bo.reconcile.ReconcileResolveResultBo;
import org.dromara.daxpay.service.enums.ReconcileFileTypeEnum;
import org.dromara.daxpay.service.strategy.AbsReconcileStrategy;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.LocalDateTimeUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.daxpay.channel.wechat.service.reconcile.WechatPayReconcileService;
import org.dromara.daxpay.core.enums.ChannelEnum;
import org.dromara.daxpay.service.bo.reconcile.ReconcileResolveResultBo;
import org.dromara.daxpay.service.enums.ReconcileFileTypeEnum;
import org.dromara.daxpay.service.strategy.AbsReconcileStrategy;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -30,8 +29,6 @@ public class WechatPayReconcileStrategy extends AbsReconcileStrategy {
private final WechatPayReconcileService reconcileService; private final WechatPayReconcileService reconcileService;
private final WechatPayConfigService wechatPayConfigService;
/** /**
* 策略标识 * 策略标识
* *

View File

@@ -59,7 +59,7 @@ public class WechatPayStrategy extends AbsPayStrategy {
} else { } else {
this.wechatPayParam = new WechatPayParam(); this.wechatPayParam = new WechatPayParam();
} }
this.wechatPayConfig = aliPayConfigService.getWechatPayConfig(); this.wechatPayConfig = aliPayConfigService.getAndCheckConfig();
wechatPayService.validation(this.getPayParam(), this.wechatPayParam, wechatPayConfig); wechatPayService.validation(this.getPayParam(), this.wechatPayParam, wechatPayConfig);
} }

View File

@@ -49,7 +49,7 @@ public class WechatRefundStrategy extends AbsRefundStrategy {
*/ */
@Override @Override
public void doBeforeRefundHandler() { public void doBeforeRefundHandler() {
this.config = wechatPayConfigService.getWechatPayConfig(); this.config = wechatPayConfigService.getAndCheckConfig();
} }

View File

@@ -52,7 +52,7 @@ public class WechatSyncPayStrategy extends AbsSyncPayOrderStrategy {
*/ */
@Override @Override
public PaySyncResultBo doSync() { public PaySyncResultBo doSync() {
var wechatPayConfig = wechatPayConfigService.getWechatPayConfig(); var wechatPayConfig = wechatPayConfigService.getAndCheckConfig();
if (Objects.equals(wechatPayConfig.getApiVersion(), WechatPayCode.API_V2)){ if (Objects.equals(wechatPayConfig.getApiVersion(), WechatPayCode.API_V2)){
return weChatPaySyncV2Service.sync(getOrder(), wechatPayConfig); return weChatPaySyncV2Service.sync(getOrder(), wechatPayConfig);
} else { } else {

View File

@@ -47,7 +47,7 @@ public class WechatSyncRefundStrategy extends AbsSyncRefundOrderStrategy {
*/ */
@Override @Override
public RefundSyncResultBo doSync() { public RefundSyncResultBo doSync() {
var wechatPayConfig = wechatPayConfigService.getWechatPayConfig(); var wechatPayConfig = wechatPayConfigService.getAndCheckConfig();
if (Objects.equals(wechatPayConfig.getApiVersion(), WechatPayCode.API_V2)){ if (Objects.equals(wechatPayConfig.getApiVersion(), WechatPayCode.API_V2)){
return wechatRefundSyncV2Service.sync(this.getRefundOrder(), wechatPayConfig); return wechatRefundSyncV2Service.sync(this.getRefundOrder(), wechatPayConfig);
} else { } else {

View File

@@ -41,7 +41,7 @@ public class WechatSyncTransferStrategy extends AbsSyncTransferOrderStrategy {
*/ */
@Override @Override
public TransferSyncResultBo doSync() { public TransferSyncResultBo doSync() {
var wechatPayConfig = wechatPayConfigService.getWechatPayConfig(); var wechatPayConfig = wechatPayConfigService.getAndCheckConfig();
return wechatTransferSyncV3Service.sync(this.getTransferOrder(), wechatPayConfig); return wechatTransferSyncV3Service.sync(this.getTransferOrder(), wechatPayConfig);
} }

View File

@@ -75,7 +75,7 @@ public class WechatTransferStrategy extends AbsTransferStrategy {
*/ */
@Override @Override
public void doBeforeHandler() { public void doBeforeHandler() {
this.weChatPayConfig = wechatPayConfigService.getWechatPayConfig(); this.weChatPayConfig = wechatPayConfigService.getAndCheckConfig();
} }
/** /**