diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/ClientEnvPayResolveService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/ClientEnvPayResolveService.java index c836e839a..d938b8acd 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/ClientEnvPayResolveService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/ClientEnvPayResolveService.java @@ -95,6 +95,7 @@ public class ClientEnvPayResolveService { return resolve(appId, clientEnv, runtime); } + /// 获取聚合配置的客户端环境配置, 不存在则抛异常 private GatewayAggregateClientEnv requireEnvConfig(GatewayAggregateConfig config, ClientEnvEnum clientEnv) { if (config == null) { throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/CodePayResolveService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/CodePayResolveService.java index f59cec222..d1b235833 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/CodePayResolveService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/CodePayResolveService.java @@ -81,6 +81,7 @@ public class CodePayResolveService { return inferred; } + /// 获取码牌配置的客户端环境与支付形态子表, 不存在则抛异常 private GatewayCodeClientEnv requireEnvConfig( GatewayCodeConfig config, ClientEnvEnum clientEnv, CodePayFormEnum payForm) { GatewayCodeClientEnv envConfig = clientEnvManager.findByConfigIdAndClientEnvAndPayForm( diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/GatewayAggregateConfigService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/GatewayAggregateConfigService.java index cbbc15728..0b994842d 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/GatewayAggregateConfigService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/GatewayAggregateConfigService.java @@ -150,6 +150,7 @@ public class GatewayAggregateConfigService { } /// 组装主表 + 客户端环境子表为 Result + /// 将聚合配置主表与子表组装为带客户端环境列表的结果对象 private GatewayAggregateConfigResult toResultWithClientEnvs(GatewayAggregateConfig entity) { GatewayAggregateConfigResult result = new GatewayAggregateConfigResult(); BeanUtil.copyProperties(entity, result); diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/GatewayCodeConfigService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/GatewayCodeConfigService.java index aef3e8fe1..ef3b80dbb 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/GatewayCodeConfigService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/merchant/service/gateway/GatewayCodeConfigService.java @@ -140,6 +140,7 @@ public class GatewayCodeConfigService { } } + /// 将码牌配置主表与子表组装为带客户端环境列表的结果对象 private GatewayCodeConfigResult toResultWithClientEnvs(GatewayCodeConfig entity) { GatewayCodeConfigResult result = new GatewayCodeConfigResult(); BeanUtil.copyProperties(entity, result); diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/notice/service/TradeNoticeBridge.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/notice/service/TradeNoticeBridge.java index f076d1f02..b9e30e054 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/notice/service/TradeNoticeBridge.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/notice/service/TradeNoticeBridge.java @@ -93,6 +93,7 @@ public class TradeNoticeBridge { .setContentOrRef(content)); } + /// 判断资金凭证是否为网关支付类型 private boolean isGateway(PayTrade trade) { return Objects.equals(trade.getTradeType(), PayTradeTypeEnum.GATEWAY.getCode()); } diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/NormalPayOrderService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/NormalPayOrderService.java index d9e322dfb..08f685c68 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/NormalPayOrderService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/NormalPayOrderService.java @@ -78,6 +78,7 @@ public class NormalPayOrderService { payCloseService.closeOrder(trade, useCancel); } + /// 商户端清空入参 mchNo, 避免越权查询他商户数据 private void sanitizeQuery(NormalPayOrderQuery query) { if (query == null) { return; @@ -87,6 +88,7 @@ public class NormalPayOrderService { } } + /// 运营端翻译商户名称(mchNo → mchName) private void translateIfAdmin(Object target) { if (ClientEnum.ADMIN.getCode().equals(clientCodeService.getClientCode())) { // 翻译商户名称(mchNo -> mchName) diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/PayTradeService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/PayTradeService.java index e156fbcbe..09ea39c8f 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/PayTradeService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/PayTradeService.java @@ -85,6 +85,7 @@ public class PayTradeService { } } + /// 运营端翻译商户名称(mchNo → mchName) private void translateIfAdmin(Object target) { if (ClientEnum.ADMIN.getCode().equals(clientCodeService.getClientCode())) { // 翻译商户名称(mchNo -> mchName) diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/RefundOrderService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/RefundOrderService.java index c8ebe2cba..a137c4d22 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/RefundOrderService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/RefundOrderService.java @@ -74,6 +74,7 @@ public class RefundOrderService { return result; } + /// 商户端清空入参 mchNo, 避免越权查询他商户数据 private void sanitizeQuery(RefundOrderQuery query) { if (query == null) { return; @@ -83,6 +84,7 @@ public class RefundOrderService { } } + /// 运营端翻译商户名称(mchNo → mchName) private void translateIfAdmin(Object target) { if (ClientEnum.ADMIN.getCode().equals(clientCodeService.getClientCode())) { // 翻译商户名称(mchNo -> mchName) diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/TradeOrderDetailAssembler.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/TradeOrderDetailAssembler.java index 088bf4606..1bd1ed3e8 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/TradeOrderDetailAssembler.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/order/service/TradeOrderDetailAssembler.java @@ -70,6 +70,7 @@ public class TradeOrderDetailAssembler { } } + /// 普通支付容器详情补充资金凭证字段(tradeNo/outOrderNo/资金状态/可退余额) private void fillFundOnContainerResult(NormalPayOrderResult result, PayTrade trade) { if (trade == null) { return; @@ -80,6 +81,7 @@ public class TradeOrderDetailAssembler { result.setRefundableBalance(trade.getRefundableBalance()); } + /// 网关支付容器详情补充资金凭证字段(含关联订单号) private void fillFundOnGatewayResult(GatewayPayOrderResult result, PayTrade trade) { if (trade == null) { return; @@ -91,6 +93,7 @@ public class TradeOrderDetailAssembler { result.setRelationOrderNo(trade.getRelationOrderNo()); } + /// 资金交易详情补充普通支付容器业务字段(产品/通道/买家/过期时间等) private void fillFromNormal(PayTradeResult result, NormalPayOrder order) { result.setContainerOrderNo(order.getOrderNo()); result.setBizOrderNo(order.getBizOrderNo()); @@ -116,6 +119,7 @@ public class TradeOrderDetailAssembler { result.setExpiredTime(order.getExpiredTime()); } + /// 资金交易详情补充网关支付容器业务字段(产品/通道/买家/过期时间等) private void fillFromGateway(PayTradeResult result, GatewayPayOrder order) { result.setContainerOrderNo(order.getOrderNo()); result.setBizOrderNo(order.getBizOrderNo()); diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/PayTradeContainerFields.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/PayTradeContainerFields.java index bf3559d28..93bb9b686 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/PayTradeContainerFields.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/PayTradeContainerFields.java @@ -58,6 +58,7 @@ public class PayTradeContainerFields { .orElse(null); } + /// 判断资金凭证是否为网关支付类型 private boolean isGateway(PayTrade trade) { return Objects.equals(trade.getTradeType(), PayTradeTypeEnum.GATEWAY.getCode()); } diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/close/PayCloseService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/close/PayCloseService.java index 73ca55766..6fcfc9938 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/close/PayCloseService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/close/PayCloseService.java @@ -188,6 +188,7 @@ public class PayCloseService { } } + /// 记录关单流水(含成功/失败标记) private void saveRecord(PayTrade trade, CloseTypeEnum closeType, String errMsg) { ContainerInfo info = loadContainerInfo(trade); PayCloseRecord record = new PayCloseRecord() diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/common/PayRiskAssistService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/common/PayRiskAssistService.java index f97306b2f..626868fdf 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/common/PayRiskAssistService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/common/PayRiskAssistService.java @@ -82,6 +82,7 @@ public class PayRiskAssistService { } } + /// 从支付参数构建风控检查上下文 private PayRiskCheckContext buildContextFromParam(NormalPayParam payParam, String scene) { PayRiskCheckContext ctx = new PayRiskCheckContext() .setScene(StrUtil.blankToDefault(scene, resolveSceneFromSource(payParam.getSource()))) @@ -97,6 +98,7 @@ public class PayRiskAssistService { return ctx; } + /// 从资金凭证构建风控检查上下文(含容器回查) private PayRiskCheckContext buildContextFromTrade(PayTrade trade) { PayRiskCheckContext ctx = new PayRiskCheckContext() .setTradeNo(trade.getTradeNo()) @@ -138,6 +140,7 @@ public class PayRiskAssistService { return ctx; } + /// 从产品编码反推通道编码填入风控上下文 private static void fillChannelByProduct(PayRiskCheckContext ctx, String product) { if (StrUtil.isBlank(product)) { return; @@ -149,6 +152,7 @@ public class PayRiskAssistService { } } + /// 交易来源 → 风控场景编码: 码牌→code, 其余→api private static String resolveSceneFromSource(String source) { if (StrUtil.isNotBlank(source) && TradeSourceEnum.CASHIER_CODE.getCode().equals(source)) { return "code"; diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/common/PayUniHandleService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/common/PayUniHandleService.java index c3e701a91..ed2c57f0a 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/common/PayUniHandleService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/common/PayUniHandleService.java @@ -282,6 +282,7 @@ public class PayUniHandleService { gatewayPayOrderManager.updateById(order); } + /// 普通容器置已支付, 同步 provider 回填 private void markContainerPaid(PayTrade trade, NormalPayOrder order) { if (order == null) { return; @@ -316,6 +317,7 @@ public class PayUniHandleService { } } + /// 容器置关闭(CLOSED)或超时(EXPIRED) private void markContainerClosed(PayTrade trade, OffsetDateTime now, boolean expired, String errMsg) { if (isGateway(trade)) { GatewayPayOrder order = gatewayPayOrderManager.findById(trade.getContainerId()).orElse(null); @@ -352,6 +354,7 @@ public class PayUniHandleService { return errMsg.length() <= 500 ? errMsg : errMsg.substring(0, 500); } + /// 普通容器写入支付回执字段(transOrderNo/buyerId/payBody 等) private void applyNormalReceipts(NormalPayOrder order, PayTradeResultBo result) { order.setTransOrderNo(result.getTransOrderNo()); // 特殊通道返回变形上送号时回写容器展示; 空则保留创建时的 orderNo 副本 @@ -370,6 +373,7 @@ public class PayUniHandleService { order.setErrorMsg(null); } + /// 网关容器写入支付回执字段(transOrderNo/buyerId/payBody 等) private void applyGatewayReceipts(GatewayPayOrder order, PayTradeResultBo result) { order.setTransOrderNo(result.getTransOrderNo()); if (result.getRelationOrderNo() != null) { @@ -387,6 +391,7 @@ public class PayUniHandleService { order.setErrorMsg(null); } + /// 普通容器写入同步查单回执字段(含 provider 回填) private void applyNormalSyncReceipts(PayTrade trade, NormalPayOrder order, PaySyncResultBo syncResult) { if (syncResult == null) { return; @@ -410,6 +415,7 @@ public class PayUniHandleService { order.setErrorMsg(null); } + /// 网关容器写入同步查单回执字段(含 provider 回填) private void applyGatewaySyncReceipts(PayTrade trade, GatewayPayOrder order, PaySyncResultBo syncResult) { if (syncResult == null) { return; @@ -447,6 +453,7 @@ public class PayUniHandleService { } } + /// provider 兜底填充: trade 空则从网关容器 provider/method 派生 private void applyProviderFallback(PayTrade trade, GatewayPayOrder order) { String containerProvider = order != null ? order.getProvider() : null; String method = order != null ? order.getMethod() : null; @@ -460,6 +467,7 @@ public class PayUniHandleService { } } + /// 判断资金凭证是否为网关支付类型 private boolean isGateway(PayTrade trade) { return Objects.equals(trade.getTradeType(), PayTradeTypeEnum.GATEWAY.getCode()); } diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/CashierPayService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/CashierPayService.java index d4cf3f7ab..01f411c5a 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/CashierPayService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/CashierPayService.java @@ -187,6 +187,7 @@ public class CashierPayService { return env.getCode(); } + /// 映射公开支付项(脱敏路由敏感字段, 注入 needOpenId 判定) private CashierItemPublicResult toPublicResult(GatewayCashierItem item, ClientEnvEnum clientEnv) { // DIRECT 模式下 method 被强制清空(见 GatewayCashierConfigService#normalizeAndValidate), // 此时用 capability 兜底判断 needOpenId; capability 与 PayMethodEnum 同码(如 wechat_jsapi), diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayAuthService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayAuthService.java index 2b1fa10fe..f404f1e5b 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayAuthService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayAuthService.java @@ -191,6 +191,7 @@ public class GatewayAuthService { null); } + /// 加载收银台支付项并校验归属与类型分桶 private GatewayCashierItem loadAndCheckItem(Long itemId, String appId, GatewayCashierTypeEnum typeEnum, String bucketClientEnv) { GatewayCashierItem item = gatewayCashierItemManager.findById(itemId) @@ -215,6 +216,7 @@ public class GatewayAuthService { return item; } + /// 规范化分桶用 clientEnv: WEB 固定 null; H5 五档; MINI 四档(无 browser) private String normalizeClientEnvForBucket(GatewayCashierTypeEnum typeEnum, String clientEnv) { if (!typeEnum.requiresClientEnv()) { return null; diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayOrderQueryService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayOrderQueryService.java index 9d6933a34..0e04b4ee6 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayOrderQueryService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayOrderQueryService.java @@ -23,6 +23,7 @@ public class GatewayOrderQueryService { private final PayTradeManager payTradeManager; private final MerchantContextLoader merchantContextLoader; + /// 按 orderNo 或 bizOrderNo 查询网关订单 public GatewayOrderResult query(GatewayOrderQueryParam param) { if (StrUtil.isBlank(param.getOrderNo()) && StrUtil.isBlank(param.getBizOrderNo())) { throw new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR, "pay.error.orderNoRequired"); @@ -54,6 +55,7 @@ public class GatewayOrderQueryService { return this.toResult(order); } + /// 网关订单实体 → 查询结果 DTO(含关联资金交易号) public GatewayOrderResult toResult(GatewayPayOrder order) { GatewayOrderResult result = new GatewayOrderResult() .setOrderNo(order.getOrderNo()) diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayPayAssistService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayPayAssistService.java index 6ccbab51b..a018a7df2 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayPayAssistService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayPayAssistService.java @@ -91,6 +91,10 @@ public class GatewayPayAssistService { ); } + /// 预下单事务体: 幂等校验 → 新建容器订单 → 返回落地页 URL + /// + /// - 已有未终态单则直接返回原 URL + /// - PAID/failed/closed/expired 视为终态拒绝重入 @Transactional(rollbackFor = Exception.class) public GatewayPrePayResult doPrePay(GatewayPrePayParam param, GatewayPayTypeEnum typeEnum) { // 幂等: 已有未终态单则返回原 URL @@ -187,6 +191,7 @@ public class GatewayPayAssistService { return gatewayBase + "/cashier/" + order.getOrderNo(); } + /// 构建预下单返回结果(含落地页 URL) public GatewayPrePayResult buildPrePayResult(GatewayPayOrder order) { return new GatewayPrePayResult() .setOrderNo(order.getOrderNo()) @@ -196,6 +201,7 @@ public class GatewayPayAssistService { .setExpiredTime(order.getExpiredTime()); } + /// 注册网关超时关单延时消息(失败由定时任务兜底) private void registerTimeout(String orderNo, String bizOrderNo, OffsetDateTime expiredTime) { GatewayTimeoutMessage message = new GatewayTimeoutMessage() .setOrderNo(orderNo) diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayPayHandleService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayPayHandleService.java index 91669c8d5..9c42fdf6e 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayPayHandleService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/pay/gateway/GatewayPayHandleService.java @@ -203,6 +203,7 @@ public class GatewayPayHandleService { return this.buildResult(latest, trade); } + /// 回填路由结果到网关容器(channelMchNo/capability/channelAppId/clientEnv/device 等) private void fillRouteOnOrder(GatewayPayOrder order, NormalPayParam payParam, String clientEnv, String device) { order.setChannelMchNo(payParam.getChannelMchNo()); order.setCapability(payParam.getCapability()); @@ -219,6 +220,7 @@ public class GatewayPayHandleService { } } + /// 组装路由与支付用请求参数(从网关容器拷贝业务字段) private NormalPayParam buildPayParam(GatewayPayOrder order, String product, String method, String channelMchNo, String capability, String openId, String clientIp) { @@ -247,6 +249,7 @@ public class GatewayPayHandleService { return payParam; } + /// 构建网关支付返回结果(含 payBody 供前端拉起) private NormalPayResult buildResult(GatewayPayOrder order, PayTrade trade) { return new NormalPayResult() .setOrderId(order.getId()) diff --git a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/sync/PaySyncService.java b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/sync/PaySyncService.java index e7facf61b..1699201e3 100644 --- a/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/sync/PaySyncService.java +++ b/daxpay-payment/daxpay-payment-core/src/main/java/cn/daxpay/open/payment/trade/runtime/service/sync/PaySyncService.java @@ -122,6 +122,10 @@ public class PaySyncService { ); } + /// 校验同步结果是否需要调整 + /// + /// - PROCESSING 且未超时则无需调整 + /// - 已超时或通道返回 SUCCESS 但本地已 CLOSE 时触发调整 private boolean checkAndAdjust(PaySyncResultBo syncResult, PayTrade trade, ContainerInfo info) { var payStatus = Optional.ofNullable(syncResult.getPayStatus()) .orElse(PayFundStatusEnum.PROCESSING); @@ -150,6 +154,7 @@ public class PaySyncService { return false; } + /// 根据同步结果执行状态调整: SUCCESS→回写成功; CLOSE→远程或本地关单; FAIL→标记失败 private void adjustHandler(PaySyncResultBo syncResult, PayTrade trade, ContainerInfo info) { var payStatus = syncResult.getPayStatus(); if (Objects.isNull(payStatus)) { @@ -170,6 +175,7 @@ public class PaySyncService { } } + /// 将交易置为成功并回写支付时间, 通道回执交由 payUniHandleService 统一处理 private void success(PayTrade trade, PaySyncResultBo syncResult) { trade.setStatus(PayFundStatusEnum.SUCCESS.getCode()); trade.setPayTime(syncResult.getFinishTime()); @@ -178,6 +184,7 @@ public class PaySyncService { payUniHandleService.paySuccess(trade, syncResult); } + /// 远程关单: 调用通道关闭策略后本地超时关闭 private void closeRemote(PayTrade trade, ContainerInfo info) { var context = new PayStrategyContext() .setTrade(trade) @@ -192,6 +199,7 @@ public class PaySyncService { payUniHandleService.payTimeout(trade); } + /// 记录支付同步流水(含通道同步快照与是否调整标记) private void saveRecord(PayTrade trade, PaySyncResultBo syncResult, boolean adjust, ContainerInfo info) { PaySyncRecord record = new PaySyncRecord() .setAppId(trade.getAppId()) diff --git a/daxpay-payment/daxpay-payment-unipay/src/main/java/cn/daxpay/open/payment/unipay/client/service/CodePayAssistService.java b/daxpay-payment/daxpay-payment-unipay/src/main/java/cn/daxpay/open/payment/unipay/client/service/CodePayAssistService.java index c7b24d948..2fa3bb399 100644 --- a/daxpay-payment/daxpay-payment-unipay/src/main/java/cn/daxpay/open/payment/unipay/client/service/CodePayAssistService.java +++ b/daxpay-payment/daxpay-payment-unipay/src/main/java/cn/daxpay/open/payment/unipay/client/service/CodePayAssistService.java @@ -230,6 +230,11 @@ public class CodePayAssistService { } } + /// 加载已启用且已分配商户的码牌实体 + /// + /// - 查无记录 → DataNotExistException + /// - 状态非 ENABLED → 码牌未启用 + /// - mchNo 为空 → 码牌未分配商户 private DeviceQrCode loadEnabledAssigned(String code) { DeviceQrCode entity = deviceQrCodeManager.findByCode(code) .orElseThrow(() -> new DataNotExistException("error.device.qrcode.notFound")); @@ -244,6 +249,10 @@ public class CodePayAssistService { return entity; } + /// 按码牌金额类型解析实际支付金额(分) + /// + /// - FIXED: 返回码牌固定金额(须 > 0) + /// - 其他: 返回请求金额(须 > 0) private long resolveAmount(DeviceQrCode entity, Long requestAmount) { QrCodeAmountTypeEnum amountType = QrCodeAmountTypeEnum.findByCode(entity.getAmountType()); if (amountType == QrCodeAmountTypeEnum.FIXED) { @@ -311,6 +320,9 @@ public class CodePayAssistService { return "/h/" + segment + "/" + code + "?authed=1"; } + /// 客户端环境映射为通道授权类型 + /// + /// 支付宝/微信/抖音各对应其授权类型; 其他环境默认回退微信 private String mapAuthType(ClientEnvEnum clientEnv) { return switch (clientEnv) { case ALIPAY -> ChannelAuthTypeEnum.ALIPAY.getCode();