From da8e7b31d0216b5e19ecc649eaa0db61543b5552 Mon Sep 17 00:00:00 2001 From: DaxPay Dev Date: Thu, 2 Jul 2026 14:06:30 +0800 Subject: [PATCH] =?UTF-8?q?refactor(pay):=20NormalPayContext=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=EF=BC=8C=E5=88=A0=E9=99=A4=20NormalOrderTrade?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新建 NormalPayContext/AbsNormalPayStrategy 替代旧的 PayStrategyContext/AbsPayStrategy - NormalPayContext 持有容器+凭证+请求参数+通道配置,按序填充 - PayAssistService 方法改为填充 NormalPayContext,不再返回中间对象 - 通道策略全部切换为 AbsNormalPayStrategy,doBeforePay 激活通道配置 - 删除 NormalOrderTrade、PayStrategyContext、AbsPayStrategy、旧 PayService - 删除 old PayCloseService/PaySyncService 中 unused import --- .../direct/AlipayDirectCloseStrategy.java | 12 +- .../direct/AlipayDirectPayStrategy.java | 31 ++- .../direct/AlipayDirectSyncStrategy.java | 16 +- .../strategy/isv/AlipayIsvCloseStrategy.java | 4 +- .../strategy/isv/AlipayIsvPayStrategy.java | 25 ++- .../strategy/isv/AlipayIsvSyncStrategy.java | 4 +- .../strategy/DouyinDirectPayStrategy.java | 8 +- .../common/context/NormalPayContext.java | 37 ++++ .../common/context/PayStrategyContext.java | 32 ---- .../service/trade/pay/PayCloseService.java | 6 +- .../old/pay/service/trade/pay/PayService.java | 178 ------------------ .../pay/service/trade/pay/PaySyncService.java | 8 +- .../payment/pay/service/NormalPayService.java | 37 ++-- .../payment/pay/service/PayAssistService.java | 18 +- .../payment/pay/service/PayCloseService.java | 8 +- .../payment/pay/service/PaySyncService.java | 6 +- .../strategy/pay/AbsNormalPayStrategy.java | 22 +++ .../strategy/pay/AbsPayCloseStrategy.java | 11 +- .../payment/strategy/pay/AbsPayStrategy.java | 21 --- .../sync/AbsSyncPayOrderStrategy.java | 9 +- 20 files changed, 181 insertions(+), 312 deletions(-) create mode 100644 daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/common/context/NormalPayContext.java delete mode 100644 daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/common/context/PayStrategyContext.java delete mode 100644 daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PayService.java create mode 100644 daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsNormalPayStrategy.java delete mode 100644 daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsPayStrategy.java diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectCloseStrategy.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectCloseStrategy.java index 98e1205b9..467afa410 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectCloseStrategy.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectCloseStrategy.java @@ -3,7 +3,7 @@ package cn.daxpay.open.channel.alipay.strategy.direct; import cn.daxpay.open.channel.alipay.client.credential.AlipaySdkCredential; import cn.daxpay.open.channel.alipay.service.direct.AlipayDirectConfigAssembler; import cn.daxpay.open.channel.alipay.service.payment.close.AlipayCloseService; -import cn.daxpay.open.payment.pay.order.dao.NormalPayOrderManager; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.pay.order.entity.NormalPayOrder; import cn.daxpay.open.payment.pay.order.entity.PayTrade; import cn.daxpay.open.payment.strategy.pay.AbsPayCloseStrategy; @@ -16,7 +16,7 @@ import org.springframework.stereotype.Service; /// # 支付宝直连支付关闭策略 /// /// 支付宝直连模式(ProductEnum.ALIPAY)下的支付关闭策略。 -/// 从容器层 NormalPayOrder 读取通道路由参数(channelMchNo / capability), +/// 从上下文容器读取通道路由参数(channelMchNo / capability), /// 组装通道凭证(委托 [AlipayDirectConfigAssembler]), 关闭执行委托给 [AlipayCloseService]。 @Slf4j @Service @@ -25,7 +25,6 @@ public class AlipayDirectCloseStrategy extends AbsPayCloseStrategy { private final AlipayCloseService alipayCloseService; private final AlipayDirectConfigAssembler alipayDirectConfigAssembler; - private final NormalPayOrderManager normalPayOrderManager; @Override public ProductEnum getProduct() { @@ -33,11 +32,12 @@ public class AlipayDirectCloseStrategy extends AbsPayCloseStrategy { } @Override - public CloseTypeEnum doClose(PayTrade trade, boolean useCancel) { - // 从容器层读取通道路由参数, 用于凭证解析 - NormalPayOrder normalOrder = normalPayOrderManager.findById(trade.getContainerId()).orElse(null); + public CloseTypeEnum doClose(NormalPayContext context, boolean useCancel) { + // 从上下文容器读取通道路由参数, 用于凭证解析 + NormalPayOrder normalOrder = context.getContainer(); String channelMchNo = normalOrder != null ? normalOrder.getChannelMchNo() : null; String capability = normalOrder != null ? normalOrder.getCapability() : null; + PayTrade trade = context.getTrade(); // 组装通道调用凭证 AlipaySdkCredential credential = alipayDirectConfigAssembler.buildConfig( diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectPayStrategy.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectPayStrategy.java index c0fab8395..de467e38f 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectPayStrategy.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectPayStrategy.java @@ -1,10 +1,12 @@ package cn.daxpay.open.channel.alipay.strategy.direct; +import cn.daxpay.open.channel.alipay.client.credential.AlipaySdkCredential; import cn.daxpay.open.channel.alipay.service.direct.AlipayDirectConfigAssembler; import cn.daxpay.open.channel.alipay.service.payment.pay.AlipayPayService; -import cn.daxpay.open.payment.common.context.PayStrategyContext; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.pay.bo.PayTradeResultBo; -import cn.daxpay.open.payment.strategy.pay.AbsPayStrategy; +import cn.daxpay.open.payment.strategy.pay.AbsNormalPayStrategy; +import cn.daxpay.open.payment.unipay.param.trade.pay.NormalPayParam; import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -13,12 +15,12 @@ import org.springframework.stereotype.Service; /// # 支付宝直连支付策略 /// /// 支付宝直连模式(ProductEnum.ALIPAY)下发起支付的具体执行策略。 -/// 负责直连配置组装(委托 [AlipayDirectConfigAssembler]), 支付执行委托给 [AlipayPayService]。 +/// 配置组装在 [doBeforePay] 阶段完成(委托 [AlipayDirectConfigAssembler]), 支付执行委托给 [AlipayPayService]。 /// @Slf4j @Service @RequiredArgsConstructor -public class AlipayDirectPayStrategy extends AbsPayStrategy { +public class AlipayDirectPayStrategy extends AbsNormalPayStrategy { private final AlipayPayService alipayPayService; private final AlipayDirectConfigAssembler alipayDirectConfigAssembler; @@ -28,12 +30,21 @@ public class AlipayDirectPayStrategy extends AbsPayStrategy { return ProductEnum.ALIPAY; } + /// 支付前预处理: 从容器读取通道路由参数, 组装直连通道凭证写入上下文 + /// 配置缺失在此阶段抛异常, fail-fast, 不会进入 doPay @Override - public PayTradeResultBo doPay(PayStrategyContext context) { - return alipayPayService.pay(context.getTrade(), context.getPayParam(), - alipayDirectConfigAssembler.buildConfig( - context.getTrade().getMchNo(), - context.getPayParam().getChannelMchNo(), - context.getPayParam().getCapability())); + public void doBeforePay(NormalPayContext context) { + // 组装直连通道凭证(只依赖请求参数, 订单尚未创建) + NormalPayParam payParam = context.getPayParam(); + AlipaySdkCredential credential = alipayDirectConfigAssembler.buildConfig( + payParam.getMchNo(), payParam.getChannelMchNo(), payParam.getCapability()); + context.setChannelConfig(credential); + } + + @Override + public PayTradeResultBo doPay(NormalPayContext context) { + // 直接使用 doBeforePay 预组装的通道凭证 + AlipaySdkCredential credential = context.getChannelConfig(AlipaySdkCredential.class); + return alipayPayService.pay(context.getTrade(), context.getPayParam(), credential); } } diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectSyncStrategy.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectSyncStrategy.java index ed8bc6a1f..410a698a9 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectSyncStrategy.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/direct/AlipayDirectSyncStrategy.java @@ -3,10 +3,9 @@ package cn.daxpay.open.channel.alipay.strategy.direct; import cn.daxpay.open.channel.alipay.client.credential.AlipaySdkCredential; import cn.daxpay.open.channel.alipay.service.direct.AlipayDirectConfigAssembler; import cn.daxpay.open.channel.alipay.service.payment.sync.AlipaySyncService; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.pay.bo.PaySyncResultBo; -import cn.daxpay.open.payment.pay.order.dao.NormalPayOrderManager; import cn.daxpay.open.payment.pay.order.entity.NormalPayOrder; -import cn.daxpay.open.payment.pay.order.entity.PayTrade; import cn.daxpay.open.payment.strategy.sync.AbsSyncPayOrderStrategy; import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum; import lombok.RequiredArgsConstructor; @@ -16,7 +15,7 @@ import org.springframework.stereotype.Service; /// # 支付宝直连支付同步策略 /// /// 支付宝直连模式(ProductEnum.ALIPAY)下的支付同步策略。 -/// 从容器层 NormalPayOrder 读取通道路由参数(channelMchNo / capability), +/// 从上下文容器读取通道路由参数(channelMchNo / capability), /// 组装通道凭证(委托 [AlipayDirectConfigAssembler]), 同步执行委托给 [AlipaySyncService]。 @Slf4j @Service @@ -25,7 +24,6 @@ public class AlipayDirectSyncStrategy extends AbsSyncPayOrderStrategy { private final AlipaySyncService alipaySyncService; private final AlipayDirectConfigAssembler alipayDirectConfigAssembler; - private final NormalPayOrderManager normalPayOrderManager; @Override public ProductEnum getProduct() { @@ -33,16 +31,16 @@ public class AlipayDirectSyncStrategy extends AbsSyncPayOrderStrategy { } @Override - public PaySyncResultBo doSync(PayTrade trade) { - // 从容器层读取通道路由参数, 用于凭证解析 - NormalPayOrder normalOrder = normalPayOrderManager.findById(trade.getContainerId()).orElse(null); + public PaySyncResultBo doSync(NormalPayContext context) { + // 从上下文容器读取通道路由参数, 用于凭证解析 + NormalPayOrder normalOrder = context.getContainer(); String channelMchNo = normalOrder != null ? normalOrder.getChannelMchNo() : null; String capability = normalOrder != null ? normalOrder.getCapability() : null; // 组装通道调用凭证 AlipaySdkCredential credential = alipayDirectConfigAssembler.buildConfig( - trade.getMchNo(), channelMchNo, capability); + context.getTrade().getMchNo(), channelMchNo, capability); - return alipaySyncService.sync(trade, credential); + return alipaySyncService.sync(context.getTrade(), credential); } } diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvCloseStrategy.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvCloseStrategy.java index a069d9698..6ae8d7c60 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvCloseStrategy.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvCloseStrategy.java @@ -3,6 +3,7 @@ package cn.daxpay.open.channel.alipay.strategy.isv; import cn.daxpay.open.channel.alipay.client.credential.AlipaySdkCredential; import cn.daxpay.open.channel.alipay.service.isv.AlipayIsvConfigAssembler; import cn.daxpay.open.channel.alipay.service.payment.close.AlipayCloseService; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.pay.order.entity.PayTrade; import cn.daxpay.open.payment.strategy.pay.AbsPayCloseStrategy; import cn.daxpay.open.platform.core.enums.pay.pay.CloseTypeEnum; @@ -29,7 +30,8 @@ public class AlipayIsvCloseStrategy extends AbsPayCloseStrategy { } @Override - public CloseTypeEnum doClose(PayTrade trade, boolean useCancel) { + public CloseTypeEnum doClose(NormalPayContext context, boolean useCancel) { + PayTrade trade = context.getTrade(); // 组装服务商模式通道调用凭证(含应用授权令牌) AlipaySdkCredential credential = alipayIsvConfigAssembler.buildConfig(trade.getMchNo()); return alipayCloseService.close(trade, credential, useCancel); diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvPayStrategy.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvPayStrategy.java index 810726078..90840b52d 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvPayStrategy.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvPayStrategy.java @@ -1,10 +1,11 @@ package cn.daxpay.open.channel.alipay.strategy.isv; +import cn.daxpay.open.channel.alipay.client.credential.AlipaySdkCredential; import cn.daxpay.open.channel.alipay.service.isv.AlipayIsvConfigAssembler; import cn.daxpay.open.channel.alipay.service.payment.pay.AlipayPayService; -import cn.daxpay.open.payment.common.context.PayStrategyContext; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.pay.bo.PayTradeResultBo; -import cn.daxpay.open.payment.strategy.pay.AbsPayStrategy; +import cn.daxpay.open.payment.strategy.pay.AbsNormalPayStrategy; import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -13,11 +14,11 @@ import org.springframework.stereotype.Service; /// # 支付宝服务商支付策略 /// /// 支付宝服务商模式(ProductEnum.ALIPAY_ISV)下发起支付的具体执行策略。 -/// 负责服务商配置组装(含应用授权令牌, 委托 [AlipayIsvConfigAssembler]), 支付执行委托给 [AlipayPayService]。 +/// 配置组装(含应用授权令牌)在 [doBeforePay] 阶段完成(委托 [AlipayIsvConfigAssembler]), 支付执行委托给 [AlipayPayService]。 @Slf4j @Service @RequiredArgsConstructor -public class AlipayIsvPayStrategy extends AbsPayStrategy { +public class AlipayIsvPayStrategy extends AbsNormalPayStrategy { private final AlipayPayService alipayPayService; private final AlipayIsvConfigAssembler alipayIsvConfigAssembler; @@ -27,10 +28,18 @@ public class AlipayIsvPayStrategy extends AbsPayStrategy { return ProductEnum.ALIPAY_ISV; } + /// 支付前预处理: 组装服务商模式通道凭证(含应用授权令牌)写入上下文 + /// 配置缺失在此阶段抛异常, fail-fast, 不会进入 doPay @Override - public PayTradeResultBo doPay(PayStrategyContext context) { - // 组装服务商模式通道调用凭证(含应用授权令牌), 支付执行委托 AlipayPayService - return alipayPayService.pay(context.getTrade(), context.getPayParam(), - alipayIsvConfigAssembler.buildConfig(context.getTrade().getMchNo())); + public void doBeforePay(NormalPayContext context) { + AlipaySdkCredential credential = alipayIsvConfigAssembler.buildConfig(context.getPayParam().getMchNo()); + context.setChannelConfig(credential); + } + + @Override + public PayTradeResultBo doPay(NormalPayContext context) { + // 直接使用 doBeforePay 预组装的通道凭证 + AlipaySdkCredential credential = (AlipaySdkCredential) context.getChannelConfig(); + return alipayPayService.pay(context.getTrade(), context.getPayParam(), credential); } } diff --git a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvSyncStrategy.java b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvSyncStrategy.java index 16f6f8c15..4d2d50aea 100644 --- a/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvSyncStrategy.java +++ b/daxpay-channel/daxpay-channel-alipay/src/main/java/cn/daxpay/open/channel/alipay/strategy/isv/AlipayIsvSyncStrategy.java @@ -3,6 +3,7 @@ package cn.daxpay.open.channel.alipay.strategy.isv; import cn.daxpay.open.channel.alipay.client.credential.AlipaySdkCredential; import cn.daxpay.open.channel.alipay.service.isv.AlipayIsvConfigAssembler; import cn.daxpay.open.channel.alipay.service.payment.sync.AlipaySyncService; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.pay.bo.PaySyncResultBo; import cn.daxpay.open.payment.pay.order.entity.PayTrade; import cn.daxpay.open.payment.strategy.sync.AbsSyncPayOrderStrategy; @@ -29,7 +30,8 @@ public class AlipayIsvSyncStrategy extends AbsSyncPayOrderStrategy { } @Override - public PaySyncResultBo doSync(PayTrade trade) { + public PaySyncResultBo doSync(NormalPayContext context) { + PayTrade trade = context.getTrade(); // 组装服务商模式通道调用凭证(含应用授权令牌) AlipaySdkCredential credential = alipayIsvConfigAssembler.buildConfig(trade.getMchNo()); return alipaySyncService.sync(trade, credential); diff --git a/daxpay-channel/daxpay-channel-douyin/src/main/java/cn/daxpay/open/channel/douyin/strategy/DouyinDirectPayStrategy.java b/daxpay-channel/daxpay-channel-douyin/src/main/java/cn/daxpay/open/channel/douyin/strategy/DouyinDirectPayStrategy.java index e2540d206..79db1e6fa 100644 --- a/daxpay-channel/daxpay-channel-douyin/src/main/java/cn/daxpay/open/channel/douyin/strategy/DouyinDirectPayStrategy.java +++ b/daxpay-channel/daxpay-channel-douyin/src/main/java/cn/daxpay/open/channel/douyin/strategy/DouyinDirectPayStrategy.java @@ -3,10 +3,10 @@ package cn.daxpay.open.channel.douyin.strategy; import cn.daxpay.open.channel.douyin.client.DouyinChannelClient; import cn.daxpay.open.channel.douyin.dto.DouyinPayReq; import cn.daxpay.open.channel.douyin.dto.DouyinPayResp; -import cn.daxpay.open.payment.common.context.PayStrategyContext; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.common.result.DaxResult; import cn.daxpay.open.payment.pay.bo.PayTradeResultBo; -import cn.daxpay.open.payment.strategy.pay.AbsPayStrategy; +import cn.daxpay.open.payment.strategy.pay.AbsNormalPayStrategy; import cn.daxpay.open.platform.core.enums.pay.channel.ProductEnum; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -21,7 +21,7 @@ import java.util.Map; @Slf4j @Service @RequiredArgsConstructor -public class DouyinDirectPayStrategy extends AbsPayStrategy { +public class DouyinDirectPayStrategy extends AbsNormalPayStrategy { private final DouyinChannelClient douyinChannelClient; @@ -31,7 +31,7 @@ public class DouyinDirectPayStrategy extends AbsPayStrategy { } @Override - public PayTradeResultBo doPay(PayStrategyContext context) { + public PayTradeResultBo doPay(NormalPayContext context) { // 构建请求 DouyinPayReq req = new DouyinPayReq(); req.setChannel(ProductEnum.DOUYIN_PAY.getChannel()); diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/common/context/NormalPayContext.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/common/context/NormalPayContext.java new file mode 100644 index 000000000..fd382b887 --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/common/context/NormalPayContext.java @@ -0,0 +1,37 @@ +package cn.daxpay.open.payment.common.context; + +import cn.daxpay.open.payment.pay.order.entity.NormalPayOrder; +import cn.daxpay.open.payment.pay.order.entity.PayTrade; +import cn.daxpay.open.payment.unipay.param.trade.pay.NormalPayParam; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; + +/// # 普通支付策略执行上下文(请求级,每次支付/同步/关闭创建新实例) +/// +/// 显式传递,替代原策略实例字段。持有"容器(业务单) + 资金凭证 + 请求参数"三要素, +/// 与 [PayTrade] 的 containerId 形成冗余双链,使策略无需再自查容器表。 +/// 通道配置由 doBeforePay 写入、doPay/doSync/doClose 读取,类型各通道不同。 +@Getter +@Setter +@Accessors(chain = true) +public class NormalPayContext { + + /// 普通支付业务单容器(承载 bizOrderNo / 回调地址 / 通道路由等业务信息) + private NormalPayOrder container; + + /// 资金交易凭证(记录本笔资金动作的状态与通道回执) + private PayTrade trade; + + /// 普通支付请求参数(pay 流程必填;sync/close 流程可为空) + private NormalPayParam payParam; + + /// 通道配置(doBeforePay 写入,doPay 读取;类型各通道不同) + private Object channelConfig; + + + @SuppressWarnings("unchecked") + public T getChannelConfig(Class clazz) { + return (T) channelConfig; + } +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/common/context/PayStrategyContext.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/common/context/PayStrategyContext.java deleted file mode 100644 index 411b9aa9b..000000000 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/common/context/PayStrategyContext.java +++ /dev/null @@ -1,32 +0,0 @@ -package cn.daxpay.open.payment.common.context; - -import cn.daxpay.open.payment.pay.order.entity.PayTrade; -import cn.daxpay.open.payment.unipay.param.trade.pay.NormalPayParam; -import lombok.Getter; -import lombok.Setter; -import lombok.experimental.Accessors; - -/// # 支付策略执行上下文(请求级,每次支付创建新实例) -/// -/// 显式传递,替代原 AbsPayStrategy 实例字段。通道配置由 doBeforePay 写入、doPay 读取。 -@Getter -@Setter -@Accessors(chain = true) -public class PayStrategyContext { - - /// 支付参数 - private NormalPayParam payParam; - - /// 资金交易凭证 - private PayTrade trade; - - /// 通道配置(doBeforePay 写入,doPay 读取;类型各通道不同) - private Object channelConfig; - - public PayStrategyContext() { - } - - public PayStrategyContext(NormalPayParam payParam) { - this.payParam = payParam; - } -} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PayCloseService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PayCloseService.java index 24944863c..7e938cb45 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PayCloseService.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PayCloseService.java @@ -17,6 +17,7 @@ import cn.daxpay.open.platform.core.enums.pay.pay.PayStatusEnum; import cn.daxpay.open.payment.old.pay.exception.TradeNotExistException; import cn.daxpay.open.payment.old.pay.exception.TradeProcessingException; import cn.daxpay.open.payment.old.pay.exception.TradeStatusErrorException; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.common.context.PaymentContext; import cn.daxpay.open.payment.old.pay.service.notice.MerchantNoticeService; import cn.daxpay.open.payment.old.pay.service.order.pay.PayOrderQueryService; @@ -95,9 +96,10 @@ public class PayCloseService { trade.setChannel(payOrder.getChannel()); trade.setMethod(payOrder.getMethod()); // 关闭前准备 - strategy.doBeforeClose(trade); + NormalPayContext closeContext = new NormalPayContext().setTrade(trade); + strategy.doBeforeClose(closeContext); // 执行关闭策略, 返回关闭的方式 - closeType = strategy.doClose(trade, useCancel); + closeType = strategy.doClose(closeContext, useCancel); // 成功处理 关闭或撤销订单 payStatusEnum = useCancel ? PayStatusEnum.CANCEL : PayStatusEnum.CLOSE; } diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PayService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PayService.java deleted file mode 100644 index dd221960a..000000000 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PayService.java +++ /dev/null @@ -1,178 +0,0 @@ -package cn.daxpay.open.payment.old.pay.service.trade.pay; - -import cn.daxpay.open.platform.common.i18n.util.I18nUtil; -import cn.daxpay.open.platform.core.exception.ValidationFailedException; -import cn.daxpay.open.platform.core.exception.system.DataErrorException; -import cn.daxpay.open.platform.core.exception.PayFailureException; -import cn.daxpay.open.platform.core.exception.BizInfoException; -import cn.daxpay.open.platform.core.code.CommonErrorCode; -import cn.daxpay.open.payment.common.context.PayStrategyContext; -import cn.daxpay.open.payment.common.util.PaymentStrategyFactory; -import cn.daxpay.open.payment.old.pay.bo.trade.PayResultBo; -import cn.daxpay.open.payment.old.pay.dao.order.pay.PayOrderExpandManager; -import cn.daxpay.open.payment.old.pay.dao.order.pay.PayOrderManager; -import cn.daxpay.open.payment.old.pay.entity.order.pay.PayOrder; -import cn.daxpay.open.platform.core.enums.pay.channel.PayMethodEnum; -import cn.daxpay.open.platform.core.enums.pay.pay.PayStatusEnum; -import cn.daxpay.open.payment.old.pay.exception.TradeProcessingException; -import cn.daxpay.open.payment.old.pay.service.trade.TradeUniHandleService; -import cn.daxpay.open.payment.masterdata.constants.product.service.PayProductCapabilityService; -import cn.daxpay.open.payment.pay.order.entity.PayTrade; -import cn.daxpay.open.payment.strategy.pay.AbsPayStrategy; -import cn.daxpay.open.platform.core.enums.unipay.PayBodyTypeEnum; -import cn.daxpay.open.payment.unipay.param.trade.pay.NormalPayParam; -import cn.daxpay.open.payment.unipay.result.trade.pay.NormalPayResult; -import cn.hutool.core.lang.Opt; -import cn.hutool.core.util.StrUtil; -import cn.hutool.extra.spring.SpringUtil; -import com.baomidou.lock.LockInfo; -import com.baomidou.lock.LockTemplate; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Objects; -import java.util.Optional; - -/// # 支付服务类 -/// -@Slf4j -@Service("oldPayService") -@RequiredArgsConstructor -public class PayService { - - private final PayAssistService payAssistService; - private final LockTemplate lockTemplate; - private final PayOrderManager payOrderManager; - private final PayOrderExpandManager payOrderExpandManager; - private final TradeUniHandleService tradeUniHandleService; - - /// 支付入口 - public NormalPayResult pay(NormalPayParam payParam){ - // 校验超时时间, 不可早于当前 - payAssistService.validationExpiredTime(payParam.getExpiredTime()); - // 获取商户订单号 - String bizOrderNo = payParam.getBizOrderNo(); - // 加锁 - LockInfo lock = lockTemplate.lock("payment:pay:" + bizOrderNo,10000,200); - if (Objects.isNull(lock)){ - log.warn("正在支付中,请勿重复支付"); - // 正在支付中,请勿重复支付 - throw new TradeProcessingException(); - } - try { - // 查询并检查订单 - var payOrder = payAssistService.getOrderAndCheck(payParam.getBizOrderNo(), payParam.getAppId()); - // 调用支付流程 - return this.payHandle(payParam,payOrder); - } catch (Exception e) { - log.error("支付异常",e); - throw e; - } finally { - lockTemplate.releaseLock(lock); - } - } - - /// 支付操作 无事务 - /// 拆分为多阶段,1. 保存订单记录信息 2. 调起支付 3. 支付成功后操作 - public NormalPayResult payHandle(NormalPayParam payParam, PayOrder payOrder) { - // 获取支付策略类 - var payStrategy = PaymentStrategyFactory.createByProduct(payParam.getProduct(), AbsPayStrategy.class); - PayStrategyContext context = new PayStrategyContext(payParam); - // 检测支付能力是否支持(产品已挂载能力覆盖该支付方式) - var methodEnum = PayMethodEnum.findByCode(payParam.getMethod()); - if (!SpringUtil.getBean(PayProductCapabilityService.class).productSupportsMethod( - payParam.getProduct(), methodEnum.getCode())) { - throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "pay.error.unsupportedPayMethod", - I18nUtil.getEnumName(methodEnum) + "(" + methodEnum.getCode() + ")"); - } - // 执行支付前处理动作, 进行各种校验, 校验通过才会进行下面的操作 - payStrategy.doBeforePay(context); - // 订单不存在执行支付前的保存动作, 保存支付订单默认状态为支付中 - if (Objects.isNull(payOrder)){ - payOrder = payAssistService.createPayOrder(payParam); - } else { - // 订单: 支付订单扩展信息不存在 - var orderExpand = payOrderExpandManager.findById(payOrder.getId()).orElseThrow(() -> new DataErrorException("error.payment.order.payOrderExtNotExist")); - // 判断是否已经拉起了支付,如果拉起返回保存的支付参数 - if (StrUtil.isNotBlank(orderExpand.getPayBody())){ - return payAssistService.buildResult(payOrder,orderExpand); - } - } - // 订单待支付状态, 设置支付方式和对应状态 - if (Objects.equals(payOrder.getStatus(), PayStatusEnum.WAIT.getCode())){ - payAssistService.updatePayOrder(payParam,payOrder); - } - PayTrade trade = new PayTrade(); - trade.setId(payOrder.getId()); - trade.setProduct(payOrder.getProduct()); - trade.setChannel(payOrder.getChannel()); - trade.setMethod(payOrder.getMethod()); - trade.setAmount(payOrder.getAmount()); - context.setTrade(trade); - PayResultBo result; - try { - // 支付操作 - var newResult = payStrategy.doPay(context); - result = new PayResultBo(); - result.setOutOrderNo(newResult.getOutOrderNo()); - result.setComplete(newResult.isComplete()); - result.setRealAmount(newResult.getRealAmount()); - result.setFinishTime(newResult.getFinishTime()); - result.setPayBody(newResult.getPayBody()); - result.setPayBodyType(newResult.getPayBodyType()); - result.setBuyerId(newResult.getBuyerId()); - result.setUserId(newResult.getUserId()); - result.setTradeProduct(newResult.getTradeProduct()); - result.setTradeWay(newResult.getTradeWay()); - result.setBankType(newResult.getBankType()); - result.setTransOrderNo(newResult.getTransOrderNo()); - result.setRelationOrderNo(newResult.getRelationOrderNo()); - result.setPromotionType(newResult.getPromotionType()); - } catch (Exception e) { - log.error("支付出现异常",e); - payOrder.setStatus(PayStatusEnum.FAIL.getCode()); - if (e instanceof PayFailureException) { - payOrder.setErrorMsg(e.getMessage()); - } else { - payOrder.setErrorMsg("支付出现异常: "+ e.getMessage()); - } - // 这个方法没有事务, 所以可以正常更新 - payOrderManager.updateById(payOrder); - throw e; - } - // 支付调起成功后操作, 使用事务来保证数据一致性 - return SpringUtil.getBean(this.getClass()).paySuccess(payOrder, result); - } - - /// 支付调用成功后操作, 更新订单信息 - @Transactional(rollbackFor = Exception.class) - public NormalPayResult paySuccess(PayOrder payOrder, PayResultBo result){ - // 如果支付完成, 进行订单完成处理, 同时发送回调消息 - if (result.isComplete()) { - payOrder.setStatus(PayStatusEnum.SUCCESS.getCode()) - .setPayTime(result.getFinishTime()); - } - // 更新订单信息 - payOrder.setOutOrderNo(result.getOutOrderNo()) - .setErrorMsg(null) - .setTransOrderNo(result.getTransOrderNo()) - .setRelationOrderNo(result.getRelationOrderNo()); - // 更新订单扩展信息 - var orderExpand = payOrderExpandManager.findById(payOrder.getId()).orElseThrow(() -> new DataErrorException("error.payment.order.payOrderExtNotExist")); - orderExpand.setTradeProduct(result.getTradeProduct()) - .setBankType(result.getBankType()) - .setTradeWay(result.getTradeWay()) - .setPromotionType(result.getPromotionType()) - .setRealAmount(Opt.ofNullable(result.getRealAmount()).orElse(payOrder.getAmount())) - .setBuyerId(result.getBuyerId()) - .setUserId(result.getUserId()) - .setPayBody(result.getPayBody()) - .setPayBodyType(Optional.ofNullable(result.getPayBodyType()).map(PayBodyTypeEnum::getCode).orElse(null)); - // 统一处理 - tradeUniHandleService.payAfterHandel(payOrder,orderExpand); - return payAssistService.buildResult(payOrder,orderExpand); - } -} - diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PaySyncService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PaySyncService.java index 40bd835b7..20cbce9e0 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PaySyncService.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/old/pay/service/trade/pay/PaySyncService.java @@ -20,6 +20,7 @@ import cn.daxpay.open.platform.core.enums.pay.pay.PayStatusEnum; import cn.daxpay.open.platform.core.enums.pay.trade.TradeTypeEnum; import cn.daxpay.open.payment.old.pay.exception.TradeNotExistException; import cn.daxpay.open.payment.old.pay.exception.TradeStatusErrorException; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.common.context.PaymentContext; import cn.daxpay.open.payment.old.pay.service.order.pay.PayOrderQueryService; import cn.daxpay.open.payment.old.pay.service.record.sync.TradeSyncRecordService; @@ -104,7 +105,7 @@ public class PaySyncService { trade.setAmount(payOrder.getAmount()); try { // 执行操作, 获取支付网关同步的结果 - var newResult = syncPayStrategy.doSync(trade); + var newResult = syncPayStrategy.doSync(new NormalPayContext().setTrade(trade)); PaySyncResultBo syncResult = new PaySyncResultBo(); syncResult.setSyncSuccess(newResult.isSyncSuccess()); if (newResult.getPayStatus() != null) { @@ -251,9 +252,10 @@ public class PaySyncService { closeTrade.setProduct(order.getProduct()); closeTrade.setChannel(order.getChannel()); closeTrade.setMethod(order.getMethod()); - strategy.doBeforeClose(closeTrade); + NormalPayContext closeContext = new NormalPayContext().setTrade(closeTrade); + strategy.doBeforeClose(closeContext); // 执行策略的关闭方法 - strategy.doClose(closeTrade, false); + strategy.doClose(closeContext, false); // 关闭统一处理 tradeUniHandleService.payClose(order, PayStatusEnum.CLOSE); } diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/NormalPayService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/NormalPayService.java index ed72e1e4b..40d6b9ae0 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/NormalPayService.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/NormalPayService.java @@ -3,15 +3,15 @@ package cn.daxpay.open.payment.pay.service; import cn.daxpay.open.platform.core.code.CommonErrorCode; import cn.daxpay.open.platform.core.exception.BizInfoException; import cn.daxpay.open.platform.core.exception.PayFailureException; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.common.enums.PayFundStatusEnum; -import cn.daxpay.open.payment.common.context.PayStrategyContext; import cn.daxpay.open.payment.common.util.PaymentStrategyFactory; import cn.daxpay.open.payment.pay.bo.PayTradeResultBo; import cn.daxpay.open.payment.pay.order.dao.PayTradeManager; import cn.daxpay.open.payment.pay.order.entity.PayTrade; import cn.daxpay.open.payment.pay.service.route.PayRouteFacade; import cn.hutool.core.util.StrUtil; -import cn.daxpay.open.payment.strategy.pay.AbsPayStrategy; +import cn.daxpay.open.payment.strategy.pay.AbsNormalPayStrategy; import cn.daxpay.open.payment.unipay.param.trade.pay.NormalPayParam; import cn.daxpay.open.payment.unipay.result.trade.pay.NormalPayResult; import cn.hutool.extra.spring.SpringUtil; @@ -46,32 +46,35 @@ public class NormalPayService { throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "pay.error.pay.processing"); } try { - PayTrade trade = payAssistService.getOrderAndCheck(bizOrderNo); - return this.payHandle(payParam, trade); + return this.payHandle(payParam); } finally { lockTemplate.releaseLock(lock); } } /// 支付操作 - public NormalPayResult payHandle(NormalPayParam payParam, PayTrade trade) { + /// 拆分为多阶段: 1.校验与配置组装 2.查询已有订单 3.新建订单 4.发起支付 5.支付成功后处理 + public NormalPayResult payHandle(NormalPayParam payParam) { // 解析应用号:空则取商户默认应用 payAssistService.resolveApp(payParam); // 路由解析:直定模式(已传 channelMchNo)直接解析,否则按 appId+method 策略匹配 payRouteFacade.resolve(payParam); - var payStrategy = PaymentStrategyFactory.createByProduct(payParam.getProduct(), AbsPayStrategy.class); - // 订单不存在,新建支付订单 - if (Objects.isNull(trade)) { - trade = payAssistService.createOrder(payParam); - } else { - // 判断是否已经拉起了支付,如果拉起返回保存的支付参数 - if (StrUtil.isNotBlank(trade.getPayBody())) { - return payAssistService.buildResult(trade); - } - } - // 显式传递上下文(替代原策略实例字段) - PayStrategyContext context = new PayStrategyContext(payParam).setTrade(trade); + var payStrategy = PaymentStrategyFactory.createByProduct(payParam.getProduct(), AbsNormalPayStrategy.class); + // 支付前处理: 校验与通道配置组装(只依赖请求参数), 失败直接抛出不持久化(订单尚未创建) + NormalPayContext context = new NormalPayContext().setPayParam(payParam); payStrategy.doBeforePay(context); + // 查询已有订单并校验,结果填充到 context + payAssistService.findAndCheckOrder(payParam.getBizOrderNo(), context); + // 已拉起支付则返回缓存的支付参数 + if (Objects.nonNull(context.getTrade()) && StrUtil.isNotBlank(context.getTrade().getPayBody())) { + return payAssistService.buildResult(context.getTrade()); + } + // 订单不存在则新建(填充 context) + if (Objects.isNull(context.getContainer())) { + payAssistService.createOrder(payParam, context); + } + PayTrade trade = context.getTrade(); + // 支付操作, 失败标记 trade 为 FAIL 并持久化 PayTradeResultBo result; try { result = payStrategy.doPay(context); diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PayAssistService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PayAssistService.java index de32e8193..a6b729109 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PayAssistService.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PayAssistService.java @@ -12,6 +12,7 @@ import cn.daxpay.open.payment.common.enums.PayTradeTypeEnum; import cn.daxpay.open.payment.common.service.MchAppInfoAssistQueryService; import cn.daxpay.open.payment.common.util.PayUtil; import cn.hutool.core.util.StrUtil; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.pay.convert.PayTradeConvert; import cn.daxpay.open.payment.pay.order.dao.NormalPayOrderManager; import cn.daxpay.open.payment.pay.order.entity.NormalPayOrder; @@ -48,10 +49,10 @@ public class PayAssistService { } } - /// 创建支付订单(容器 + 资金交易) + /// 创建支付订单(容器 + 资金交易),填充到 context /// 调用方需保证 appId 和 product 已解析完毕 @Transactional(rollbackFor = Exception.class) - public PayTrade createOrder(NormalPayParam payParam) { + public void createOrder(NormalPayParam payParam, NormalPayContext context) { String appId = payParam.getAppId(); OffsetDateTime expiredTime = this.getExpiredTime(payParam.getExpiredTime()); Long amount = payParam.getAmount(); @@ -108,22 +109,23 @@ public class PayAssistService { trade.setBarCode(payParam.getAuthCode()); trade.setOpenid(payParam.getOpenId()); payTradeManager.save(trade); - return trade; + context.setContainer(normalOrder).setTrade(trade); } - /// 根据业务单号查询并检查支付状态(按商户号自动租户隔离) - public PayTrade getOrderAndCheck(String bizOrderNo) { + /// 查询已有订单并校验,结果填充到 context + /// 订单不存在则 context 保持不变(调用方据此判断是否新建) + public void findAndCheckOrder(String bizOrderNo, NormalPayContext context) { Optional normalOrderOpt = payNormalOrderManager.findByBizOrderNo(bizOrderNo); if (normalOrderOpt.isEmpty()) { - return null; + return; } NormalPayOrder normalOrder = normalOrderOpt.get(); PayTrade trade = payTradeManager.findByContainerId(normalOrder.getId()).orElse(null); if (trade == null) { - return null; + return; } this.checkOrder(normalOrder, trade); - return trade; + context.setContainer(normalOrder).setTrade(trade); } /// 检查订单状态 diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PayCloseService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PayCloseService.java index 42ed034b9..78da71018 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PayCloseService.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PayCloseService.java @@ -6,6 +6,7 @@ import cn.daxpay.open.platform.core.code.DaxPayErrorCode; import cn.daxpay.open.platform.core.exception.BizInfoException; import cn.daxpay.open.platform.core.exception.PayFailureException; import cn.daxpay.open.platform.core.exception.operation.OperationFailException; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.common.enums.PayFundStatusEnum; import cn.daxpay.open.payment.common.util.PaymentStrategyFactory; import cn.daxpay.open.payment.pay.order.dao.NormalPayOrderManager; @@ -74,10 +75,13 @@ public class PayCloseService { if (Objects.equals(PayFundStatusEnum.INIT.getCode(), trade.getStatus())) { payUniHandleService.payClose(trade, normalOrder); } else { + NormalPayContext context = new NormalPayContext() + .setContainer(normalOrder) + .setTrade(trade); AbsPayCloseStrategy strategy = PaymentStrategyFactory.createByProduct( trade.getProduct(), AbsPayCloseStrategy.class); - strategy.doBeforeClose(trade); - strategy.doClose(trade, useCancel); + strategy.doBeforeClose(context); + strategy.doClose(context, useCancel); payUniHandleService.payClose(trade, normalOrder); } } catch (Exception e) { diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PaySyncService.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PaySyncService.java index 305094edb..e5bd408ed 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PaySyncService.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/pay/service/PaySyncService.java @@ -7,6 +7,7 @@ import cn.daxpay.open.platform.core.exception.PayFailureException; import cn.daxpay.open.platform.core.exception.RepetitiveOperationException; import cn.daxpay.open.platform.core.exception.system.SystemUnknownErrorException; import cn.daxpay.open.platform.core.util.DateTimeUtil; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.common.enums.PayFundStatusEnum; import cn.daxpay.open.payment.common.util.PaymentStrategyFactory; import cn.daxpay.open.payment.pay.bo.PaySyncResultBo; @@ -85,9 +86,12 @@ public class PaySyncService { try { NormalPayOrder normalOrder = payNormalOrderManager.findById(trade.getContainerId()) .orElse(null); + NormalPayContext context = new NormalPayContext() + .setContainer(normalOrder) + .setTrade(trade); var syncStrategy = PaymentStrategyFactory.createByProduct( trade.getProduct(), AbsSyncPayOrderStrategy.class); - PaySyncResultBo syncResult = syncStrategy.doSync(trade); + PaySyncResultBo syncResult = syncStrategy.doSync(context); if (!Objects.equals(syncResult.getOutOrderNo(), trade.getOutOrderNo())) { trade.setOutOrderNo(syncResult.getOutOrderNo()); payTradeManager.updateById(trade); diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsNormalPayStrategy.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsNormalPayStrategy.java new file mode 100644 index 000000000..702177dca --- /dev/null +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsNormalPayStrategy.java @@ -0,0 +1,22 @@ +package cn.daxpay.open.payment.strategy.pay; + +import cn.daxpay.open.payment.common.context.NormalPayContext; +import cn.daxpay.open.payment.common.strategy.PaymentStrategy; +import cn.daxpay.open.payment.pay.bo.PayTradeResultBo; + +/// # 抽象普通支付策略基类 +/// +/// 策略为单例无状态,运行时数据通过 [NormalPayContext] 显式传递。 +/// 上下文同时携带容器(业务单)与资金凭证,策略无需再自查容器表。 +public abstract class AbsNormalPayStrategy implements PaymentStrategy { + + /// 支付前处理 包含必要的校验以及对当前通道支付配置信息的初始化 + /// 出现错误不会保存相关信息 + public void doBeforePay(NormalPayContext context) { + } + + /// 支付操作 + /// 出现错误会保存相关信息 + public abstract PayTradeResultBo doPay(NormalPayContext context); + +} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsPayCloseStrategy.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsPayCloseStrategy.java index 7bbda2676..a568e2a38 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsPayCloseStrategy.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsPayCloseStrategy.java @@ -1,22 +1,23 @@ package cn.daxpay.open.payment.strategy.pay; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.common.strategy.PaymentStrategy; import cn.daxpay.open.platform.core.enums.pay.pay.CloseTypeEnum; -import cn.daxpay.open.payment.pay.order.entity.PayTrade; /// # 支付关闭策略 /// -/// 策略为单例无状态,运行时数据通过方法参数显式传递。 +/// 策略为单例无状态,运行时数据通过 [NormalPayContext] 显式传递。 +/// 上下文同时携带容器(业务单)与资金凭证,策略无需再自查容器表。 public abstract class AbsPayCloseStrategy implements PaymentStrategy { /// 关闭前的处理方式 - public void doBeforeClose(PayTrade trade) { + public void doBeforeClose(NormalPayContext context) { } /// 关闭操作 - /// @param trade 资金交易凭证 + /// @param context 支付上下文(容器 + 资金凭证) /// @param useCancel 是否使用撤销方式进行订单关闭 /// @return 如果执行成功, 返回使用何种方式关闭的支付订单 - public abstract CloseTypeEnum doClose(PayTrade trade, boolean useCancel); + public abstract CloseTypeEnum doClose(NormalPayContext context, boolean useCancel); } diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsPayStrategy.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsPayStrategy.java deleted file mode 100644 index 6209c73c4..000000000 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/pay/AbsPayStrategy.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.daxpay.open.payment.strategy.pay; - -import cn.daxpay.open.payment.common.context.PayStrategyContext; -import cn.daxpay.open.payment.common.strategy.PaymentStrategy; -import cn.daxpay.open.payment.pay.bo.PayTradeResultBo; - -/// # 抽象支付策略基类 -/// -/// 策略为单例无状态,运行时数据通过 [PayStrategyContext] 显式传递。 -public abstract class AbsPayStrategy implements PaymentStrategy { - - /// 支付前处理 包含必要的校验以及对当前通道支付配置信息的初始化 - /// 出现错误不会保存相关信息 - public void doBeforePay(PayStrategyContext context) { - } - - /// 支付操作 - /// 出现错误会保存相关信息 - public abstract PayTradeResultBo doPay(PayStrategyContext context); - -} diff --git a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/sync/AbsSyncPayOrderStrategy.java b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/sync/AbsSyncPayOrderStrategy.java index 1de85db9d..4b10027de 100644 --- a/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/sync/AbsSyncPayOrderStrategy.java +++ b/daxpay-payment/daxpay-payment-common/src/main/java/cn/daxpay/open/payment/strategy/sync/AbsSyncPayOrderStrategy.java @@ -1,15 +1,16 @@ package cn.daxpay.open.payment.strategy.sync; +import cn.daxpay.open.payment.common.context.NormalPayContext; import cn.daxpay.open.payment.common.strategy.PaymentStrategy; import cn.daxpay.open.payment.pay.bo.PaySyncResultBo; -import cn.daxpay.open.payment.pay.order.entity.PayTrade; /// # 支付同步抽象类 /// -/// 策略为单例无状态,运行时数据通过方法参数显式传递。 +/// 策略为单例无状态,运行时数据通过 [NormalPayContext] 显式传递。 +/// 上下文同时携带容器(业务单)与资金凭证,策略无需再自查容器表。 public abstract class AbsSyncPayOrderStrategy implements PaymentStrategy { - /// 查询通道网关方的退款订单状态信息 - public abstract PaySyncResultBo doSync(PayTrade trade); + /// 查询通道网关方的支付订单状态信息 + public abstract PaySyncResultBo doSync(NormalPayContext context); }