From a35fc472fcf3bb9b0d59760364d1c3517d4ff7a6 Mon Sep 17 00:00:00 2001 From: bootx Date: Sun, 21 Apr 2024 23:08:38 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E6=94=AF=E4=BB=98=E5=92=8C=E9=80=80?= =?UTF-8?q?=E6=AC=BE=E9=87=8D=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- _config/sql/dax-pay.sql | 2 +- _doc/Task.md | 9 +- .../sdk/param/refund/RefundChannelParam.java | 1 + .../controller/channel/AlipayController.java | 1 - .../channel/UnionPayController.java | 1 - .../controller/channel/WalletController.java | 1 - .../channel/WeChatPayController.java | 1 - .../controller/order/PayOrderController.java | 1 - .../order/RefundOrderController.java | 4 +- .../platform/daxpay/code/PayChannelEnum.java | 2 + .../{PayWayEnum.java => PayMethodEnum.java} | 6 +- .../daxpay/param/payment/pay/PayParam.java | 15 +- .../param/payment/pay/QueryPayParam.java | 2 +- .../payment/refund/QueryRefundParam.java | 2 +- .../param/payment/refund/RefundParam.java | 10 +- .../param/payment/refund/RefundSyncParam.java | 2 +- .../platform/daxpay/result/CommonResult.java | 19 + .../daxpay/result/order/PayOrderResult.java | 41 +- .../platform/daxpay/result/pay/PayResult.java | 27 +- .../daxpay/util/OrderNoGenerateUtil.java | 41 +- .../bootx/platform/daxpay/util/PayUtil.java | 61 +-- .../gateway/controller/UniPayController.java | 16 - .../daxpay/service/code/AliPayCode.java | 2 +- .../daxpay/service/code/AliPayWay.java | 10 +- ...Enum.java => TradeFlowRecordTypeEnum.java} | 4 +- .../daxpay/service/code/UnionPayWay.java | 10 +- .../daxpay/service/code/WalletPayWay.java | 8 +- .../daxpay/service/code/WeChatPayWay.java | 10 +- .../service/common/context/CallbackLocal.java | 10 +- .../service/common/context/PayLocal.java | 23 +- .../alipay/service/AliPayCallbackService.java | 10 +- .../alipay/service/AliPayRecordService.java | 73 ---- .../channel/alipay/service/AliPayService.java | 33 +- .../union/convert/UnionPayConvert.java | 7 - .../union/dao/UnionPayRecordManager.java | 44 -- .../union/dao/UnionPayRecordMapper.java | 14 - .../channel/union/entity/UnionPayRecord.java | 63 --- .../service/UnionPayCallbackService.java | 8 +- .../union/service/UnionPayRecordService.java | 72 --- .../union/service/UnionPayService.java | 33 +- .../wallet/service/WalletPayService.java | 6 +- .../wallet/service/WalletRecordService.java | 132 ------ .../channel/wallet/service/WalletService.java | 3 - .../wechat/entity/WeChatPayRecord.java | 4 +- .../service/WeChatPayCallbackService.java | 8 +- .../service/WeChatPayRecordService.java | 74 ---- .../wechat/service/WeChatPayService.java | 35 +- .../core/order/pay/builder/PayBuilder.java | 86 +--- .../core/order/pay/dao/PayOrderManager.java | 15 +- .../order/pay/entity/PayChannelOrder.java | 2 +- .../core/order/pay/entity/PayOrder.java | 48 +- .../core/order/pay/entity/PayOrderExtra.java | 49 +-- .../pay/service/PayChannelOrderService.java | 119 ----- .../pay/service/PayOrderQueryService.java | 39 +- .../order/pay/service/PayOrderService.java | 21 +- .../refund/dao/RefundChannelOrderManager.java | 1 + .../refund/dao/RefundChannelOrderMapper.java | 1 + .../order/refund/dao/RefundOrderManager.java | 8 + .../refund/entity/RefundChannelOrder.java | 1 + .../core/order/refund/entity/RefundOrder.java | 55 +-- .../order/refund/entity/RefundOrderExtra.java | 29 +- .../refund/service/RefundOrderService.java | 8 +- .../callback/service/PayCallbackService.java | 4 +- .../service/RefundCallbackService.java | 2 +- .../close/service/PayCloseService.java | 2 +- .../strategy/WalletPayCloseStrategy.java | 5 +- .../notice/result/PayChannelResult.java | 5 +- .../notice/result/PayNoticeResult.java | 35 +- .../notice/result/RefundChannelResult.java | 1 + .../service/ClientNoticeAssistService.java | 34 +- .../notice/service/ClientNoticeService.java | 10 +- .../pay/factory/PayStrategyFactory.java | 75 +--- .../payment/pay/service/PayAssistService.java | 146 +++---- .../core/payment/pay/service/PayService.java | 413 ++++-------------- .../payment/pay/strategy/AliPayStrategy.java | 47 +- .../pay/strategy/UnionPayStrategy.java | 46 +- .../pay/strategy/WalletPayStrategy.java | 21 +- .../pay/strategy/WeChatPayStrategy.java | 46 +- .../strategy/AlipayReconcileStrategy.java | 6 +- .../strategy/UnionPayReconcileStrategy.java | 4 - .../strategy/WechatPayReconcileStrategy.java | 2 - .../refund/factory/RefundStrategyFactory.java | 88 +--- .../refund/service/RefundAssistService.java | 128 ++---- .../payment/refund/service/RefundService.java | 210 +++------ .../refund/strategy/AliRefundStrategy.java | 2 - .../refund/strategy/UnionRefundStrategy.java | 2 - .../refund/strategy/WalletRefundStrategy.java | 1 - .../refund/strategy/WeChatRefundStrategy.java | 2 - .../strategy/pay/AliPayRepairStrategy.java | 1 - .../strategy/pay/UnionPayRepairStrategy.java | 1 - .../strategy/pay/WalletPayRepairStrategy.java | 1 - .../strategy/pay/WeChatPayRepairStrategy.java | 1 - .../refund/AliRefundRepairStrategy.java | 1 - .../refund/WalletRefundRepairStrategy.java | 1 - .../refund/WeChatRefundRepairStrategy.java | 1 - .../payment/sync/service/PaySyncService.java | 2 +- .../flow/convert/TradeFlowRecordConvert.java | 12 + .../flow/dao/TradeFlowRecordManager.java | 18 + .../flow/dao/TradeFlowRecordMapper.java | 14 + .../record/flow/entity/TradeFlowRecord.java | 61 +++ .../flow/service/TradeFlowRecordService.java | 16 + .../service/func/AbsCallbackStrategy.java | 2 +- .../daxpay/service/func/AbsPayStrategy.java | 28 -- .../service/func/AbsRefundStrategy.java | 54 +-- .../param/order/PayOrderRefundParam.java | 24 +- 106 files changed, 838 insertions(+), 2184 deletions(-) rename daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/{PayWayEnum.java => PayMethodEnum.java} (86%) rename daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/{WechatPayRecordTypeEnum.java => TradeFlowRecordTypeEnum.java} (82%) delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayRecordService.java delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/dao/UnionPayRecordManager.java delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/dao/UnionPayRecordMapper.java delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/entity/UnionPayRecord.java delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayRecordService.java delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletRecordService.java delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayRecordService.java delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/service/PayChannelOrderService.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/convert/TradeFlowRecordConvert.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/dao/TradeFlowRecordManager.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/dao/TradeFlowRecordMapper.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/entity/TradeFlowRecord.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/service/TradeFlowRecordService.java diff --git a/README.md b/README.md index 8c90ccc8..fc22b1a3 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,9 @@ > DaxPay是一套基于Bootx-Platform脚手架构建的开源支付网关系统,已经对接支付宝、微信支付相关的接口,以及扩展了钱包支付、储值卡支付、现金支付等新的支付方式。 > 可以独立部署,提供接口供业务系统进行调用,不对原有系统产生影响 -> **gateway为开发分支,本地运行请使用master分支进行测试** +gateway为开发分支,本地运行请使用master分支进行测试,当前正在进行整个系统的优化重构工作,**请勿在生产环境中使用,请等待生产可用的版本发布**, + + ## 🧭 特色功能 - 封装各类支付通道的接口为统一的接口,方便业务系统进行调用,简化对接多种支付方式的复杂度 - 已对接`微信支付`、`支付宝`和云闪付相关的接口,后续版本将支持`V3`版本的接口 diff --git a/_config/sql/dax-pay.sql b/_config/sql/dax-pay.sql index 4baa8622..de463c61 100644 --- a/_config/sql/dax-pay.sql +++ b/_config/sql/dax-pay.sql @@ -3008,7 +3008,7 @@ CREATE TABLE `pay_platform_config` ( -- ---------------------------- -- Records of pay_platform_config -- ---------------------------- -INSERT INTO `pay_platform_config` VALUES (0, 'http://127.0.0.1', 'HMAC_SHA256', '123456', 'http://127.0.0.1/h5/#/result/success', 'http://127.0.0.1/h5/#/result/success', 30, 0, '2024-01-02 20:23:19', 1757299137932677120, '2024-02-13 15:08:51', 3, b'0', NULL); +INSERT INTO `pay_platform_config` VALUES (0, 'http://127.0.0.1', 'HMAC_SHA256', '123456', 'http://127.0.0.1/h5/#/result/success', 'http://127.0.0.1/h5/#/result/success', 30, 0, '2024-01-02 20:23:19', 1757299137932677120, '2024-02-13 15:08:51', 3, b'0', 2000); -- ---------------------------- -- Table structure for pay_reconcile_detail diff --git a/_doc/Task.md b/_doc/Task.md index 9bc0bd41..619817f6 100644 --- a/_doc/Task.md +++ b/_doc/Task.md @@ -1,7 +1,10 @@ ## 单商户 2.0.6: 去除组合支付, 一系列代码优化 -- [ ] 删除现金支付和储值卡支付方式 +- [x] 删除现金支付和储值卡支付方式 - [ ] 支付订单 + - [x] 支付改造 + - [ ] 回调改造 + - [x] 发送通知改造 - [ ] 去除组合支付和场景,降低逻辑的的复杂度 - [ ] 退款场景 - [ ] 关闭支付订单 @@ -10,8 +13,10 @@ - [ ] 支付和退款回调 - [ ] 去除现金支付和储值卡支付方式 - [ ] 三方支付外部订单号规则优化: 支付P、退款R、分账A,根据环境加前缀:DEV_、DEMO_、PRE_ -- [ ] 资金流水优化(去除) +- [ ] 资金流水优化 - [ ] 金额显示统一使用元 +- [ ] 响应数据和通知数据全部都进行签名 +- [ ] 数据加密方式改为类型处理器模式 2.0.7: 分账完善 - [ ] 支持分账组分账和自己传接收方进行分账 diff --git a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/RefundChannelParam.java b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/RefundChannelParam.java index d8f8cf89..9abbc0d3 100644 --- a/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/RefundChannelParam.java +++ b/daxpay-single-sdk/src/main/java/cn/bootx/platform/daxpay/sdk/param/refund/RefundChannelParam.java @@ -13,6 +13,7 @@ import lombok.ToString; @Getter @Setter @ToString +@Deprecated public class RefundChannelParam { /** diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/AlipayController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/AlipayController.java index 134f23ff..4c66add5 100644 --- a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/AlipayController.java +++ b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/AlipayController.java @@ -4,7 +4,6 @@ import cn.bootx.platform.common.core.rest.PageResult; import cn.bootx.platform.common.core.rest.Res; import cn.bootx.platform.common.core.rest.ResResult; import cn.bootx.platform.common.core.rest.param.PageParam; -import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayRecordService; import cn.bootx.platform.daxpay.service.dto.channel.alipay.AliPayRecordDto; import cn.bootx.platform.daxpay.service.param.channel.alipay.AliPayRecordQuery; import io.swagger.v3.oas.annotations.Operation; diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/UnionPayController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/UnionPayController.java index 083e967f..cc8c426a 100644 --- a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/UnionPayController.java +++ b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/UnionPayController.java @@ -4,7 +4,6 @@ import cn.bootx.platform.common.core.rest.PageResult; import cn.bootx.platform.common.core.rest.Res; import cn.bootx.platform.common.core.rest.ResResult; import cn.bootx.platform.common.core.rest.param.PageParam; -import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayRecordService; import cn.bootx.platform.daxpay.service.dto.channel.union.UnionPayRecordDto; import cn.bootx.platform.daxpay.service.param.channel.union.UnionPayRecordQuery; import io.swagger.v3.oas.annotations.Operation; diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/WalletController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/WalletController.java index c18c4b4f..c90e41c0 100644 --- a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/WalletController.java +++ b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/WalletController.java @@ -6,7 +6,6 @@ import cn.bootx.platform.common.core.rest.ResResult; import cn.bootx.platform.common.core.rest.param.PageParam; import cn.bootx.platform.common.core.util.ValidationUtil; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletQueryService; -import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletRecordService; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletService; import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletDto; import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletRecordDto; diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/WeChatPayController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/WeChatPayController.java index aff648d5..7b1a1848 100644 --- a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/WeChatPayController.java +++ b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/channel/WeChatPayController.java @@ -4,7 +4,6 @@ import cn.bootx.platform.common.core.rest.PageResult; import cn.bootx.platform.common.core.rest.Res; import cn.bootx.platform.common.core.rest.ResResult; import cn.bootx.platform.common.core.rest.param.PageParam; -import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayRecordService; import cn.bootx.platform.daxpay.service.dto.channel.wechat.WeChatPayRecordDto; import cn.bootx.platform.daxpay.service.param.channel.wechat.WeChatPayRecordQuery; import io.swagger.v3.oas.annotations.Operation; diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/PayOrderController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/PayOrderController.java index 4c3bcc2c..d2d89046 100644 --- a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/PayOrderController.java +++ b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/PayOrderController.java @@ -10,7 +10,6 @@ import cn.bootx.platform.daxpay.param.payment.pay.PaySyncParam; import cn.bootx.platform.daxpay.param.payment.allocation.AllocationStartParam; import cn.bootx.platform.daxpay.result.pay.SyncResult; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; -import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService; import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderExtraService; import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService; import cn.bootx.platform.daxpay.service.core.payment.allocation.service.AllocationService; diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/RefundOrderController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/RefundOrderController.java index 69a29d59..13ba764d 100644 --- a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/RefundOrderController.java +++ b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/RefundOrderController.java @@ -74,9 +74,9 @@ public class RefundOrderController { @Operation(summary = "退款同步") @PostMapping("/syncById") - public ResResult syncById(Long id){ + public ResResult syncById(String refundNo){ RefundSyncParam refundSyncParam = new RefundSyncParam(); - refundSyncParam.setRefundId(id); + refundSyncParam.setRefundNo(refundNo); return Res.ok(refundSyncService.sync(refundSyncParam)); } } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayChannelEnum.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayChannelEnum.java index 73ea9bbe..efffe918 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayChannelEnum.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayChannelEnum.java @@ -45,8 +45,10 @@ public enum PayChannelEnum { } /** 异步支付通道 */ + @Deprecated public static final List ASYNC_TYPE = Collections.unmodifiableList(Arrays.asList(ALI, WECHAT, UNION_PAY)); /** 异步支付通道的编码 */ + @Deprecated public static final List ASYNC_TYPE_CODE = Collections.unmodifiableList(Arrays.asList(ALI.code, WECHAT.code, UNION_PAY.code)); } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayWayEnum.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayMethodEnum.java similarity index 86% rename from daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayWayEnum.java rename to daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayMethodEnum.java index 93abc50f..932e53ca 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayWayEnum.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayMethodEnum.java @@ -15,7 +15,7 @@ import java.util.Objects; */ @Getter @AllArgsConstructor -public enum PayWayEnum { +public enum PayMethodEnum { NORMAL("normal", "常规支付"), WAP("wap", "wap支付"), @@ -36,8 +36,8 @@ public enum PayWayEnum { /** * 根据字符编码获取 */ - public static PayWayEnum findByCode(String code) { - return Arrays.stream(PayWayEnum.values()) + public static PayMethodEnum findByCode(String code) { + return Arrays.stream(PayMethodEnum.values()) .filter(e -> Objects.equals(code, e.getCode())) .findFirst() .orElseThrow(() -> new PayFailureException("不存在的支付方式")); diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/pay/PayParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/pay/PayParam.java index 0afc9202..54eb7745 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/pay/PayParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/pay/PayParam.java @@ -1,7 +1,7 @@ package cn.bootx.platform.daxpay.param.payment.pay; import cn.bootx.platform.daxpay.code.PayChannelEnum; -import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.code.PayMethodEnum; import cn.bootx.platform.daxpay.param.PaymentCommonParam; import cn.bootx.platform.daxpay.param.channel.AliPayParam; import cn.bootx.platform.daxpay.param.channel.WalletPayParam; @@ -31,7 +31,7 @@ public class PayParam extends PaymentCommonParam { @Schema(description = "商户订单号") @NotBlank(message = "商户订单号不可为空") - private String outTradeNo; + private String bizOrderNo; @Schema(description = "支付标题") @NotBlank(message = "支付标题不可为空") @@ -55,11 +55,11 @@ public class PayParam extends PaymentCommonParam { private String channel; /** - * @see PayWayEnum#getCode() + * @see PayMethodEnum#getCode() */ @Schema(description = "支付方式编码") - @NotBlank(message = "支付方式编码不可为空") - private String way; + @NotBlank(message = "支付方式不可为空") + private String method; @Schema(description = "支付金额") @NotNull(message = "支付金额不可为空") @@ -67,12 +67,13 @@ public class PayParam extends PaymentCommonParam { private Integer amount; /** + * 支付扩展参数 * @see AliPayParam * @see WeChatPayParam * @see WalletPayParam */ - @Schema(description = "通道附加支付参数") - private Map channelParam; + @Schema(description = "支付扩展参数") + private Map extraParam; /** 商户扩展参数,回调时会原样返回 */ @Schema(description = "商户扩展参数,回调时会原样返回") diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/pay/QueryPayParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/pay/QueryPayParam.java index 18976c61..9d655bed 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/pay/QueryPayParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/pay/QueryPayParam.java @@ -19,5 +19,5 @@ public class QueryPayParam extends PaymentCommonParam { private String orderNo; @Schema(description = "商户订单号") - private String outTradeNo; + private String bizOrderNo; } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/QueryRefundParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/QueryRefundParam.java index 0e3dd296..1704abb7 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/QueryRefundParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/QueryRefundParam.java @@ -19,5 +19,5 @@ public class QueryRefundParam extends PaymentCommonParam { private String refundNo; @Schema(description = "商户退款号") - private String outRefundNo; + private String bizRefundNo; } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/RefundParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/RefundParam.java index 323d40ce..e759f5d1 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/RefundParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/RefundParam.java @@ -27,19 +27,19 @@ public class RefundParam extends PaymentCommonParam { */ @Schema(description = "商户退款号") @NotBlank(message = "商户退款号不可为空") - private String outRefundNo; + private String bizRefundNo; /** - * 支付操作是返回的订单号,与商户订单号至少要传输一个,同时传输以订单号为准 + * 支付订单号,与商户订单号至少要传输一个,同时传输以订单号为准 */ @Schema(description = "订单号") private String orderNo; /** - * 支付操作时传入的的商户订单号,与订单号至少要传输一个,同时传输以订单号为准 + * 商户支付订单号,与订单号至少要传输一个,同时传输以订单号为准 */ @Schema(description = "商户订单号") - private String outTradeNo; + private String bizOrderNo; @Schema(description = "退款金额") @Min(value = 1,message = "退款金额至少为0.01元") @@ -52,7 +52,7 @@ public class RefundParam extends PaymentCommonParam { * @see WalletPayParam */ @Schema(description = "退款扩展参数") - private Map channelParam; + private Map extraParam; @Schema(description = "退款原因") private String reason; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/RefundSyncParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/RefundSyncParam.java index 2c9436e0..8a392a06 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/RefundSyncParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/payment/refund/RefundSyncParam.java @@ -19,6 +19,6 @@ public class RefundSyncParam extends PaymentCommonParam { private String refundNo; @Schema(description = "商户退款号") - private String outRefundNo; + private String bizRefundNo; } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/CommonResult.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/CommonResult.java index efdd8599..5afcdc05 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/CommonResult.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/CommonResult.java @@ -1,7 +1,12 @@ package cn.bootx.platform.daxpay.result; +import cn.bootx.platform.daxpay.serializer.LocalDateTimeToTimestampSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; /** * 支付通用返回参数 @@ -9,7 +14,21 @@ import lombok.Data; * @since 2023/12/25 */ @Data +@Accessors(chain = true) @Schema(title = "支付通用返回参数") public class CommonResult { + @Schema(description = "响应数据签名值") + private String sign; + + @Schema(description = "错误码") + private String code; + + @Schema(description = "错误信息") + private String msg; + + @Schema(description = "响应时间") + @JsonSerialize(using = LocalDateTimeToTimestampSerializer.class) + private LocalDateTime resTime; + } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/order/PayOrderResult.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/order/PayOrderResult.java index 6f73307e..da771118 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/order/PayOrderResult.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/order/PayOrderResult.java @@ -11,10 +11,9 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.time.LocalDateTime; -import java.util.List; /** - * 支付单响应参数 + * 支付单茶香返回参数 * @author xxm * @since 2024/1/16 */ @@ -24,13 +23,13 @@ import java.util.List; @Schema(title = "支付单响应参数") public class PayOrderResult extends CommonResult { - /** 支付ID */ - @Schema(description = "支付ID") - private Long paymentId; + /** 支付订单号 */ + @Schema(description = "支付订单号") + private String orderNo; - /** 业务号 */ + /** 业务系统订单号 */ @Schema(description = "业务号") - private String businessNo; + private String bizOrderNo; /** 标题 */ @Schema(description = "标题") @@ -40,20 +39,18 @@ public class PayOrderResult extends CommonResult { @Schema(description = "描述") private String description; - /** 是否是异步支付 */ - @Schema(description = "是否是异步支付") - private boolean asyncPay; - - /** 是否是组合支付 */ - @Schema(description = "是否是组合支付") - private boolean combinationPay; - /** - * 异步支付通道 - * @see PayChannelEnum#ASYNC_TYPE_CODE + * 支付通道 + * @see PayChannelEnum */ @Schema(description = "异步支付通道") - private String asyncChannel; + private String channel; + + /** + * 支付方式 + */ + @Schema(description = "支付方式") + private String method; /** 金额 */ @Schema(description = "金额") @@ -80,6 +77,10 @@ public class PayOrderResult extends CommonResult { @JsonSerialize(using = LocalDateTimeToTimestampSerializer.class) private LocalDateTime expiredTime; - @Schema(description = "支付通道列表") - private List channels; + /** 关闭时间 */ + @Schema(description = "过期时间") + @JsonSerialize(using = LocalDateTimeToTimestampSerializer.class) + private LocalDateTime closeTime; + + } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/pay/PayResult.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/pay/PayResult.java index db86ba12..ba1ea3bb 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/pay/PayResult.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/pay/PayResult.java @@ -1,7 +1,5 @@ package cn.bootx.platform.daxpay.result.pay; -import cn.bootx.platform.daxpay.code.PayChannelEnum; -import cn.bootx.platform.daxpay.code.PayStatusEnum; import cn.bootx.platform.daxpay.result.CommonResult; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -19,27 +17,16 @@ import lombok.experimental.Accessors; @Schema(title = "统一下单响应参数") public class PayResult extends CommonResult { - @Schema(description = "支付ID") - private Long paymentId; + @Schema(description = "商户订单号") + private String bizOrderNo; - @Schema(description = "是否是异步支付") - private boolean asyncPay; + @Schema(description = "订单号") + private String orderNo; - /** - * @see PayChannelEnum#ASYNC_TYPE_CODE - */ - @Schema(description = "异步支付通道") - private String asyncChannel; - - - /** 支付参数体(通常用于发起异步支付的参数) */ - @Schema(description = "支付参数体") - private String payBody; - - /** - * @see PayStatusEnum - */ @Schema(description = "支付状态") private String status; + /** 支付参数体(通常用于发起支付的参数) */ + @Schema(description = "支付参数体") + private String payBody; } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/OrderNoGenerateUtil.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/OrderNoGenerateUtil.java index bab1737b..84658fd4 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/OrderNoGenerateUtil.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/OrderNoGenerateUtil.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.util; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; @@ -16,7 +17,8 @@ public class OrderNoGenerateUtil { private static final AtomicLong ATOMIC_LONG = new AtomicLong(); private final static long ORDER_MAX_LIMIT = 999999L; - + /** 机器号 */ + @Setter private static String machineNo; /** @@ -26,8 +28,7 @@ public class OrderNoGenerateUtil { StringBuilder orderNo = new StringBuilder(); String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")); long id = ATOMIC_LONG.incrementAndGet(); - log.info("dataStr:{},id:{}", dateStr, id); - orderNo.append("T").append(dateStr).append(machineNo).append(String.format("%06d", Math.abs(id) % ORDER_MAX_LIMIT)); + orderNo.append("P").append(dateStr).append(machineNo).append(String.format("%06d", Math.abs(id) % ORDER_MAX_LIMIT)); return orderNo.toString(); } @@ -38,12 +39,40 @@ public class OrderNoGenerateUtil { StringBuilder orderNo = new StringBuilder(); String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")); long id = ATOMIC_LONG.incrementAndGet(); - log.info("dataStr:{},id:{}", dateStr, id); orderNo.append("R").append(dateStr).append(machineNo).append(String.format("%06d", Math.abs(id) % ORDER_MAX_LIMIT)); return orderNo.toString(); } - public static void setMachineNo(String machineNo) { - OrderNoGenerateUtil.machineNo = machineNo; + /** + * 生成转账订单号 + */ + public static String transfer() { + StringBuilder orderNo = new StringBuilder(); + String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")); + long id = ATOMIC_LONG.incrementAndGet(); + orderNo.append("T").append(dateStr).append(machineNo).append(String.format("%06d", Math.abs(id) % ORDER_MAX_LIMIT)); + return orderNo.toString(); + } + + /** + * 生成分账订单号 + */ + public static String allocation() { + StringBuilder orderNo = new StringBuilder(); + String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")); + long id = ATOMIC_LONG.incrementAndGet(); + orderNo.append("A").append(dateStr).append(machineNo).append(String.format("%06d", Math.abs(id) % ORDER_MAX_LIMIT)); + return orderNo.toString(); + } + + /** + * 生成对账订单号 + */ + public static String reconciliation() { + StringBuilder orderNo = new StringBuilder(); + String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")); + long id = ATOMIC_LONG.incrementAndGet(); + orderNo.append("C").append(dateStr).append(machineNo).append(String.format("%06d", Math.abs(id) % ORDER_MAX_LIMIT)); + return orderNo.toString(); } } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/PayUtil.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/PayUtil.java index b29c307b..4016fc0a 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/PayUtil.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/util/PayUtil.java @@ -1,16 +1,13 @@ package cn.bootx.platform.daxpay.util; import cn.bootx.platform.common.core.util.LocalDateTimeUtil; -import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException; -import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.param.payment.pay.PayParam; import cn.hutool.core.date.DatePattern; import lombok.experimental.UtilityClass; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; -import java.util.List; /** * 支付工具类 @@ -25,56 +22,16 @@ public class PayUtil { */ public void validation(PayParam payParam) { // 验证支付金额 - validationAmount(payParam.getPayChannels()); - // 验证异步支付方式 - validationAsyncPay(payParam); - // 验证是否可以分账 - validationAllocation(payParam); - } - - /** - * 验证是否可以分账 - */ - private void validationAllocation(PayParam payParam) { - // 如果分账不启用, 不需要校验 - if (!payParam.isAllocation()) { - return; - } - // 只有异步支付方式支持分账 - if (isNotSync(payParam.getPayChannels())) { - throw new PayFailureException("分账只支持包含异步支付通道的订单"); - } - } - - - /** - * 检查异步支付方式 - */ - public void validationAsyncPay(PayParam payParam) { - // 组合支付时只允许有一个异步支付方式 - List payModeList = payParam.getPayChannels(); - - long asyncPayCount = payModeList.stream() - .map(PayChannelParam::getChannel) - .map(PayChannelEnum::findByCode) - .filter(PayChannelEnum.ASYNC_TYPE::contains) - .count(); - if (asyncPayCount > 1) { - throw new PayFailureException("组合支付时只允许有一个异步支付方式"); - } - + validationAmount(payParam); } /** * 检查支付金额 */ - public void validationAmount(List payModeList) { + public void validationAmount(PayParam param) { // 验证支付金额 - for (PayChannelParam payChannelParam : payModeList) { - // 支付金额小于等于零 - if (payChannelParam.getAmount() < 0) { - throw new PayAmountAbnormalException(); - } + if (param.getAmount() <= 0) { + throw new PayAmountAbnormalException("支付金额不能小于等于0"); } } @@ -105,14 +62,4 @@ public class PayUtil { public LocalDateTime getPaymentExpiredTime(Integer minute) { return LocalDateTimeUtil.offset(LocalDateTime.now(), minute, ChronoUnit.MINUTES); } - - /** - * 判断是否有异步支付 - */ - public boolean isNotSync(List payChannelParams) { - return payChannelParams.stream() - .map(PayChannelParam::getChannel) - .noneMatch(PayChannelEnum.ASYNC_TYPE_CODE::contains); - } - } diff --git a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayController.java b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayController.java index a15bd75f..0585de65 100644 --- a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayController.java +++ b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/UniPayController.java @@ -58,14 +58,6 @@ public class UniPayController { return DaxRes.ok(payService.pay(payParam)); } - @CountTime - @PaymentApi(PaymentApiCode.SIMPLE_PAY) - @Operation(summary = "简单支付接口") - @PostMapping("/simplePay") - public DaxResult simplePay(@RequestBody SimplePayParam payParam){ - return DaxRes.ok(payService.simplePay(payParam)); - } - @CountTime @PaymentApi(PaymentApiCode.CLOSE) @Operation(summary = "支付关闭接口") @@ -83,14 +75,6 @@ public class UniPayController { return DaxRes.ok(refundService.refund(param)); } - @CountTime - @PaymentApi(PaymentApiCode.SIMPLE_REFUND) - @Operation(summary = "简单退款接口") - @PostMapping("/simpleRefund") - public DaxResult simpleRefund(@RequestBody SimpleRefundParam param){ - return DaxRes.ok(refundService.simpleRefund(param)); - } - @CountTime @PaymentApi(PaymentApiCode.SYNC_PAY) @Operation(summary = "支付同步接口") diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AliPayCode.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AliPayCode.java index bb029961..cc19133c 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AliPayCode.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AliPayCode.java @@ -41,7 +41,7 @@ public interface AliPayCode { /** 对交易或商品的描述(在没有公用回传参数的时候, 这个作为公用回传参数) */ String BODY = "body"; - /** 外部支付订单号 */ + /** 外部支付订单号 - 商户订单号 */ String OUT_TRADE_NO = "out_trade_no"; /** 支付流水号 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AliPayWay.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AliPayWay.java index ec1376a5..f29d9cdf 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AliPayWay.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AliPayWay.java @@ -1,6 +1,6 @@ package cn.bootx.platform.daxpay.service.code; -import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.code.PayMethodEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import lombok.experimental.UtilityClass; @@ -18,13 +18,13 @@ import java.util.Objects; public class AliPayWay { // 支付方式 - private static final List PAY_WAYS = Arrays.asList(PayWayEnum.WAP, PayWayEnum.APP, PayWayEnum.WEB, - PayWayEnum.QRCODE, PayWayEnum.BARCODE); + private static final List PAY_WAYS = Arrays.asList(PayMethodEnum.WAP, PayMethodEnum.APP, PayMethodEnum.WEB, + PayMethodEnum.QRCODE, PayMethodEnum.BARCODE); /** * 根据编码获取 */ - public PayWayEnum findByCode(String code) { + public PayMethodEnum findByCode(String code) { return PAY_WAYS.stream() .filter(e -> Objects.equals(code, e.getCode())) .findFirst() @@ -34,7 +34,7 @@ public class AliPayWay { /** * 获取支持的支付方式 */ - public List getPayWays() { + public List getPayWays() { return PAY_WAYS; } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WechatPayRecordTypeEnum.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/TradeFlowRecordTypeEnum.java similarity index 82% rename from daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WechatPayRecordTypeEnum.java rename to daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/TradeFlowRecordTypeEnum.java index 88e85135..271d5b8e 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WechatPayRecordTypeEnum.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/TradeFlowRecordTypeEnum.java @@ -4,13 +4,13 @@ import lombok.AllArgsConstructor; import lombok.Getter; /** - * 微信支付流水记录类型 + * 交易流水记录类型 * @author xxm * @since 2024/2/20 */ @Getter @AllArgsConstructor -public enum WechatPayRecordTypeEnum { +public enum TradeFlowRecordTypeEnum { /** 支付 */ PAY("pay", "支付"), diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/UnionPayWay.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/UnionPayWay.java index a71ce80f..2b07a60c 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/UnionPayWay.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/UnionPayWay.java @@ -1,6 +1,6 @@ package cn.bootx.platform.daxpay.service.code; -import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.code.PayMethodEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import lombok.experimental.UtilityClass; @@ -17,13 +17,13 @@ import java.util.Objects; public class UnionPayWay { // 支付方式 - private static final List PAY_WAYS = Arrays.asList(PayWayEnum.WAP, PayWayEnum.APP, PayWayEnum.WEB, - PayWayEnum.JSAPI, PayWayEnum.QRCODE, PayWayEnum.BARCODE ); + private static final List PAY_WAYS = Arrays.asList(PayMethodEnum.WAP, PayMethodEnum.APP, PayMethodEnum.WEB, + PayMethodEnum.JSAPI, PayMethodEnum.QRCODE, PayMethodEnum.BARCODE ); /** * 根据编码获取 */ - public PayWayEnum findByCode(String code) { + public PayMethodEnum findByCode(String code) { return PAY_WAYS.stream() .filter(e -> Objects.equals(code, e.getCode())) .findFirst() @@ -33,7 +33,7 @@ public class UnionPayWay { /** * 获取支持的支付方式 */ - public List getPayWays() { + public List getPayWays() { return PAY_WAYS; } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WalletPayWay.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WalletPayWay.java index 073a03d9..fdb66818 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WalletPayWay.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WalletPayWay.java @@ -1,6 +1,6 @@ package cn.bootx.platform.daxpay.service.code; -import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.code.PayMethodEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import lombok.experimental.UtilityClass; @@ -17,12 +17,12 @@ import java.util.Objects; public class WalletPayWay { // 支付方式 - private static final List PAY_WAYS = Collections.singletonList(PayWayEnum.NORMAL); + private static final List PAY_WAYS = Collections.singletonList(PayMethodEnum.NORMAL); /** * 根据编码获取 */ - public PayWayEnum findByCode(String code) { + public PayMethodEnum findByCode(String code) { return PAY_WAYS.stream() .filter(e -> Objects.equals(code, e.getCode())) .findFirst() @@ -32,7 +32,7 @@ public class WalletPayWay { /** * 获取支持的支付方式 */ - public List getPayWays() { + public List getPayWays() { return PAY_WAYS; } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WeChatPayWay.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WeChatPayWay.java index a72e2b1a..10aecca8 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WeChatPayWay.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/WeChatPayWay.java @@ -1,6 +1,6 @@ package cn.bootx.platform.daxpay.service.code; -import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.code.PayMethodEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import lombok.experimental.UtilityClass; @@ -17,13 +17,13 @@ import java.util.Objects; @UtilityClass public class WeChatPayWay { - private static final List PAY_WAYS = Arrays.asList(PayWayEnum.WAP, PayWayEnum.APP, PayWayEnum.JSAPI, - PayWayEnum.QRCODE, PayWayEnum.BARCODE); + private static final List PAY_WAYS = Arrays.asList(PayMethodEnum.WAP, PayMethodEnum.APP, PayMethodEnum.JSAPI, + PayMethodEnum.QRCODE, PayMethodEnum.BARCODE); /** * 根据数字编号获取 */ - public PayWayEnum findByCode(String code) { + public PayMethodEnum findByCode(String code) { return PAY_WAYS.stream() .filter(e -> Objects.equals(code, e.getCode())) .findFirst() @@ -33,7 +33,7 @@ public class WeChatPayWay { /** * 获取支持的支付方式 */ - public List getPayWays() { + public List getPayWays() { return PAY_WAYS; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/CallbackLocal.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/CallbackLocal.java index 0db14f1a..5451b9c0 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/CallbackLocal.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/CallbackLocal.java @@ -23,20 +23,20 @@ public class CallbackLocal { /** 回调参数内容 */ private Map callbackParam = new HashMap<>(); - /** 本地订单ID */ - private Long orderId; + /** 订单号, 支付/退款 */ + private String orderNo; /** * 第三方支付平台订单号 */ - private String gatewayOrderNo; + private String outOrderNo; /** - * 网关返回状态 + * 三方支付系统返回状态 * @see PayStatusEnum 支付状态 * @see RefundStatusEnum 退款状态 */ - private String gatewayStatus; + private String outStatus; /** 金额(元) */ private String amount; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/PayLocal.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/PayLocal.java index 55240900..42435583 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/PayLocal.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/PayLocal.java @@ -1,15 +1,11 @@ package cn.bootx.platform.daxpay.service.common.context; -import cn.bootx.platform.daxpay.code.PayWayEnum; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra; import lombok.Data; import lombok.experimental.Accessors; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; /** * 异步支付信息 @@ -20,25 +16,23 @@ import java.util.List; @Accessors(chain = true) public class PayLocal { - /** - * 异步支付方式 - * @see PayWayEnum - */ - private String payWay; - /** * 第三方支付网关生成的订单号, 用与将记录关联起来 * 1. 如付款码支付直接成功时会出现 + * 2. 部分通道创建订单是会直接返回 */ - private String gatewayOrderNo; + private String outOrderNo; /** 是否支付完成 */ - private boolean payComplete; + private boolean complete; + + /** 完成时间 */ + private LocalDateTime completeTime; /** 支付参数体(通常用于发起支付的参数) */ private String payBody; - /** 订单失效时间, */ + /** 订单超时时间, */ private LocalDateTime expiredTime; /** 支付订单 */ @@ -47,7 +41,4 @@ public class PayLocal { /** 支付订单扩展 */ private PayOrderExtra payOrderExtra; - /** 通道支付订单 */ - private List payChannelOrders = new ArrayList<>(); - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayCallbackService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayCallbackService.java index caca6964..a2dca23b 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayCallbackService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayCallbackService.java @@ -89,12 +89,12 @@ public class AliPayCallbackService extends AbsCallbackStrategy { CallbackLocal callback = PaymentContextLocal.get().getCallbackInfo(); Map callbackParam = callback.getCallbackParam(); // 网关订单号 - callback.setGatewayOrderNo(callbackParam.get(TRADE_NO)); + callback.setOutOrderNo(callbackParam.get(TRADE_NO)); // 支付订单ID - callback.setOrderId(Long.valueOf(callbackParam.get(OUT_TRADE_NO))); + callback.setOrderNo(callbackParam.get(OUT_TRADE_NO)); // 支付状态 PayStatusEnum payStatus = Objects.equals(callbackParam.get(TRADE_STATUS), NOTIFY_TRADE_SUCCESS) ? PayStatusEnum.SUCCESS : PayStatusEnum.FAIL; - callback.setGatewayStatus(payStatus.getCode()); + callback.setOutStatus(payStatus.getCode()); // 支付金额 callback.setAmount(callbackParam.get(TOTAL_AMOUNT)); @@ -117,9 +117,9 @@ public class AliPayCallbackService extends AbsCallbackStrategy { CallbackLocal callback = PaymentContextLocal.get().getCallbackInfo(); Map callbackParam = callback.getCallbackParam(); // 退款订单Id - callback.setOrderId(Long.valueOf(callbackParam.get(OUT_BIZ_NO))); + callback.setOrderNo(callbackParam.get(OUT_BIZ_NO)); // 退款状态 - callback.setGatewayStatus(callbackParam.get(TRADE_STATUS)); + callback.setOutStatus(callbackParam.get(TRADE_STATUS)); // 退款金额 callback.setAmount(callbackParam.get(REFUND_FEE)); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayRecordService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayRecordService.java deleted file mode 100644 index caba7cb7..00000000 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayRecordService.java +++ /dev/null @@ -1,73 +0,0 @@ -package cn.bootx.platform.daxpay.service.core.channel.alipay.service; - -import cn.bootx.platform.common.core.exception.DataNotExistException; -import cn.bootx.platform.common.core.rest.PageResult; -import cn.bootx.platform.common.core.rest.param.PageParam; -import cn.bootx.platform.common.mybatisplus.util.MpUtil; -import cn.bootx.platform.daxpay.service.code.AliPayRecordTypeEnum; -import cn.bootx.platform.daxpay.service.core.channel.alipay.dao.AliPayRecordManager; -import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayRecord; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; -import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrder; -import cn.bootx.platform.daxpay.service.dto.channel.alipay.AliPayRecordDto; -import cn.bootx.platform.daxpay.service.param.channel.alipay.AliPayRecordQuery; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -/** - * 支付宝流水 - * @author xxm - * @since 2024/2/1+9 - */ -@Slf4j -@Service -@RequiredArgsConstructor -public class AliPayRecordService { - - private final AliPayRecordManager aliPayRecordManager; - - /** - * 支付 - */ - public void pay(PayOrder order, PayChannelOrder channelOrder){ - AliPayRecord aliPayRecord = new AliPayRecord() - .setType(AliPayRecordTypeEnum.PAY.getCode()) - .setTitle(order.getTitle()) - .setOrderId(order.getId()) - .setAmount(channelOrder.getAmount()) - .setGatewayOrderNo(order.getGatewayOrderNo()) - .setGatewayTime(channelOrder.getPayTime()); - aliPayRecordManager.save(aliPayRecord); - } - - /** - * 退款 - */ - public void refund(RefundOrder order, RefundChannelOrder channelOrder){ - AliPayRecord aliPayRecord = new AliPayRecord() - .setType(AliPayRecordTypeEnum.REFUND.getCode()) - .setTitle(order.getTitle()) - .setOrderId(order.getId()) - .setAmount(channelOrder.getAmount()) - .setGatewayOrderNo(order.getGatewayOrderNo()) - .setGatewayTime(channelOrder.getRefundTime()); - aliPayRecordManager.save(aliPayRecord); - } - - /** - * 分页 - */ - public PageResult page(PageParam pageParam, AliPayRecordQuery param){ - return MpUtil.convert2DtoPageResult(aliPayRecordManager.page(pageParam, param)); - } - - /** - * 查询详情 - */ - public AliPayRecordDto findById(Long id){ - return aliPayRecordManager.findById(id).map(AliPayRecord::toDto).orElseThrow(DataNotExistException::new); - } -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayService.java index 1341daf3..95926d2c 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayService.java @@ -1,8 +1,9 @@ package cn.bootx.platform.daxpay.service.core.channel.alipay.service; -import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.code.PayMethodEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.param.channel.AliPayParam; +import cn.bootx.platform.daxpay.param.payment.pay.PayParam; import cn.bootx.platform.daxpay.service.code.AliPayCode; import cn.bootx.platform.daxpay.service.code.AliPayWay; import cn.bootx.platform.daxpay.service.common.context.PayLocal; @@ -45,49 +46,53 @@ public class AliPayService { /** * 支付前检查支付方式是否可用 */ - public void validation(PayChannelParam payChannelParam, AliPayConfig alipayConfig) { + public void validation(PayParam payParam, AliPayConfig alipayConfig) { if (CollUtil.isEmpty(alipayConfig.getPayWays())){ throw new PayFailureException("支付宝未配置可用的支付方式"); } // 发起的支付类型是否在支持的范围内 - PayWayEnum payWayEnum = Optional.ofNullable(AliPayWay.findByCode(payChannelParam.getWay())) + PayMethodEnum payMethodEnum = Optional.ofNullable(AliPayWay.findByCode(payParam.getMethod())) .orElseThrow(() -> new PayFailureException("非法的支付宝支付类型")); - if (!alipayConfig.getPayWays().contains(payWayEnum.getCode())) { + if (!alipayConfig.getPayWays().contains(payMethodEnum.getCode())) { throw new PayFailureException("该支付宝支付方式不可用"); } // 验证订单金额是否超限 - if(payChannelParam.getAmount() > alipayConfig.getSingleLimit()){ + if(payParam.getAmount() > alipayConfig.getSingleLimit()){ throw new PayFailureException("支付宝支付金额超过限额"); } + // 支付参数开启分账, 配置未开启分账 + if(payParam.isAllocation() && !Objects.equals(alipayConfig.getAllocation(),true)){ + throw new PayFailureException("未开启分账配置"); + } } /** * 调起支付 */ - public void pay(PayOrder payOrder, PayChannelParam payChannelParam, AliPayParam aliPayParam, AliPayConfig alipayConfig) { - Integer amount = payChannelParam.getAmount(); + public void pay(PayOrder payOrder, AliPayParam aliPayParam, AliPayConfig alipayConfig) { + Integer amount = payOrder.getAmount(); String payBody = null; // 异步线程存储 PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo(); // wap支付 - if (Objects.equals(payChannelParam.getWay(), PayWayEnum.WAP.getCode())) { + if (Objects.equals(payOrder.getMethod(), PayMethodEnum.WAP.getCode())) { payBody = this.wapPay(amount, payOrder, alipayConfig); } // 程序支付 - else if (Objects.equals(payChannelParam.getWay(), PayWayEnum.APP.getCode())) { + else if (Objects.equals(payOrder.getMethod(), PayMethodEnum.APP.getCode())) { payBody = this.appPay(amount, payOrder, alipayConfig); } // pc支付 - else if (Objects.equals(payChannelParam.getWay(), PayWayEnum.WEB.getCode())) { + else if (Objects.equals(payOrder.getMethod(), PayMethodEnum.WEB.getCode())) { payBody = this.webPay(amount, payOrder, alipayConfig); } // 二维码支付 - else if (Objects.equals(payChannelParam.getWay(), PayWayEnum.QRCODE.getCode())) { + else if (Objects.equals(payOrder.getMethod(), PayMethodEnum.QRCODE.getCode())) { payBody = this.qrCodePay(amount, payOrder, alipayConfig); } // 付款码支付 - else if (Objects.equals(payChannelParam.getWay(), PayWayEnum.BARCODE.getCode())) { + else if (Objects.equals(payOrder.getMethod(), PayMethodEnum.BARCODE.getCode())) { this.barCode(amount, payOrder, aliPayParam, alipayConfig); } // 通常是发起支付的参数 @@ -254,8 +259,8 @@ public class AliPayService { // 支付成功处理 金额2000以下免密支付, 记录支付完成相关信息 if (Objects.equals(response.getCode(), AliPayCode.SUCCESS)) { - asyncPayInfo.setGatewayOrderNo(response.getTradeNo()) - .setPayComplete(true); + asyncPayInfo.setOutOrderNo(response.getTradeNo()) + .setComplete(true); } // 非支付中响应码, 进行错误处理 if (!Objects.equals(response.getCode(), AliPayCode.INPROCESS)) { diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/convert/UnionPayConvert.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/convert/UnionPayConvert.java index e26e41cf..ca262be4 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/convert/UnionPayConvert.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/convert/UnionPayConvert.java @@ -1,10 +1,7 @@ package cn.bootx.platform.daxpay.service.core.channel.union.convert; import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayConfig; -import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayRecord; -import cn.bootx.platform.daxpay.service.core.payment.reconcile.domain.GeneralReconcileRecord; import cn.bootx.platform.daxpay.service.dto.channel.union.UnionPayConfigDto; -import cn.bootx.platform.daxpay.service.dto.channel.union.UnionPayRecordDto; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -19,8 +16,4 @@ public interface UnionPayConvert { UnionPayConfigDto convert(UnionPayConfig in); - UnionPayRecordDto convert(UnionPayRecord in); - - GeneralReconcileRecord convertReconcileRecord(UnionPayRecord in); - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/dao/UnionPayRecordManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/dao/UnionPayRecordManager.java deleted file mode 100644 index a053391a..00000000 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/dao/UnionPayRecordManager.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.bootx.platform.daxpay.service.core.channel.union.dao; - -import cn.bootx.platform.common.core.rest.param.PageParam; -import cn.bootx.platform.common.mybatisplus.impl.BaseManager; -import cn.bootx.platform.common.mybatisplus.util.MpUtil; -import cn.bootx.platform.common.query.generator.QueryGenerator; -import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayRecord; -import cn.bootx.platform.daxpay.service.param.channel.union.UnionPayRecordQuery; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Repository; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * @author xxm - * @since 2022/3/11 - */ -@Slf4j -@Repository -@RequiredArgsConstructor -public class UnionPayRecordManager extends BaseManager { - - /** - * 分页 - */ - public Page page(PageParam pageParam, UnionPayRecordQuery param){ - Page mpPage = MpUtil.getMpPage(pageParam, UnionPayRecord.class); - QueryWrapper generator = QueryGenerator.generator(param); - return this.page(mpPage, generator); - } - - /** - * 按时间范围查询 - */ - public List findByDate(LocalDateTime startDate, LocalDateTime endDate){ - return this.lambdaQuery() - .between(UnionPayRecord::getGatewayTime, startDate, endDate) - .list(); - } -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/dao/UnionPayRecordMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/dao/UnionPayRecordMapper.java deleted file mode 100644 index 56b85581..00000000 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/dao/UnionPayRecordMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.bootx.platform.daxpay.service.core.channel.union.dao; - -import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayRecord; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.apache.ibatis.annotations.Mapper; - -/** - * @author xxm - * @since 2022/3/11 - */ -@Mapper -public interface UnionPayRecordMapper extends BaseMapper { - -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/entity/UnionPayRecord.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/entity/UnionPayRecord.java deleted file mode 100644 index 46a89d0d..00000000 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/entity/UnionPayRecord.java +++ /dev/null @@ -1,63 +0,0 @@ -package cn.bootx.platform.daxpay.service.core.channel.union.entity; - -import cn.bootx.platform.common.core.function.EntityBaseFunction; -import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; -import cn.bootx.platform.daxpay.service.code.UnionPayRecordTypeEnum; -import cn.bootx.platform.daxpay.service.core.channel.union.convert.UnionPayConvert; -import cn.bootx.platform.daxpay.service.dto.channel.union.UnionPayRecordDto; -import cn.bootx.table.modify.annotation.DbColumn; -import cn.bootx.table.modify.annotation.DbTable; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.experimental.Accessors; - -import java.time.LocalDateTime; - -/** - * 云闪付流水记录 - * @author xxm - * @since 2024/2/19 - */ -@EqualsAndHashCode(callSuper = true) -@Data -@DbTable(comment = "云闪付流水记录") -@Accessors(chain = true) -@TableName("pay_union_pay_record") -public class UnionPayRecord extends MpCreateEntity implements EntityBaseFunction { - - /** 标题 */ - @DbColumn(comment = "标题") - private String title; - - /** 金额 */ - @DbColumn(comment = "金额") - private Integer amount; - - /** - * 业务类型 - * @see UnionPayRecordTypeEnum - */ - @DbColumn(comment = "业务类型") - private String type; - - /** 本地订单号 */ - @DbColumn(comment = "本地订单号") - private Long orderId; - - /** 网关订单号 */ - @DbColumn(comment = "网关订单号") - private String gatewayOrderNo; - - /** 网关完成时间 */ - @DbColumn(comment = "网关完成时间") - private LocalDateTime gatewayTime; - - /** - * 转换 - */ - @Override - public UnionPayRecordDto toDto() { - return UnionPayConvert.CONVERT.convert(this); - } -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayCallbackService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayCallbackService.java index 007629e1..1f458edb 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayCallbackService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayCallbackService.java @@ -85,14 +85,14 @@ public class UnionPayCallbackService extends AbsCallbackStrategy { Map callbackParam = callbackInfo.getCallbackParam(); // 网关订单号 - callbackInfo.setGatewayOrderNo(callbackParam.get(QUERY_ID)); + callbackInfo.setOutOrderNo(callbackParam.get(QUERY_ID)); // 支付订单ID callbackInfo.setOrderId(Long.valueOf(callbackParam.get(ORDER_ID))); // 支付结果 String resultCode = callbackParam.get(UnionPayCode.RESP_CODE); PayStatusEnum payStatus = UnionPayCode.RESP_SUCCESS.equals(resultCode) ? PayStatusEnum.SUCCESS : PayStatusEnum.FAIL; - callbackInfo.setGatewayStatus(payStatus.getCode()); + callbackInfo.setOutStatus(payStatus.getCode()); // 支付金额 callbackInfo.setAmount(callbackParam.get(UnionPayCode.TXN_AMT)); String timeEnd = callbackParam.get(TXN_TIME); @@ -115,7 +115,7 @@ public class UnionPayCallbackService extends AbsCallbackStrategy { CallbackLocal callbackInfo = PaymentContextLocal.get().getCallbackInfo(); Map callbackParam = callbackInfo.getCallbackParam(); // 网关订单号 - callbackInfo.setGatewayOrderNo(callbackParam.get(QUERY_ID)); + callbackInfo.setOutOrderNo(callbackParam.get(QUERY_ID)); // 退款订单Id callbackInfo.setOrderId(Long.valueOf(callbackParam.get(ORDER_ID))); // 退款金额 @@ -124,7 +124,7 @@ public class UnionPayCallbackService extends AbsCallbackStrategy { // 交易状态 String resultCode = callbackParam.get(UnionPayCode.RESP_CODE); RefundStatusEnum refundStatus = UnionPayCode.RESP_SUCCESS.equals(resultCode) ? RefundStatusEnum.SUCCESS : RefundStatusEnum.FAIL; - callbackInfo.setGatewayStatus(refundStatus.getCode()); + callbackInfo.setOutStatus(refundStatus.getCode()); // 退款时间 String timeEnd = callbackParam.get(TXN_TIME); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayRecordService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayRecordService.java deleted file mode 100644 index c7b4214f..00000000 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayRecordService.java +++ /dev/null @@ -1,72 +0,0 @@ -package cn.bootx.platform.daxpay.service.core.channel.union.service; - -import cn.bootx.platform.common.core.exception.DataNotExistException; -import cn.bootx.platform.common.core.rest.PageResult; -import cn.bootx.platform.common.core.rest.param.PageParam; -import cn.bootx.platform.common.mybatisplus.util.MpUtil; -import cn.bootx.platform.daxpay.service.code.UnionPayRecordTypeEnum; -import cn.bootx.platform.daxpay.service.core.channel.union.dao.UnionPayRecordManager; -import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayRecord; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; -import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrder; -import cn.bootx.platform.daxpay.service.dto.channel.union.UnionPayRecordDto; -import cn.bootx.platform.daxpay.service.param.channel.union.UnionPayRecordQuery; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -/** - * 云闪付支付记录服务 - * @author xxm - * @since 2024/3/7 - */ -@Slf4j -@Service -@RequiredArgsConstructor -public class UnionPayRecordService { - private final UnionPayRecordManager unionPayRecordManager; - - /** - * 支付 - */ - public void pay(PayOrder order, PayChannelOrder channelOrder){ - UnionPayRecord unionPayRecord = new UnionPayRecord() - .setType(UnionPayRecordTypeEnum.PAY.getCode()) - .setTitle(order.getTitle()) - .setOrderId(order.getId()) - .setAmount(channelOrder.getAmount()) - .setGatewayOrderNo(order.getGatewayOrderNo()) - .setGatewayTime(channelOrder.getPayTime()); - unionPayRecordManager.save(unionPayRecord); - } - - /** - * 退款 - */ - public void refund(RefundOrder order, RefundChannelOrder channelOrder){ - UnionPayRecord unionPayRecord = new UnionPayRecord() - .setType(UnionPayRecordTypeEnum.REFUND.getCode()) - .setTitle(order.getTitle()) - .setOrderId(order.getId()) - .setAmount(channelOrder.getAmount()) - .setGatewayOrderNo(order.getGatewayOrderNo()) - .setGatewayTime(channelOrder.getRefundTime()); - unionPayRecordManager.save(unionPayRecord); - } - - /** - * 分页 - */ - public PageResult page(PageParam pageParam, UnionPayRecordQuery param){ - return MpUtil.convert2DtoPageResult(unionPayRecordManager.page(pageParam, param)); - } - - /** - * 查询详情 - */ - public UnionPayRecordDto findById(Long id){ - return unionPayRecordManager.findById(id).map(UnionPayRecord::toDto).orElseThrow(DataNotExistException::new); - } -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayService.java index 6257700f..1c1c3629 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayService.java @@ -1,8 +1,9 @@ package cn.bootx.platform.daxpay.service.core.channel.union.service; -import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.code.PayMethodEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.param.channel.UnionPayParam; +import cn.bootx.platform.daxpay.param.payment.pay.PayParam; import cn.bootx.platform.daxpay.service.code.UnionPayCode; import cn.bootx.platform.daxpay.service.code.UnionPayWay; import cn.bootx.platform.daxpay.service.common.context.PayLocal; @@ -40,55 +41,59 @@ public class UnionPayService { /** * 支付前检查支付方式是否可用 */ - public void validation(PayChannelParam payChannelParam, UnionPayConfig unionPayConfig) { + public void validation(PayParam payParam, UnionPayConfig unionPayConfig) { if (CollUtil.isEmpty(unionPayConfig.getPayWays())){ throw new PayFailureException("云闪付未配置可用的支付方式"); } // 发起的支付类型是否在支持的范围内 - PayWayEnum payWayEnum = Optional.ofNullable(UnionPayWay.findByCode(payChannelParam.getWay())) + PayMethodEnum payMethodEnum = Optional.ofNullable(UnionPayWay.findByCode(payParam.getMethod())) .orElseThrow(() -> new PayFailureException("非法的云闪付支付类型")); - if (!unionPayConfig.getPayWays().contains(payWayEnum.getCode())) { + if (!unionPayConfig.getPayWays().contains(payMethodEnum.getCode())) { throw new PayFailureException("该云闪付支付方式不可用"); } // 支付金额是否超限 - if (payChannelParam.getAmount() > unionPayConfig.getSingleLimit()) { + if (payParam.getAmount() > unionPayConfig.getSingleLimit()) { throw new PayFailureException("云闪付支付金额超限"); } + // 分账 + if (payParam.isAllocation()) { + throw new PayFailureException("云闪付不支持分账"); + } } /** * 支付接口 */ - public void pay(PayOrder payOrder, PayChannelParam payChannelParam, UnionPayParam unionPayParam, UnionPayKit unionPayKit){ - Integer amount = payChannelParam.getAmount(); + public void pay(PayOrder payOrder, UnionPayParam unionPayParam, UnionPayKit unionPayKit){ + Integer amount = payOrder.getAmount(); BigDecimal totalFee = BigDecimal.valueOf(amount * 0.01); PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();; String payBody = null; - PayWayEnum payWayEnum = PayWayEnum.findByCode(payChannelParam.getWay()); + PayMethodEnum payMethodEnum = PayMethodEnum.findByCode(payOrder.getMethod()); // 二维码支付 - if (payWayEnum == PayWayEnum.QRCODE) { + if (payMethodEnum == PayMethodEnum.QRCODE) { payBody = this.qrCodePay(totalFee, payOrder, unionPayKit); } // 付款码支付 - else if (payWayEnum == PayWayEnum.BARCODE) { + else if (payMethodEnum == PayMethodEnum.BARCODE) { this.barCodePay(totalFee, payOrder, unionPayParam.getAuthCode(), unionPayKit); } // APP支付 - else if (payWayEnum == PayWayEnum.APP) { + else if (payMethodEnum == PayMethodEnum.APP) { payBody = this.appPay(totalFee, payOrder, unionPayParam, unionPayKit); } // web支付 - else if (payWayEnum == PayWayEnum.WEB) { + else if (payMethodEnum == PayMethodEnum.WEB) { payBody = this.formPay(totalFee, payOrder, unionPayKit, UnionTransactionType.WEB); } // wap支付 - else if (payWayEnum == PayWayEnum.WAP) { + else if (payMethodEnum == PayMethodEnum.WAP) { payBody = this.formPay(totalFee, payOrder, unionPayKit, UnionTransactionType.WAP ); } // b2b支付 TODO 未完成 - else if (payWayEnum == PayWayEnum.B2B) { + else if (payMethodEnum == PayMethodEnum.B2B) { payBody = this.b2bPay(totalFee, payOrder, unionPayKit); } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletPayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletPayService.java index 7369afe5..766aac06 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletPayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletPayService.java @@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.service.core.channel.wallet.service; import cn.bootx.platform.daxpay.service.core.channel.wallet.dao.WalletManager; import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; +import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -34,9 +34,9 @@ public class WalletPayService { /** * 关闭支付, 将支付成功的金额进行返还 */ - public void close(PayChannelOrder channelOrder, Wallet wallet) { + public void close(PayOrder payOrder, Wallet wallet) { // 将订单的金额退款到钱包 - wallet.setBalance(wallet.getBalance() + channelOrder.getAmount()); + wallet.setBalance(wallet.getBalance() + payOrder.getAmount()); walletManager.updateById(wallet); } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletRecordService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletRecordService.java deleted file mode 100644 index 0ee3ef8a..00000000 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletRecordService.java +++ /dev/null @@ -1,132 +0,0 @@ -package cn.bootx.platform.daxpay.service.core.channel.wallet.service; - -import cn.bootx.platform.common.core.exception.DataNotExistException; -import cn.bootx.platform.common.core.rest.PageResult; -import cn.bootx.platform.common.core.rest.param.PageParam; -import cn.bootx.platform.common.mybatisplus.util.MpUtil; -import cn.bootx.platform.daxpay.service.code.WalletRecordTypeEnum; -import cn.bootx.platform.daxpay.service.core.channel.wallet.dao.WalletRecordManager; -import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet; -import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletRecord; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder; -import cn.bootx.platform.daxpay.service.dto.channel.wallet.WalletRecordDto; -import cn.bootx.platform.daxpay.service.param.channel.wallet.WalletRecordQuery; -import cn.hutool.core.util.StrUtil; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -/** - * 钱包记录服务类 - * @author xxm - * @since 2024/2/18 - */ -@Slf4j -@Service -@RequiredArgsConstructor -public class WalletRecordService { - private final WalletRecordManager walletRecordManager; - - /** - * 创建保存 - */ - public void create(Wallet wallet){ - WalletRecord walletRecord = new WalletRecord() - .setTitle("创建钱包") - .setType(WalletRecordTypeEnum.CREATE.getCode()) - .setAmount(wallet.getBalance()) - .setNewAmount(wallet.getBalance()) - .setOldAmount(0) - .setWalletId(wallet.getId()); - walletRecordManager.save(walletRecord); - } - - /** - * 充值保存 - */ - public void recharge(Wallet wallet, int amount){ - WalletRecord walletRecord = new WalletRecord() - .setTitle(StrUtil.format("余额充值:{} 分", amount)) - .setType(WalletRecordTypeEnum.RECHARGE.getCode()) - .setAmount(wallet.getBalance()) - .setNewAmount(wallet.getBalance()) - .setOldAmount(wallet.getBalance() + amount) - .setWalletId(wallet.getId()); - walletRecordManager.save(walletRecord); - } - - /** - * 扣减保存 - */ - public void deduct(Wallet wallet, int amount){ - WalletRecord walletRecord = new WalletRecord() - .setTitle(StrUtil.format("余额扣减:{} 分", amount)) - .setType(WalletRecordTypeEnum.DEDUCT.getCode()) - .setWalletId(wallet.getId()) - .setAmount(wallet.getBalance()) - .setNewAmount(wallet.getBalance()) - .setOldAmount(wallet.getBalance() + amount); - walletRecordManager.save(walletRecord); - } - - /** - * 支付保存 - */ - public void pay(PayChannelOrder channelOrder, String title, Wallet wallet){ - WalletRecord walletRecord = new WalletRecord() - .setTitle(title) - .setType(WalletRecordTypeEnum.PAY.getCode()) - .setAmount(channelOrder.getAmount()) - .setNewAmount(wallet.getBalance()) - .setOldAmount(wallet.getBalance() - channelOrder.getAmount()) - .setOrderId(String.valueOf(channelOrder.getPaymentId())) - .setWalletId(wallet.getId()); - walletRecordManager.save(walletRecord); - } - - /** - * 退款保存 - */ - public void refund(RefundChannelOrder channelOrder, String title, Wallet wallet){ - WalletRecord walletRecord = new WalletRecord() - .setTitle(title) - .setType(WalletRecordTypeEnum.REFUND.getCode()) - .setAmount(channelOrder.getAmount()) - .setNewAmount(wallet.getBalance()) - .setOldAmount(wallet.getBalance() + channelOrder.getAmount()) - .setOrderId(String.valueOf(channelOrder.getRefundId())) - .setWalletId(wallet.getId()); - walletRecordManager.save(walletRecord); - } - - /** - * 支付关闭 - */ - public void payClose(PayChannelOrder channelOrder, String title, Wallet wallet){ - WalletRecord walletRecord = new WalletRecord() - .setTitle(title) - .setType(WalletRecordTypeEnum.CLOSE_PAY.getCode()) - .setAmount(channelOrder.getAmount()) - .setNewAmount(wallet.getBalance()) - .setOldAmount(wallet.getBalance() - channelOrder.getAmount()) - .setOrderId(String.valueOf(channelOrder.getPaymentId())) - .setWalletId(wallet.getId()); - walletRecordManager.save(walletRecord); - } - - /** - * 分页 - */ - public PageResult page(PageParam pageParam, WalletRecordQuery param) { - return MpUtil.convert2DtoPageResult(walletRecordManager.page(pageParam, param)); - } - - /** - * 查询详情 - */ - public WalletRecordDto findById(Long id){ - return walletRecordManager.findById(id).map(WalletRecord::toDto).orElseThrow(DataNotExistException::new); - } - -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletService.java index 19b4338a..a5764455 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wallet/service/WalletService.java @@ -25,7 +25,6 @@ import java.util.Objects; @RequiredArgsConstructor public class WalletService { private final WalletManager walletManager; - private final WalletRecordService walletRecordService; /** * 创建钱包操作,默认为启用状态, 不传输余额则默认为0 @@ -80,7 +79,6 @@ public class WalletService { } wallet.setBalance(wallet.getBalance() + param.getAmount()); walletManager.updateById(wallet); - walletRecordService.recharge(wallet, param.getAmount()); } /** @@ -100,6 +98,5 @@ public class WalletService { } wallet.setBalance(wallet.getBalance() - param.getAmount()); walletManager.updateById(wallet); - walletRecordService.deduct(wallet, param.getAmount()); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WeChatPayRecord.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WeChatPayRecord.java index abb8248e..5a95cfd7 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WeChatPayRecord.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WeChatPayRecord.java @@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.entity; import cn.bootx.platform.common.core.function.EntityBaseFunction; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; -import cn.bootx.platform.daxpay.service.code.WechatPayRecordTypeEnum; +import cn.bootx.platform.daxpay.service.code.TradeFlowRecordTypeEnum; import cn.bootx.platform.daxpay.service.core.channel.wechat.convert.WeChatConvert; import cn.bootx.platform.daxpay.service.dto.channel.wechat.WeChatPayRecordDto; import cn.bootx.table.modify.annotation.DbColumn; @@ -36,7 +36,7 @@ public class WeChatPayRecord extends MpCreateEntity implements EntityBaseFunctio /** * 业务类型 - * @see WechatPayRecordTypeEnum + * @see TradeFlowRecordTypeEnum */ @DbColumn(comment = "业务类型") private String type; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayCallbackService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayCallbackService.java index 0fba7715..9d0e26f5 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayCallbackService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayCallbackService.java @@ -85,12 +85,12 @@ public class WeChatPayCallbackService extends AbsCallbackStrategy { Map callbackParam = callbackInfo.getCallbackParam(); // 网关订单号 - callbackInfo.setGatewayOrderNo(callbackParam.get(TRANSACTION_ID)); + callbackInfo.setOutOrderNo(callbackParam.get(TRANSACTION_ID)); // 支付订单ID callbackInfo.setOrderId(Long.valueOf(callbackParam.get(OUT_TRADE_NO))); // 支付状态 PayStatusEnum payStatus = WxPayKit.codeIsOk(callbackParam.get(RESULT_CODE)) ? PayStatusEnum.SUCCESS : PayStatusEnum.FAIL; - callbackInfo.setGatewayStatus(payStatus.getCode()); + callbackInfo.setOutStatus(payStatus.getCode()); // 支付金额 callbackInfo.setAmount(callbackParam.get(TOTAL_FEE)); String timeEnd = callbackParam.get(TIME_END); @@ -119,7 +119,7 @@ public class WeChatPayCallbackService extends AbsCallbackStrategy { callbackParam = WxPayKit.xmlToMap(decryptData); callbackInfo.setCallbackParam(callbackParam); // 网关订单号 - callbackInfo.setGatewayOrderNo(callbackParam.get(CALLBACK_REFUND_ID)); + callbackInfo.setOutOrderNo(callbackParam.get(CALLBACK_REFUND_ID)); // 退款订单Id callbackInfo.setOrderId(Long.valueOf(callbackParam.get(CALLBACK_OUT_REFUND_NO))); // 退款金额 @@ -128,7 +128,7 @@ public class WeChatPayCallbackService extends AbsCallbackStrategy { // 交易状态 RefundStatusEnum refundStatus = Objects.equals(callbackParam.get(CALLBACK_REFUND_STATUS), REFUND_SUCCESS) ? RefundStatusEnum.SUCCESS : RefundStatusEnum.FAIL; - callbackInfo.setGatewayStatus(refundStatus.getCode()); + callbackInfo.setOutStatus(refundStatus.getCode()); // 退款时间 String timeEnd = callbackParam.get(CALLBACK_SUCCESS_TIME); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayRecordService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayRecordService.java deleted file mode 100644 index 34e21033..00000000 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayRecordService.java +++ /dev/null @@ -1,74 +0,0 @@ -package cn.bootx.platform.daxpay.service.core.channel.wechat.service; - -import cn.bootx.platform.common.core.exception.DataNotExistException; -import cn.bootx.platform.common.core.rest.PageResult; -import cn.bootx.platform.common.core.rest.param.PageParam; -import cn.bootx.platform.common.mybatisplus.util.MpUtil; -import cn.bootx.platform.daxpay.service.code.WechatPayRecordTypeEnum; -import cn.bootx.platform.daxpay.service.core.channel.wechat.dao.WeChatPayRecordManager; -import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayRecord; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; -import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrder; -import cn.bootx.platform.daxpay.service.dto.channel.wechat.WeChatPayRecordDto; -import cn.bootx.platform.daxpay.service.param.channel.wechat.WeChatPayRecordQuery; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -/** - * 微信支付记录 - * @author xxm - * @since 2024/2/19 - */ -@Slf4j -@Service -@RequiredArgsConstructor -public class WeChatPayRecordService { - private final WeChatPayRecordManager weChatPayRecordManager; - - /** - * 支付 - */ - public void pay(PayOrder order, PayChannelOrder channelOrder){ - WeChatPayRecord weChatPayRecord = new WeChatPayRecord() - .setType(WechatPayRecordTypeEnum.PAY.getCode()) - .setTitle(order.getTitle()) - .setOrderId(order.getId()) - .setAmount(channelOrder.getAmount()) - .setGatewayOrderNo(order.getGatewayOrderNo()) - .setGatewayTime(channelOrder.getPayTime()); - weChatPayRecordManager.save(weChatPayRecord); - } - - /** - * 退款 - */ - public void refund(RefundOrder order, RefundChannelOrder channelOrder){ - WeChatPayRecord weChatPayRecord = new WeChatPayRecord() - .setType(WechatPayRecordTypeEnum.REFUND.getCode()) - .setTitle(order.getTitle()) - .setOrderId(order.getId()) - .setAmount(channelOrder.getAmount()) - .setGatewayOrderNo(order.getGatewayOrderNo()) - .setGatewayTime(channelOrder.getRefundTime()); - weChatPayRecordManager.save(weChatPayRecord); - } - - /** - * 分页 - */ - public PageResult page(PageParam pageParam, WeChatPayRecordQuery param){ - return MpUtil.convert2DtoPageResult(weChatPayRecordManager.page(pageParam, param)); - } - - /** - * 查询详情 - */ - public WeChatPayRecordDto findById(Long id){ - return weChatPayRecordManager.findById(id).map(WeChatPayRecord::toDto).orElseThrow(DataNotExistException::new); - } - - -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java index 198cbb0a..9ddb0d31 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayService.java @@ -4,8 +4,9 @@ import cn.bootx.platform.common.core.util.CollUtil; import cn.bootx.platform.common.core.util.LocalDateTimeUtil; import cn.bootx.platform.common.jackson.util.JacksonUtil; import cn.bootx.platform.common.spring.exception.RetryableException; -import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.code.PayMethodEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; +import cn.bootx.platform.daxpay.param.payment.pay.PayParam; import cn.bootx.platform.daxpay.result.pay.SyncResult; import cn.bootx.platform.daxpay.service.code.WeChatPayCode; import cn.bootx.platform.daxpay.service.code.WeChatPayWay; @@ -58,52 +59,56 @@ public class WeChatPayService { /** * 校验 */ - public void validation(PayChannelParam payChannelParam, WeChatPayConfig weChatPayConfig) { + public void validation(PayParam payParam, WeChatPayConfig weChatPayConfig) { List payWays = weChatPayConfig.getPayWays(); if (CollUtil.isEmpty(payWays)){ throw new PayFailureException("未配置微信支付方式"); } - PayWayEnum payWayEnum = Optional.ofNullable(WeChatPayWay.findByCode(payChannelParam.getWay())) + PayMethodEnum payMethodEnum = Optional.ofNullable(WeChatPayWay.findByCode(payParam.getMethod())) .orElseThrow(() -> new PayFailureException("非法的微信支付类型")); - if (!payWays.contains(payWayEnum.getCode())) { + if (!payWays.contains(payMethodEnum.getCode())) { throw new PayFailureException("该微信支付方式不可用"); } // 支付金额是否超限 - if (payChannelParam.getAmount() > weChatPayConfig.getSingleLimit()) { + if (payParam.getAmount() > weChatPayConfig.getSingleLimit()) { throw new PayFailureException("微信支付金额超限"); } + // 是否支持分账 + if (payParam.isAllocation() && !weChatPayConfig.getAllocation()) { + throw new PayFailureException("未开启分账配置"); + } } /** * 支付 */ - public void pay(PayOrder payOrder, WeChatPayParam weChatPayParam, PayChannelParam payChannelParam, WeChatPayConfig weChatPayConfig) { + public void pay(PayOrder payOrder, WeChatPayParam weChatPayParam, WeChatPayConfig weChatPayConfig) { - Integer amount = payChannelParam.getAmount(); + Integer amount = payOrder.getAmount(); String totalFee = String.valueOf(amount); PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();; String payBody = null; - PayWayEnum payWayEnum = PayWayEnum.findByCode(payChannelParam.getWay()); + PayMethodEnum payMethodEnum = PayMethodEnum.findByCode(payOrder.getMethod()); // wap支付 - if (payWayEnum == PayWayEnum.WAP) { + if (payMethodEnum == PayMethodEnum.WAP) { payBody = this.wapPay(totalFee, payOrder, weChatPayConfig); } // APP支付 - else if (payWayEnum == PayWayEnum.APP) { + else if (payMethodEnum == PayMethodEnum.APP) { payBody = this.appPay(totalFee, payOrder, weChatPayConfig); } // 微信公众号支付或者小程序支付 - else if (payWayEnum == PayWayEnum.JSAPI) { + else if (payMethodEnum == PayMethodEnum.JSAPI) { payBody = this.jsPay(totalFee, payOrder, weChatPayParam.getOpenId(), weChatPayConfig); } // 二维码支付 - else if (payWayEnum == PayWayEnum.QRCODE) { + else if (payMethodEnum == PayMethodEnum.QRCODE) { payBody = this.qrCodePay(totalFee, payOrder, weChatPayConfig); } // 付款码支付 - else if (payWayEnum == PayWayEnum.BARCODE) { + else if (payMethodEnum == PayMethodEnum.BARCODE) { this.barCodePay(totalFee, payOrder, weChatPayParam.getAuthCode(), weChatPayConfig); } asyncPayInfo.setPayBody(payBody); @@ -205,14 +210,14 @@ public class WeChatPayService { String errCode = result.get(WeChatPayCode.ERR_CODE); // 支付成功处理, if (Objects.equals(resultCode, WeChatPayCode.PAY_SUCCESS)) { - asyncPayInfo.setGatewayOrderNo(result.get(WeChatPayCode.TRANSACTION_ID)).setPayComplete(true); + asyncPayInfo.setOutOrderNo(result.get(WeChatPayCode.TRANSACTION_ID)).setComplete(true); return; } // 支付中, 发起轮训同步 if (Objects.equals(resultCode, WeChatPayCode.PAY_FAIL) && Objects.equals(errCode, WeChatPayCode.PAY_USERPAYING)) { SpringUtil.getBean(this.getClass()).rotationSync(payOrder); - asyncPayInfo.setGatewayOrderNo(result.get(WeChatPayCode.TRANSACTION_ID)); + asyncPayInfo.setOutOrderNo(result.get(WeChatPayCode.TRANSACTION_ID)); return; } // 支付撤销 diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/builder/PayBuilder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/builder/PayBuilder.java index 3dd71c86..59114fa3 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/builder/PayBuilder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/builder/PayBuilder.java @@ -1,16 +1,12 @@ package cn.bootx.platform.daxpay.service.core.order.pay.builder; -import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.code.PayOrderAllocationStatusEnum; import cn.bootx.platform.daxpay.code.PayStatusEnum; import cn.bootx.platform.daxpay.param.payment.pay.PayParam; import cn.bootx.platform.daxpay.result.pay.PayResult; -import cn.bootx.platform.daxpay.service.common.context.ApiInfoLocal; -import cn.bootx.platform.daxpay.service.common.context.PayLocal; import cn.bootx.platform.daxpay.service.common.context.NoticeLocal; -import cn.bootx.platform.daxpay.service.common.context.PlatformLocal; +import cn.bootx.platform.daxpay.service.common.context.PayLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra; import cn.bootx.platform.daxpay.util.OrderNoGenerateUtil; @@ -20,9 +16,6 @@ import cn.hutool.json.JSONUtil; import lombok.experimental.UtilityClass; import java.time.LocalDateTime; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; /** * 支付对象构建器 @@ -41,30 +34,20 @@ public class PayBuilder { LocalDateTime expiredTime = PaymentContextLocal.get() .getPayInfo() .getExpiredTime(); - // 计算总价 - int sumAmount = payParam.getPayChannels().stream() - .map(PayChannelParam::getAmount) - .filter(Objects::nonNull) - .reduce(Integer::sum) - .orElse(0); - // 是否有异步支付方式 - Optional asyncPay = payParam.getPayChannels().stream() - .map(PayChannelParam::getChannel) - .filter(PayChannelEnum.ASYNC_TYPE_CODE::contains) - .findFirst(); // 构建支付订单对象 PayOrder payOrder = new PayOrder() - .setBusinessNo(payParam.getBusinessNo()) + .setBizOrderNo(payParam.getBizOrderNo()) .setOrderNo(OrderNoGenerateUtil.trade()) .setTitle(payParam.getTitle()) + .setDescription(payParam.getDescription()) .setStatus(PayStatusEnum.PROGRESS.getCode()) .setAllocation(payParam.isAllocation()) - .setAmount(sumAmount) + .setAmount(payParam.getAmount()) + .setChannel(payParam.getChannel()) + .setMethod(payParam.getMethod()) .setExpiredTime(expiredTime) - .setCombinationPay(payParam.getPayChannels().size() > 1) - .setAsyncPay(asyncPay.isPresent()) - .setRefundableBalance(sumAmount); - // 设置分账状态 + .setRefundableBalance(payParam.getAmount()); + // 如果支持分账, 设置分账状态为代分账 if (payOrder.isAllocation()) { payOrder.setAllocationStatus(PayOrderAllocationStatusEnum.WAITING.getCode()); } @@ -74,43 +57,23 @@ public class PayBuilder { /** * 构建支付订单的额外信息 * @param payParam 支付参数 - * @param paymentId 支付订单id + * @param payOrderId 支付订单id */ - public PayOrderExtra buildPayOrderExtra(PayParam payParam, Long paymentId) { - PlatformLocal platform = PaymentContextLocal.get().getPlatformInfo(); + public PayOrderExtra buildPayOrderExtra(PayParam payParam, Long payOrderId) { NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo(); - ApiInfoLocal apiInfo = PaymentContextLocal.get().getApiInfo(); PayOrderExtra payOrderExtra = new PayOrderExtra() .setClientIp(payParam.getClientIp()) - .setDescription(payParam.getDescription()) - .setNoticeSign(apiInfo.isNoticeSign()) .setNotifyUrl(noticeInfo.getNotifyUrl()) .setReturnUrl(noticeInfo.getReturnUrl()) - .setReqSign(payParam.getSign()) - .setReqSignType(platform.getSignType()) .setAttach(payParam.getAttach()) .setReqTime(payParam.getReqTime()); - payOrderExtra.setId(paymentId); - return payOrderExtra; - } - - /** - * 构建订单关联通道信息 - */ - public PayChannelOrder buildPayChannelOrder(PayChannelParam channelParam) { - PayChannelOrder payChannelOrder = new PayChannelOrder() - .setAsync(PayChannelEnum.ASYNC_TYPE_CODE.contains(channelParam.getChannel())) - .setChannel(channelParam.getChannel()) - .setPayWay(channelParam.getWay()) - .setAmount(channelParam.getAmount()) - .setRefundableBalance(channelParam.getAmount()); - - Map cp = channelParam.getChannelParam(); - if (CollUtil.isNotEmpty(cp)){ - payChannelOrder.setChannelExtra(JSONUtil.toJsonStr(cp)); + // 扩展参数 + if (CollUtil.isNotEmpty(payParam.getExtraParam())) { + payOrderExtra.setExtraParam(JSONUtil.toJsonStr(payParam.getExtraParam())); } - return payChannelOrder; + payOrderExtra.setId(payOrderId); + return payOrderExtra; } @@ -119,19 +82,18 @@ public class PayBuilder { * @param payOrder 支付订单 * @return PayResult 支付结果 */ - public PayResult buildPayResultByPayOrder(PayOrder payOrder) { - PayResult paymentResult; - paymentResult = new PayResult(); - paymentResult.setPaymentId(payOrder.getId()); - paymentResult.setAsyncPay(payOrder.isAsyncPay()); - paymentResult.setAsyncChannel(payOrder.getAsyncChannel()); - paymentResult.setStatus(payOrder.getStatus()); + public PayResult buildResultByPayOrder(PayOrder payOrder) { + PayResult payResult; + payResult = new PayResult(); + payResult.setBizOrderNo(payOrder.getBizOrderNo()); + payResult.setOrderNo(payOrder.getOrderNo()); + payResult.setStatus(payOrder.getStatus()); - // 设置异步支付参数 + // 设置支付参数 PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();; if (StrUtil.isNotBlank(asyncPayInfo.getPayBody())) { - paymentResult.setPayBody(asyncPayInfo.getPayBody()); + payResult.setPayBody(asyncPayInfo.getPayBody()); } - return paymentResult; + return payResult; } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/dao/PayOrderManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/dao/PayOrderManager.java index 4922d97d..38b00335 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/dao/PayOrderManager.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/dao/PayOrderManager.java @@ -25,8 +25,19 @@ import java.util.Optional; @Repository @RequiredArgsConstructor public class PayOrderManager extends BaseManager { - public Optional findByBusinessNo(String businessNo) { - return findByField(PayOrder::getBusinessNo,businessNo); + + /** + * 根据订单号查询 + */ + public Optional findByOrderNo(String orderNo) { + return findByField(PayOrder::getOrderNo,orderNo); + } + + /** + * 根据商户订单号查询 + */ + public Optional findByBizOrderNo(String bizOrderNo) { + return findByField(PayOrder::getBizOrderNo,bizOrderNo); } /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayChannelOrder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayChannelOrder.java index 4bce5ba1..04c74259 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayChannelOrder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayChannelOrder.java @@ -29,6 +29,7 @@ import java.time.LocalDateTime; @Accessors(chain = true) @DbTable(comment = "支付订单关联支付时通道信息") @TableName("pay_channel_order") +@Deprecated public class PayChannelOrder extends MpCreateEntity implements EntityBaseFunction { @DbColumn(comment = "支付id") @@ -64,7 +65,6 @@ public class PayChannelOrder extends MpCreateEntity implements EntityBaseFunctio /** * @see AliPayParam * @see WeChatPayParam - * @see VoucherPayParam * @see WalletPayParam */ @DbColumn(comment = "附加支付参数") diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayOrder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayOrder.java index 1c732f24..0cf87fd7 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayOrder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/entity/PayOrder.java @@ -32,42 +32,44 @@ import java.time.LocalDateTime; @TableName(value = "pay_order",autoResultMap = true) public class PayOrder extends MpBaseEntity implements EntityBaseFunction { - /** 关联的业务id */ - @DbMySqlIndex(comment = "业务业务号索引",type = MySqlIndexType.UNIQUE) - @DbColumn(comment = "关联的业务号") - private String businessNo; + /** 商户订单号 */ + @DbMySqlIndex(comment = "商户订单号索引",type = MySqlIndexType.UNIQUE) + @DbColumn(comment = "商户订单号") + private String bizOrderNo; - @DbColumn(comment = "支付订单编号") + @DbColumn(comment = "支付订单号") private String orderNo; + /** + * 三方系统交易号 + */ + @DbColumn(comment = "三方系统交易号") + private String outOrderNo; + /** 标题 */ @DbColumn(comment = "标题") private String title; - /** 是否是组合支付 */ - @DbColumn(comment = "是否是组合支付") - private boolean combinationPay; - - /** 是否是异步支付 */ - @DbColumn(comment = "是否是异步支付") - private boolean asyncPay; + /** 描述 */ + @DbColumn(comment = "描述") + private String description; /** 是否支持分账 */ @DbColumn(comment = "是否需要分账") private boolean allocation; /** - * 异步支付通道 - * @see PayChannelEnum#ASYNC_TYPE_CODE + * 支付通道 + * @see PayChannelEnum */ @DbColumn(comment = "异步支付通道") - private String asyncChannel; + private String channel; /** - * 如果有异步支付的情况下, 保存关联网关订单号 + * 支付方式 */ - @DbColumn(comment = "网关订单号") - private String gatewayOrderNo; + @DbColumn(comment = "支付方式") + private String method; /** 金额 */ @DbColumn(comment = "金额") @@ -105,6 +107,16 @@ public class PayOrder extends MpBaseEntity implements EntityBaseFunction { - /** 描述 */ - @DbColumn(comment = "描述") - private String description; - /** 同步跳转地址, 以最后一次为准 */ @DbColumn(comment = "同步跳转地址") @TableField(updateStrategy = FieldStrategy.ALWAYS) private String returnUrl; - /** 回调通知时是否需要进行签名, 以最后一次为准 */ - @DbColumn(comment = "回调通知时是否需要进行签名") - private boolean noticeSign; - - /** 异步通知地址 以最后一次为准 */ - @DbColumn(comment = "异步通知地址,以最后一次为准") + /** 异步通知地址,以最后一次为准 */ + @DbColumn(comment = "异步通知地址") @TableField(updateStrategy = FieldStrategy.ALWAYS) private String notifyUrl; - /** 商户扩展参数,回调时会原样返回 */ + /** + * 附加参数 以最后一次为准 + * @see AliPayParam + * @see WeChatPayParam + * @see WalletPayParam + */ + @DbColumn(comment = "附加参数") + @TableField(updateStrategy = FieldStrategy.ALWAYS) + private String extraParam; + + /** 商户扩展参数,回调时会原样返回, 以最后一次为准 */ @DbColumn(comment = "商户扩展参数") private String attach; - /** 请求签名类型 */ - @DbColumn(comment = "签名类型") - private String reqSignType; - - /** 请求签名值,以最后一次为准 */ - @DbColumn(comment = "签名") - private String reqSign; - /** 请求时间,时间戳转时间, 以最后一次为准 */ @DbColumn(comment = "请求时间,传输时间戳,以最后一次为准") private LocalDateTime reqTime; @@ -66,20 +63,6 @@ public class PayOrderExtra extends MpBaseEntity implements EntityBaseFunction findAllByPaymentId(String orderNo){ - return ResultConvertUtil.dtoListConvert(channelOrderManager.findAllByPaymentId(orderNo)); - } - - /** - * 查询单条 - */ - public PayChannelOrderDto findById(Long id){ - return channelOrderManager.findById(id).map(PayChannelOrder::toDto).orElseThrow(() -> new DataNotExistException("通道支付订单未查到")); - } - - /** - * 切换支付订单关联的异步支付通道, 设置是否支付完成状态, 并返回通道订单 - * 同时会更新支付订单上的异步通道信息 - */ - @Transactional(rollbackFor = Exception.class) - public PayChannelOrder switchAsyncPayChannel(PayOrder payOrder, PayChannelParam payChannelParam){ - PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); - // 是否支付完成 - PayStatusEnum payStatus = payInfo.isPayComplete() ? PayStatusEnum.SUCCESS : PayStatusEnum.PROGRESS; - Optional payOrderChannelOpt = channelOrderManager.findByPaymentIdAndChannel(payOrder.getId(), payChannelParam.getChannel()); - // 扩展信息处理 - Map channelParam = payChannelParam.getChannelParam(); - String channelParamStr = null; - if (Objects.nonNull(channelParam)){ - channelParamStr = JSONUtil.toJsonStr(channelParam); - } - PayChannelOrder payChannelOrder; - if (!payOrderChannelOpt.isPresent()){ - payChannelOrder = new PayChannelOrder(); - // 替换原有的的支付通道信息 - payChannelOrder.setPayWay(payChannelParam.getWay()) - .setPaymentId(payOrder.getOrderNo()) - .setAsync(true) - .setChannel(payChannelParam.getChannel()) - .setPayWay(payChannelParam.getWay()) - .setAmount(payChannelParam.getAmount()) - .setRefundableBalance(payChannelParam.getAmount()) - .setChannelExtra(channelParamStr) - .setStatus(payStatus.getCode()); - channelOrderManager.deleteByPaymentIdAndAsync(payOrder.getOrderNo()); - channelOrderManager.save(payChannelOrder); - payInfo.getPayChannelOrders().add(payChannelOrder); - } else { - // 更新支付通道信息 - payChannelOrder = payOrderChannelOpt.get(); - payChannelOrder.setPayWay(payChannelParam.getWay()) - .setChannelExtra(channelParamStr) - .setStatus(payStatus.getCode()); - channelOrderManager.updateById(payChannelOrder); - } - // 对上下文中的通道支付订单进行替换 - List payChannelOrders = payInfo.getPayChannelOrders(); - payChannelOrders.removeIf(o->Objects.equals(o.getChannel(),payChannelOrder.getChannel())); - payChannelOrders.add(payChannelOrder); - // 更新支付订单中的异步通道信息 - payOrder.setAsyncChannel(payChannelOrder.getChannel()); - payOrderManager.updateById(payOrder); - return payChannelOrder; - } - - /** - * 更新异步支付通道退款余额和状态 - */ - public void updateAsyncPayRefund(PayChannelOrder payChannelOrder, RefundChannelOrder refundChannelOrder){ - // 支付通道订单状态 - if (Objects.equals(refundChannelOrder.getStatus(), RefundStatusEnum.SUCCESS.getCode())){ - // 如果可退金额为0说明已经全部退款 - PayStatusEnum status = payChannelOrder.getRefundableBalance() == 0 ? PayStatusEnum.REFUNDED : PayStatusEnum.PARTIAL_REFUND; - payChannelOrder.setStatus(status.getCode()); - refundChannelOrder.setRefundTime(LocalDateTime.now()); - } else { - payChannelOrder.setStatus(PayStatusEnum.REFUNDING.getCode()); - } - } - -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/service/PayOrderQueryService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/service/PayOrderQueryService.java index 6522dfd4..b3e47ddf 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/service/PayOrderQueryService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/service/PayOrderQueryService.java @@ -7,13 +7,10 @@ import cn.bootx.platform.common.core.rest.param.PageParam; import cn.bootx.platform.common.mybatisplus.util.MpUtil; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.param.payment.pay.QueryPayParam; -import cn.bootx.platform.daxpay.result.order.PayChannelOrderResult; import cn.bootx.platform.daxpay.result.order.PayOrderResult; -import cn.bootx.platform.daxpay.service.core.order.pay.convert.PayOrderConvert; import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager; import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderExtraManager; import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderManager; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra; import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto; @@ -25,10 +22,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.List; import java.util.Objects; import java.util.Optional; -import java.util.stream.Collectors; /** * 支付查询服务 @@ -59,10 +54,17 @@ public class PayOrderQueryService { } /** - * 根据业务号查询 + * 根据商户订单号查询 */ - public Optional findByBusinessNo(String businessNo) { - return payOrderManager.findByBusinessNo(businessNo); + public Optional findByOrderNo(String businessNo) { + return payOrderManager.findByOrderNo(businessNo); + } + + /** + * 根据订单号查询 + */ + public Optional findByOutOrderNo(String businessNo) { + return payOrderManager.findByBizOrderNo(businessNo); } /** @@ -70,18 +72,18 @@ public class PayOrderQueryService { */ public PayOrderResult queryPayOrder(QueryPayParam param) { // 校验参数 - if (StrUtil.isBlank(param.getBusinessNo()) && Objects.isNull(param.getPaymentId())){ + if (StrUtil.isBlank(param.getBizOrderNo()) && Objects.isNull(param.getOrderNo())){ throw new ValidationFailedException("业务号或支付单ID不能都为空"); } // 查询支付单 PayOrder payOrder = null; - if (Objects.nonNull(param.getPaymentId())){ - payOrder = payOrderManager.findById(param.getPaymentId()) + if (Objects.nonNull(param.getOrderNo())){ + payOrder = payOrderManager.findByOrderNo(param.getOrderNo()) .orElseThrow(() -> new DataNotExistException("未查询到支付订单")); } if (Objects.isNull(payOrder)){ - payOrder = payOrderManager.findByBusinessNo(param.getBusinessNo()) + payOrder = payOrderManager.findByBizOrderNo(param.getBizOrderNo()) .orElseThrow(() -> new DataNotExistException("未查询到支付订单")); } @@ -89,23 +91,10 @@ public class PayOrderQueryService { PayOrderExtra payOrderExtra = payOrderExtraManager.findById(payOrder.getId()) .orElseThrow(() -> new PayFailureException("支付订单不完整")); - // 查询通道数据 - List orderChannelList = payChannelOrderManager.findAllByPaymentId(payOrder.getOrderNo()); - - List channels = orderChannelList.stream() - .map(PayOrderConvert.CONVERT::convertResult) - .collect(Collectors.toList()); PayOrderResult payOrderResult = new PayOrderResult(); BeanUtil.copyProperties(payOrder, payOrderResult); - payOrderResult.setPaymentId(payOrder.getId()); - payOrderResult.setDescription(payOrderExtra.getDescription()) - .setChannels(channels); return payOrderResult; } - - public Optional findByOrderNo(String orderNo) { - return payOrderManager.findByField(PayOrder::getOrderNo,orderNo); - } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/service/PayOrderService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/service/PayOrderService.java index 7c0c4470..197e7864 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/service/PayOrderService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/pay/service/PayOrderService.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.service.core.order.pay.service; +import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.code.PayStatusEnum; import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderManager; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; @@ -10,6 +11,7 @@ import org.springframework.stereotype.Service; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Optional; /** @@ -40,8 +42,8 @@ public class PayOrderService { */ public void save(PayOrder payOrder){ payOrderManager.save(payOrder); - // 异步支付需要添加订单超时任务记录 - if (payOrder.isAsyncPay()){ + // TODO 钱包支付不需要注册超时任务 + if (Objects.equals(payOrder.getChannel(), PayChannelEnum.WALLET.getCode())){ expiredTimeService.registerExpiredTime(payOrder); } } @@ -51,22 +53,9 @@ public class PayOrderService { */ public void updateById(PayOrder payOrder){ // 如果是异步支付且支付订单完成, 需要删除订单超时任务记录 - if (payOrder.isAsyncPay() && ORDER_FINISH.contains(payOrder.getStatus())){ + if (ORDER_FINISH.contains(payOrder.getStatus())){ expiredTimeService.cancelExpiredTime(payOrder.getId()); } payOrderManager.updateById(payOrder); } - - /** - * 使用强制更新 - */ - public void updateForceById(PayOrder payOrder){ - // 如果是异步支付且支付订单完成, 需要删除订单超时任务记录 - if (payOrder.isAsyncPay() && ORDER_FINISH.contains(payOrder.getStatus())){ - expiredTimeService.cancelExpiredTime(payOrder.getId()); - } - payOrder.setVersion(null); - payOrderManager.updateForceById(payOrder); - } - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundChannelOrderManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundChannelOrderManager.java index d41bd998..ed8c7fac 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundChannelOrderManager.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundChannelOrderManager.java @@ -17,6 +17,7 @@ import java.util.Optional; @Slf4j @Repository @RequiredArgsConstructor +@Deprecated public class RefundChannelOrderManager extends BaseManager { /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundChannelOrderMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundChannelOrderMapper.java index b0ef552c..3fb926b1 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundChannelOrderMapper.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundChannelOrderMapper.java @@ -10,5 +10,6 @@ import org.apache.ibatis.annotations.Mapper; * @since 2024/1/17 */ @Mapper +@Deprecated public interface RefundChannelOrderMapper extends BaseMapper { } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundOrderManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundOrderManager.java index 6c01e1df..af5321ab 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundOrderManager.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/dao/RefundOrderManager.java @@ -43,6 +43,14 @@ public class RefundOrderManager extends BaseManager findByBizRefundNo(String bizRefundNo) { + return findByField(RefundOrder::getBizRefundNo, bizRefundNo); + } + /** * 查询支付号是否重复 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/RefundChannelOrder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/RefundChannelOrder.java index 312b7320..55065f2f 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/RefundChannelOrder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/RefundChannelOrder.java @@ -25,6 +25,7 @@ import java.time.LocalDateTime; @Data @DbTable(comment = "支付退款通道订单") @Accessors(chain = true) +@Deprecated @TableName("pay_refund_channel_order") public class RefundChannelOrder extends MpCreateEntity implements EntityBaseFunction { diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/RefundOrder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/RefundOrder.java index 89ab08c1..f67c20a1 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/RefundOrder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/refund/entity/RefundOrder.java @@ -8,8 +8,6 @@ import cn.bootx.platform.daxpay.service.core.order.refund.convert.RefundOrderCon import cn.bootx.platform.daxpay.service.dto.order.refund.RefundOrderDto; import cn.bootx.table.modify.annotation.DbColumn; import cn.bootx.table.modify.annotation.DbTable; -import com.baomidou.mybatisplus.annotation.FieldStrategy; -import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; @@ -31,42 +29,40 @@ import java.time.LocalDateTime; @TableName(value = "pay_refund_order", autoResultMap = true) public class RefundOrder extends MpBaseEntity implements EntityBaseFunction { - /** 原支付id */ - @DbColumn(comment = "原支付订单号") + /** 支付订单ID */ + @DbColumn(comment = "支付订单ID") + private Long orderId; + + /** 支付订单号 */ + @DbColumn(comment = "支付订单号") private String orderNo; + /** 商户支付订单号 */ + @DbColumn(comment = "商户支付订单号") + private String bizOrderNo; - /** 原支付业务号 */ - @DbColumn(comment = "原支付业务号") - private String businessNo; - - /** 原支付标题 */ - @DbColumn(comment = "原支付标题") + /** 支付标题 */ + @DbColumn(comment = "支付标题") private String title; - /** - * 需要保证全局唯一 - */ + /** 退款号 */ @DbColumn(comment = "退款号") private String refundNo; - private String refundBusinessNo; + @DbColumn(comment = "商户退款号") + private String bizRefundNo; - /** 退款时是否是含有异步通道 */ - @DbColumn(comment = "是否含有异步通道") - private boolean asyncPay; + + /** 三方支付系统退款交易号 */ + @DbColumn(comment = "三方支付系统退款交易号") + private String outOrderNo; /** - * 异步通道 - * @see PayChannelEnum#ASYNC_TYPE_CODE + * 退款通道 + * @see PayChannelEnum */ - @DbColumn(comment = "异步通道") - private String asyncChannel; - - /** 如果有异步通道, 保存关联的网关订单号 */ - @DbColumn(comment = "网关订单号") - private String gatewayOrderNo; - + @DbColumn(comment = "支付通道") + private String channel; /** 订单金额 */ @DbColumn(comment = "订单金额") @@ -76,16 +72,11 @@ public class RefundOrder extends MpBaseEntity implements EntityBaseFunction new DataNotExistException("未查询到支付订单")); } if (Objects.isNull(refundOrder)){ @@ -135,7 +134,6 @@ public class RefundOrderService { RefundParam refundParam = new RefundParam(); refundParam.setPaymentId(param.getPaymentId()); - refundParam.setRefundChannels(param.getRefundChannels()); refundParam.setReason(param.getReason()); refundParam.setReqTime(LocalDateTime.now()); refundParam.setClientIp(ip); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/callback/service/PayCallbackService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/callback/service/PayCallbackService.java index a1c6bfe2..4666c85c 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/callback/service/PayCallbackService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/callback/service/PayCallbackService.java @@ -57,10 +57,10 @@ public class PayCallbackService { return; } // 设置订单关联网关订单号 - payOrder.setGatewayOrderNo(callbackInfo.getGatewayOrderNo()); + payOrder.setGatewayOrderNo(callbackInfo.getOutOrderNo()); // 成功状态 - if (Objects.equals(PayCallbackStatusEnum.SUCCESS.getCode(), callbackInfo.getGatewayStatus())) { + if (Objects.equals(PayCallbackStatusEnum.SUCCESS.getCode(), callbackInfo.getOutStatus())) { // 支付成功处理 this.success(payOrder); } else { diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/callback/service/RefundCallbackService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/callback/service/RefundCallbackService.java index 7db3736a..ccb30cbd 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/callback/service/RefundCallbackService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/callback/service/RefundCallbackService.java @@ -60,7 +60,7 @@ public class RefundCallbackService { } // 退款成功还是失败 - if (Objects.equals(RefundStatusEnum.SUCCESS.getCode(), callbackInfo.getGatewayStatus())) { + if (Objects.equals(RefundStatusEnum.SUCCESS.getCode(), callbackInfo.getOutStatus())) { PaymentContextLocal.get().getRepairInfo().setFinishTime(callbackInfo.getFinishTime()); RefundRepairResult repair = reflectionService.repair(refundOrder, RefundRepairWayEnum.REFUND_SUCCESS); callbackInfo.setPayRepairNo(repair.getRepairNo()); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/close/service/PayCloseService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/close/service/PayCloseService.java index 98ad0fcd..c1a4ae57 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/close/service/PayCloseService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/close/service/PayCloseService.java @@ -60,7 +60,7 @@ public class PayCloseService { .orElseThrow(() -> new PayFailureException("未查询到支付订单")); } if (Objects.isNull(payOrder)){ - payOrder = payOrderQueryService.findByBusinessNo(param.getBusinessNo()) + payOrder = payOrderQueryService.findByOutOrderNo(param.getBusinessNo()) .orElseThrow(() -> new PayFailureException("未查询到支付订单")); } LockInfo lock = lockTemplate.lock("payment:close:" + payOrder.getId(),10000, 50); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/close/strategy/WalletPayCloseStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/close/strategy/WalletPayCloseStrategy.java index bd2d8184..0aad09b2 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/close/strategy/WalletPayCloseStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/close/strategy/WalletPayCloseStrategy.java @@ -5,7 +5,6 @@ import cn.bootx.platform.daxpay.param.channel.WalletPayParam; import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletPayService; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletQueryService; -import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletRecordService; import cn.bootx.platform.daxpay.service.func.AbsPayCloseStrategy; import cn.hutool.json.JSONUtil; import lombok.RequiredArgsConstructor; @@ -27,7 +26,6 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT public class WalletPayCloseStrategy extends AbsPayCloseStrategy { private final WalletPayService walletPayService; private final WalletQueryService walletQueryService; - private final WalletRecordService walletRecordService; private Wallet wallet; @@ -53,7 +51,6 @@ public class WalletPayCloseStrategy extends AbsPayCloseStrategy { */ @Override public void doCloseHandler() { - walletPayService.close(this.getChannelOrder(),this.wallet); - walletRecordService.payClose(this.getChannelOrder(), this.getOrder().getTitle(), this.wallet); + walletPayService.close(this.getOrder(),this.wallet); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/PayChannelResult.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/PayChannelResult.java index 2364d652..6b20783d 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/PayChannelResult.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/PayChannelResult.java @@ -1,7 +1,7 @@ package cn.bootx.platform.daxpay.service.core.payment.notice.result; import cn.bootx.platform.daxpay.code.PayChannelEnum; -import cn.bootx.platform.daxpay.code.PayWayEnum; +import cn.bootx.platform.daxpay.code.PayMethodEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.experimental.Accessors; @@ -14,6 +14,7 @@ import lombok.experimental.Accessors; @Data @Accessors(chain = true) @Schema(title = "支付通道信息") +@Deprecated public class PayChannelResult { /** * 支付通道编码 @@ -24,7 +25,7 @@ public class PayChannelResult { /** * 支付方式编码 - * @see PayWayEnum + * @see PayMethodEnum */ @Schema(description = "支付方式编码") private String way; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/PayNoticeResult.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/PayNoticeResult.java index b67c02bd..605f0d4f 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/PayNoticeResult.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/PayNoticeResult.java @@ -9,7 +9,6 @@ import lombok.Data; import lombok.experimental.Accessors; import java.time.LocalDateTime; -import java.util.List; /** * 支付异步通知类 @@ -21,36 +20,36 @@ import java.util.List; @Schema(title = "支付异步通知类") public class PayNoticeResult { - @Schema(description = "支付ID") - private Long paymentId; + @Schema(description = "订单号") + private String orderNo; - @Schema(description = "业务号") - private String businessNo; + @Schema(description = "商户订单号") + private String bizOrderNo; - @Schema(description = "是否是异步支付") - private boolean asyncPay; + @Schema(description = "标题") + private String title; /** - * @see PayChannelEnum#ASYNC_TYPE_CODE + * @see PayChannelEnum */ - @Schema(description = "异步支付通道") - private String asyncChannel; + @Schema(description = "支付通道") + private String channel; + + /** + * 支付方式 + */ + @Schema(description = "支付方式") + private String method; @Schema(description = "支付金额") private Integer amount; - @Schema(description = "支付通道信息") - private List payChannels; - /** * @see PayStatusEnum */ @Schema(description = "支付状态") private String status; - @Schema(description = "支付创建时间") - @JsonSerialize(using = LocalDateTimeToTimestampSerializer.class) - private LocalDateTime createTime; @Schema(description = "支付成功时间") @JsonSerialize(using = LocalDateTimeToTimestampSerializer.class) @@ -60,6 +59,10 @@ public class PayNoticeResult { @JsonSerialize(using = LocalDateTimeToTimestampSerializer.class) private LocalDateTime closeTime; + @Schema(description = "支付创建时间") + @JsonSerialize(using = LocalDateTimeToTimestampSerializer.class) + private LocalDateTime createTime; + @Schema(description = "商户扩展参数,回调时会原样返回") private String attach; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/RefundChannelResult.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/RefundChannelResult.java index 434a5b20..51f0d438 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/RefundChannelResult.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/result/RefundChannelResult.java @@ -11,6 +11,7 @@ import lombok.experimental.Accessors; * @since 2024/2/22 */ @Data +@Deprecated @Accessors(chain = true) @Schema(title = "退款通道信息") public class RefundChannelResult { diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/service/ClientNoticeAssistService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/service/ClientNoticeAssistService.java index 7e249428..0b3b026b 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/service/ClientNoticeAssistService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/service/ClientNoticeAssistService.java @@ -3,13 +3,11 @@ package cn.bootx.platform.daxpay.service.core.payment.notice.service; import cn.bootx.platform.common.jackson.util.JacksonUtil; import cn.bootx.platform.daxpay.code.PaySignTypeEnum; import cn.bootx.platform.daxpay.service.code.ClientNoticeTypeEnum; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra; import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder; import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrder; import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrderExtra; -import cn.bootx.platform.daxpay.service.core.payment.notice.result.PayChannelResult; import cn.bootx.platform.daxpay.service.core.payment.notice.result.PayNoticeResult; import cn.bootx.platform.daxpay.service.core.payment.notice.result.RefundChannelResult; import cn.bootx.platform.daxpay.service.core.payment.notice.result.RefundNoticeResult; @@ -41,37 +39,31 @@ public class ClientNoticeAssistService { /** * 构建出支付通知任务对象 */ - public ClientNoticeTask buildPayTask(PayOrder order, PayOrderExtra orderExtra, List channelOrders){ - // 组装内容 - List channels = channelOrders.stream() - .map(o->new PayChannelResult().setChannel(o.getChannel()).setWay(o.getPayWay()).setAmount(o.getAmount())) - .collect(Collectors.toList()); + public ClientNoticeTask buildPayTask(PayOrder order, PayOrderExtra orderExtra){ PayNoticeResult payNoticeResult = new PayNoticeResult() - .setPaymentId(order.getId()) - .setAsyncPay(order.isAsyncPay()) - .setBusinessNo(order.getBusinessNo()) + .setOrderNo(order.getOrderNo()) + .setBizOrderNo(order.getBizOrderNo()) + .setTitle(order.getTitle()) + .setChannel(order.getChannel()) + .setMethod(order.getMethod()) .setAmount(order.getAmount()) .setPayTime(order.getPayTime()) .setCloseTime(order.getCloseTime()) .setCreateTime(order.getCreateTime()) .setStatus(order.getStatus()) - .setAttach(orderExtra.getAttach()) - .setPayChannels(channels); + .setAttach(orderExtra.getAttach()); PlatformConfig config = configService.getConfig(); - // 是否需要签名 - if (orderExtra.isNoticeSign()){ - // 签名 - if (Objects.equals(config.getSignType(), PaySignTypeEnum.MD5.getCode())){ - payNoticeResult.setSign(PaySignUtil.md5Sign(payNoticeResult,config.getSignSecret())); - } else { - payNoticeResult.setSign(PaySignUtil.hmacSha256Sign(payNoticeResult,config.getSignSecret())); - } + // 签名 + if (Objects.equals(config.getSignType(), PaySignTypeEnum.MD5.getCode())){ + payNoticeResult.setSign(PaySignUtil.md5Sign(payNoticeResult,config.getSignSecret())); + } else { + payNoticeResult.setSign(PaySignUtil.hmacSha256Sign(payNoticeResult,config.getSignSecret())); } return new ClientNoticeTask() .setUrl(orderExtra.getNotifyUrl()) - // 时间序列化进行了重写 + // 时间序列化进行了重写, 所以使用Jackson的序列化工具类 .setContent(JacksonUtil.toJson(payNoticeResult)) .setNoticeType(ClientNoticeTypeEnum.PAY.getType()) .setSendCount(0) diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/service/ClientNoticeService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/service/ClientNoticeService.java index 9c31c9e9..d9ad3c44 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/service/ClientNoticeService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/notice/service/ClientNoticeService.java @@ -7,7 +7,6 @@ import cn.bootx.platform.common.redis.RedisClient; import cn.bootx.platform.daxpay.service.code.ClientNoticeSendTypeEnum; import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager; import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderExtraManager; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra; import cn.bootx.platform.daxpay.service.core.order.refund.dao.RefundChannelOrderManager; @@ -93,10 +92,9 @@ public class ClientNoticeService { * 注册支付消息通知任务 * @param order 支付订单 * @param orderExtra 支付订单扩展信息 - * @param channelOrders 支付通道订单 */ @Async("bigExecutor") - public void registerPayNotice(PayOrder order, PayOrderExtra orderExtra, List channelOrders) { + public void registerPayNotice(PayOrder order, PayOrderExtra orderExtra) { // 支付订单扩展信息为空则进行查询 if (Objects.isNull(orderExtra)){ Optional extraOpt = payOrderExtraManager.findById(order.getId()); @@ -112,12 +110,8 @@ public class ClientNoticeService { return; } - // 通道支付订单为空则进行查询 - if (CollUtil.isEmpty(channelOrders)){ - channelOrders = payChannelOrderManager.findAllByPaymentId(order.getOrderNo()); - } // 创建通知任务并保存 - ClientNoticeTask task = clientNoticeAssistService.buildPayTask(order, orderExtra, channelOrders); + ClientNoticeTask task = clientNoticeAssistService.buildPayTask(order, orderExtra); try { taskManager.save(task); } catch (Exception e) { diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/factory/PayStrategyFactory.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/factory/PayStrategyFactory.java index de4367e9..ac4394f8 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/factory/PayStrategyFactory.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/factory/PayStrategyFactory.java @@ -2,20 +2,14 @@ package cn.bootx.platform.daxpay.service.core.payment.pay.factory; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException; -import cn.bootx.platform.daxpay.service.core.payment.pay.strategy.*; +import cn.bootx.platform.daxpay.service.core.payment.pay.strategy.AliPayStrategy; +import cn.bootx.platform.daxpay.service.core.payment.pay.strategy.UnionPayStrategy; +import cn.bootx.platform.daxpay.service.core.payment.pay.strategy.WalletPayStrategy; +import cn.bootx.platform.daxpay.service.core.payment.pay.strategy.WeChatPayStrategy; import cn.bootx.platform.daxpay.service.func.AbsPayStrategy; -import cn.hutool.core.collection.CollectionUtil; import cn.hutool.extra.spring.SpringUtil; import lombok.experimental.UtilityClass; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -import static cn.bootx.platform.daxpay.code.PayChannelEnum.ASYNC_TYPE_CODE; - /** * 支付策略工厂 @@ -28,12 +22,11 @@ public class PayStrategyFactory { /** * 根据传入的支付通道创建策略 - * @param payChannelParam 支付类型 * @return 支付策略 */ - public AbsPayStrategy create(PayChannelParam payChannelParam) { + public AbsPayStrategy create(String channel) { AbsPayStrategy strategy; - PayChannelEnum channelEnum = PayChannelEnum.findByCode(payChannelParam.getChannel()); + PayChannelEnum channelEnum = PayChannelEnum.findByCode(channel); switch (channelEnum) { case ALI: strategy = SpringUtil.getBean(AliPayStrategy.class); @@ -50,62 +43,6 @@ public class PayStrategyFactory { default: throw new PayUnsupportedMethodException(); } - strategy.setPayChannelParam(payChannelParam); return strategy; } - - /** - * 根据传入的支付类型批量创建策略, 异步支付在后面 - * 同步支付逻辑完后才执行异步支付的逻辑, 预防异步执行成功, 然同步执行失败. 导致异步支付无法回滚的问题 - */ - public static List createAsyncLast(List payChannelParamList) { - return createAsyncFront(payChannelParamList, false); - } - - /** - * 根据传入的支付类型批量创建策略, 异步支付在前面 font - */ - public List createAsyncFront(List payChannelParamList) { - return createAsyncFront(payChannelParamList, true); - } - - /** - * 根据传入的支付类型批量创建策略 - * @param payChannelParamList 支付类型 - * @return 支付策略 - */ - private List createAsyncFront(List payChannelParamList, boolean asyncFirst) { - if (CollectionUtil.isEmpty(payChannelParamList)) { - return Collections.emptyList(); - } - List list = new ArrayList<>(payChannelParamList.size()); - - // 同步支付 - List syncPayChannelParamList = payChannelParamList.stream() - .filter(Objects::nonNull) - .filter(payModeParam -> !ASYNC_TYPE_CODE.contains(payModeParam.getChannel())) - .collect(Collectors.toList()); - - // 异步支付 - List asyncPayChannelParamList = payChannelParamList.stream() - .filter(Objects::nonNull) - .filter(payModeParam -> ASYNC_TYPE_CODE.contains(payModeParam.getChannel())) - .collect(Collectors.toList()); - - List sortList = new ArrayList<>(payChannelParamList.size()); - - // 异步在后面 - if (asyncFirst) { - sortList.addAll(asyncPayChannelParamList); - sortList.addAll(syncPayChannelParamList); - } else { - sortList.addAll(syncPayChannelParamList); - sortList.addAll(asyncPayChannelParamList); - } - - // 此处有一个根据Type的反转排序, - sortList.stream().filter(Objects::nonNull).forEach(payMode -> list.add(create(payMode))); - return list; - } - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayAssistService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayAssistService.java index ef788c38..f6e0f956 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayAssistService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayAssistService.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.service.core.payment.pay.service; +import cn.bootx.platform.common.core.util.CollUtil; import cn.bootx.platform.common.core.util.LocalDateTimeUtil; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; @@ -10,17 +11,15 @@ import cn.bootx.platform.daxpay.service.common.context.PayLocal; import cn.bootx.platform.daxpay.service.common.context.PlatformLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.order.pay.builder.PayBuilder; -import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager; import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderExtraManager; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra; import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService; import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService; import cn.bootx.platform.daxpay.service.core.payment.sync.service.PaySyncService; -import cn.bootx.platform.daxpay.service.func.AbsPayStrategy; import cn.bootx.platform.daxpay.util.PayUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -30,7 +29,6 @@ import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; import static cn.bootx.platform.daxpay.code.PayStatusEnum.*; @@ -52,14 +50,12 @@ public class PayAssistService { private final PayOrderExtraManager payOrderExtraManager; - private final PayChannelOrderManager payChannelOrderManager; - /** * 初始化支付相关上下文 */ - public void initPayContext(PayOrder order, PayParam payParam){ + public void initPayContext(PayOrder order, PayParam payParam) { // 初始化支付订单超时时间 - this.initExpiredTime(order,payParam); + this.initExpiredTime(order, payParam); // 初始化通知相关上下文 this.initNotice(payParam); } @@ -70,20 +66,23 @@ public class PayAssistService { * 1. 如果支付记录为空, 超时时间读取顺序 PayParam -> 平台设置 * 2. 如果支付记录不为空, 超时时间通过支付记录进行反推 */ - public void initExpiredTime(PayOrder order, PayParam payParam){ - // 不是异步支付,没有超时时间 - if (PayUtil.isNotSync(payParam.getPayChannels())){ + public void initExpiredTime(PayOrder order, PayParam payParam) { + // 钱包没有超时时间 + if (PayChannelEnum.WALLET.getCode() + .equals(payParam.getChannel())) { return; } - PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo(); - PlatformLocal platform = PaymentContextLocal.get().getPlatformInfo(); + PayLocal asyncPayInfo = PaymentContextLocal.get() + .getPayInfo(); + PlatformLocal platform = PaymentContextLocal.get() + .getPlatformInfo(); // 支付订单是非为空 - if (Objects.nonNull(order)){ + if (Objects.nonNull(order)) { asyncPayInfo.setExpiredTime(order.getExpiredTime()); return; } // 支付参数传入 - if (Objects.nonNull(payParam.getExpiredTime())){ + if (Objects.nonNull(payParam.getExpiredTime())) { asyncPayInfo.setExpiredTime(payParam.getExpiredTime()); return; } @@ -94,104 +93,101 @@ public class PayAssistService { /** * 初始化通知相关上下文 + * 1. 异步通知参数: 读取参数配置 -> 读取接口配置 -> 读取平台参数 + * 2. 同步跳转参数: 读取参数配置 -> 读取平台参数 + * 3. 中途退出地址: 读取参数配置 */ - private void initNotice(PayParam payParam){ - NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo(); - ApiInfoLocal apiInfo = PaymentContextLocal.get().getApiInfo(); - PlatformLocal platform = PaymentContextLocal.get().getPlatformInfo(); + private void initNotice(PayParam payParam) { + NoticeLocal noticeInfo = PaymentContextLocal.get() + .getNoticeInfo(); + ApiInfoLocal apiInfo = PaymentContextLocal.get() + .getApiInfo(); + PlatformLocal platform = PaymentContextLocal.get() + .getPlatformInfo(); // 异步回调为开启状态 - if (!payParam.isNotNotify() && apiInfo.isNotice()){ + if (!payParam.isNotNotify() && apiInfo.isNotice()) { // 首先读取请求参数 noticeInfo.setNotifyUrl(payParam.getNotifyUrl()); // 读取接口配置 - if (StrUtil.isBlank(noticeInfo.getNotifyUrl())){ + if (StrUtil.isBlank(noticeInfo.getNotifyUrl())) { noticeInfo.setNotifyUrl(apiInfo.getNoticeUrl()); } // 读取平台配置 - if (StrUtil.isBlank(noticeInfo.getNotifyUrl())){ + if (StrUtil.isBlank(noticeInfo.getNotifyUrl())) { noticeInfo.setNotifyUrl(platform.getNotifyUrl()); } } // 同步回调 noticeInfo.setReturnUrl(payParam.getReturnUrl()); - if (StrUtil.isBlank(noticeInfo.getReturnUrl())){ + if (StrUtil.isBlank(noticeInfo.getReturnUrl())) { noticeInfo.setReturnUrl(platform.getNotifyUrl()); } // 退出回调地址 noticeInfo.setQuitUrl(payParam.getQuitUrl()); } - /** - * 获取异步支付参数 - */ - public PayChannelParam getAsyncPayParam(PayParam payParam, PayOrder payOrder) { - // 查询异步支付方式 - return payParam.getPayChannels() - .stream() - .filter(payMode -> PayChannelEnum.ASYNC_TYPE_CODE.contains(payMode.getChannel())) - .findFirst() - .orElseThrow(() -> new PayFailureException("支付参数异常, 不存在异步支付方式")); - } - - /** - * 切换异步支付参数 - */ - public PayChannelParam switchAsyncPayParam(PayParam payParam, PayOrder payOrder) { - // 查询之前的异步支付方式 - PayChannelOrder payChannelOrder = payChannelOrderManager.findByAsyncChannel(payOrder.getId()) - .orElseThrow(() -> new PayFailureException("支付订单数据异常, 不存在异步支付方式")); - - // 新的异步支付方式 - PayChannelParam payChannelParam = payParam.getPayChannels() - .stream() - .filter(payMode -> PayChannelEnum.ASYNC_TYPE_CODE.contains(payMode.getChannel())) - .findFirst() - .orElseThrow(() -> new PayFailureException("支付参数异常, 不存在异步支付方式")); - // 新传入的金额是否一致 - if (!Objects.equals(payChannelOrder.getAmount(), payChannelParam.getAmount())){ - throw new PayFailureException("传入的支付金额非法!与订单金额不一致"); - } - return payChannelParam; - } /** * 创建支付订单并保存, 返回支付订单 */ @Transactional(rollbackFor = Exception.class) public PayOrder createPayOrder(PayParam payParam) { - PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); + PayLocal payInfo = PaymentContextLocal.get() + .getPayInfo(); // 构建支付订单并保存 PayOrder order = PayBuilder.buildPayOrder(payParam); payOrderService.save(order); // 构建支付订单扩展表并保存 PayOrderExtra payOrderExtra = PayBuilder.buildPayOrderExtra(payParam, order.getId()); payOrderExtraManager.save(payOrderExtra); - payInfo.setPayOrder(order).setPayOrderExtra(payOrderExtra); + payInfo.setPayOrder(order) + .setPayOrderExtra(payOrderExtra); return order; } /** - * 创建并保存通道支付订单 + * 根据新传入的支付订单更新订单和扩展信息 */ - public void savePayChannelOrder(List payStrategies) { - PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); - List channelOrders = payStrategies.stream() - .map(AbsPayStrategy::getChannelOrder) - .filter(Objects::nonNull) - .collect(Collectors.toList()); - payChannelOrderManager.saveAll(channelOrders); - payInfo.getPayChannelOrders().addAll(channelOrders); + @Transactional(rollbackFor = Exception.class) + public void updatePayOrder(PayParam payParam,PayOrder order, PayOrderExtra payOrderExtra) { + PayLocal payInfo = PaymentContextLocal.get() + .getPayInfo(); + // 订单信息 + order.setAllocation(payParam.isAllocation()) + .setChannel(payParam.getChannel()) + .setMethod(payParam.getMethod()); + if (!order.isAllocation()) { + order.setAllocationStatus(null); + } + + // 扩展信息 + NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo(); + payOrderExtra.setClientIp(payParam.getClientIp()) + .setNotifyUrl(noticeInfo.getNotifyUrl()) + .setReturnUrl(noticeInfo.getReturnUrl()) + .setAttach(payParam.getAttach()) + .setClientIp(payParam.getClientIp()) + .setReqTime(payParam.getReqTime()); + if (CollUtil.isNotEmpty(payParam.getExtraParam())){ + payOrderExtra.setExtraParam(JSONUtil.toJsonStr(payParam.getExtraParam())); + } else { + payOrderExtra.setExtraParam(null); + } + + payOrderService.updateById(order); + payOrderExtraManager.updateById(payOrderExtra); } /** * 校验支付状态,支付成功则返回,支付失败则抛出对应的异常 */ - public PayOrder getOrderAndCheck(String businessNo) { + public PayOrder getOrderAndCheck(String bizOrderNo) { // 根据订单查询支付记录 - PayOrder payOrder = payOrderQueryService.findByBusinessNo(businessNo).orElse(null); + PayOrder payOrder = payOrderQueryService.findByOutOrderNo(bizOrderNo) + .orElse(null); if (Objects.nonNull(payOrder)) { // 待支付 - if (Objects.equals(payOrder.getStatus(), PROGRESS.getCode())){ + if (Objects.equals(payOrder.getStatus(), PROGRESS.getCode())) { // 如果支付超时, 触发订单同步操作, 同时抛出异常 if (Objects.nonNull(payOrder.getExpiredTime()) && LocalDateTimeUtil.ge(LocalDateTime.now(), payOrder.getExpiredTime())) { paySyncService.syncPayOrder(payOrder); @@ -200,7 +196,8 @@ public class PayAssistService { return payOrder; } // 已经支付状态 - if (SUCCESS.getCode().equals(payOrder.getStatus())) { + if (SUCCESS.getCode() + .equals(payOrder.getStatus())) { throw new PayFailureException("已经支付成功,请勿重新支付"); } // 支付失败类型状态 @@ -224,12 +221,9 @@ public class PayAssistService { */ public void validationLimitAmount(PayParam payParam) { // 总额校验 - PlatformLocal platformInfo = PaymentContextLocal.get().getPlatformInfo(); - Integer amount = payParam.getPayChannels() - .stream() - .map(PayChannelParam::getAmount) - .reduce(0, Integer::sum); - if (amount > platformInfo.getLimitAmount()) { + PlatformLocal platformInfo = PaymentContextLocal.get() + .getPlatformInfo(); + if (payParam.getAmount() > platformInfo.getLimitAmount()) { throw new PayFailureException("支付金额超过限额"); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayService.java index c145a3b0..d611a59f 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/service/PayService.java @@ -1,24 +1,19 @@ package cn.bootx.platform.daxpay.service.core.payment.pay.service; -import cn.bootx.platform.common.core.exception.RepetitiveOperationException; -import cn.bootx.platform.daxpay.exception.pay.PayFailureException; -import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException; +import cn.bootx.platform.common.core.exception.DataNotExistException; import cn.bootx.platform.daxpay.param.payment.pay.PayParam; import cn.bootx.platform.daxpay.result.pay.PayResult; import cn.bootx.platform.daxpay.service.common.context.PayLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.order.pay.builder.PayBuilder; -import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; +import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderExtraManager; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra; -import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderExtraService; import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService; import cn.bootx.platform.daxpay.service.core.payment.notice.service.ClientNoticeService; import cn.bootx.platform.daxpay.service.core.payment.pay.factory.PayStrategyFactory; import cn.bootx.platform.daxpay.service.func.AbsPayStrategy; import cn.bootx.platform.daxpay.util.PayUtil; -import cn.hutool.core.collection.CollectionUtil; import cn.hutool.extra.spring.SpringUtil; import com.baomidou.lock.LockInfo; import com.baomidou.lock.LockTemplate; @@ -27,13 +22,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.time.LocalDateTime; -import java.util.List; import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; -import static cn.bootx.platform.daxpay.code.PayChannelEnum.ASYNC_TYPE; import static cn.bootx.platform.daxpay.code.PayStatusEnum.SUCCESS; @@ -50,396 +40,151 @@ public class PayService { private final PayOrderService payOrderService; - private final PayOrderExtraService payOrderExtraManager; - private final PayAssistService payAssistService; private final ClientNoticeService clientNoticeService; - private final PayChannelOrderManager payChannelOrderManager; + private final PayOrderExtraManager payOrderExtraManager; private final LockTemplate lockTemplate; - - /** - * 支付下单流程 - */ - public PayResult simplePay(SimplePayParam simplePayParam) { - // 组装支付参数 - return null; - } - - /** * 支付入口 - * 支付下单接口(同步/异步/组合支付) - * 1. 同步支付:包含一个或多个同步支付通道进行支付, 使用一个事务进行包裹,要么成功要么失败 - * 2. 异步支付:会首先创建订单信息,然后再发起支付,支付成功后更新订单和通道订单信息,支付失败也会存在订单信息,预防丢单 - * 3. 组合支付(包含异步支付):会首先进行同步通道的支付,支付完成后才会调用异步支付,如果同步支付失败会回滚信息,不会进行存库 - * 执行异步通道支付的逻辑与上面异步支付的逻辑一致 - * 4. 同步支付一次支付完成,不允许重复发起支付 - * 5. 重复支付时,不允许中途将异步支付换为同步支付,也不允许更改出支付通道和支付方式之外的支付参数(请求时间、IP、签名等可以更改) - * 6. 如果要进行分账, 请求时就需要将分账标识字段穿true */ public PayResult pay(PayParam payParam){ - + // 创建返回类 + PayResult payResult = new PayResult(); // 支付参数检查 PayUtil.validation(payParam); // 校验支付限额 payAssistService.validationLimitAmount(payParam); - - String businessNo = payParam.getBusinessNo(); + // 获取商户订单号 + String bizOrderNo = payParam.getBizOrderNo(); // 加锁 - LockInfo lock = lockTemplate.lock("payment:pay:" + businessNo,10000,200); + LockInfo lock = lockTemplate.lock("payment:pay:" + bizOrderNo,10000,200); if (Objects.isNull(lock)){ - throw new RepetitiveOperationException("正在支付中,请勿重复支付"); + payResult.setMsg("正在支付中,请勿重复支付"); + return payResult; } try { // 查询并检查订单 - PayOrder payOrder = payAssistService.getOrderAndCheck(payParam.getBusinessNo()); + PayOrder payOrder = payAssistService.getOrderAndCheck(payParam.getBizOrderNo()); // 初始化上下文 payAssistService.initPayContext(payOrder, payParam); - // 走首次下单逻辑还是重复发起逻辑 + // 走首次下单逻辑还是重复下档逻辑 if (Objects.isNull(payOrder)){ - // 判断不同的支付请求类型, 然后走不同的逻辑 - List payChannels = payParam.getPayChannels(); - // 不包含异步支付通道 - if (PayUtil.isNotSync(payChannels)){ - return SpringUtil.getBean(this.getClass()).firstSyncPay(payParam); - } - // 单个异步通道支付 - else if (payChannels.size() == 1 && !PayUtil.isNotSync(payChannels)) { - return this.firstAsyncPay(payParam); - } - // 包含异步通道的组合支付 - else if (!PayUtil.isNotSync(payChannels)) { - return this.firstCombinationPay(payParam); - } else { - throw new PayFailureException("支付参数错误"); - } + return this.firstPay(payParam); } else { - List payChannels = payParam.getPayChannels(); - // 不包含异步支付通道 - if (PayUtil.isNotSync(payChannels)){ - throw new PayFailureException("支付参数错误, 不可以中途切换为同步支付通道"); - } - // 单个异步通道支付 - if (payOrder.isAsyncPay() && !payOrder.isCombinationPay()){ - return this.repeatAsyncPay(payParam,payOrder); - } - // 包含异步通道的组合支付 - else if (payOrder.isAsyncPay()){ - return this.repeatCombinationPay(payParam, payOrder); - } else { - throw new PayFailureException("支付参数错误"); - } + return this.repeatPay(payParam,payOrder); } } catch (Exception e) { - throw new RuntimeException(e); + payResult.setMsg(e.getMessage()); + return payResult; } finally { lockTemplate.releaseLock(lock); } } /** - * 首次同步支付, 可以为一个或多个同步通道进行支付 - * 使用事务,保证支付只有成功或失败两种状态 - */ - @Transactional(rollbackFor = Exception.class) - public PayResult firstSyncPay(PayParam payParam){ - PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); - - // 获取支付方式,通过工厂生成对应的策略组 - List strategies = PayStrategyFactory.createAsyncLast(payParam.getPayChannels()); - if (CollectionUtil.isEmpty(strategies)) { - throw new PayUnsupportedMethodException(); - } - - // 初始化支付参数 - strategies.forEach(strategy -> strategy.setPayParam(payParam)); - - // 执行支付前处理动作, 进行校验 - strategies.forEach(AbsPayStrategy::doBeforePayHandler); - - // 创建支付订单和扩展记录并返回支付订单对象 - PayOrder payOrder = payAssistService.createPayOrder(payParam); - strategies.forEach(strategy -> strategy.setOrder(payOrder)); - - // 生成支付通道订单 - strategies.forEach(AbsPayStrategy::generateChannelOrder); - // 支付操作 - strategies.forEach(AbsPayStrategy::doPayHandler); - // 支付成功操作, 进行扣款、创建记录类类似的操作 - strategies.forEach(AbsPayStrategy::doSuccessHandler); - payOrder.setStatus(SUCCESS.getCode()) - .setPayTime(LocalDateTime.now()); - // 保存通道支付订单 - payAssistService.savePayChannelOrder(strategies); - // 更新订单信息 - payOrderService.updateById(payOrder); - // 支付完成 发送通知 - clientNoticeService.registerPayNotice(payOrder, payInfo.getPayOrderExtra(), payInfo.getPayChannelOrders()); - return PayBuilder.buildPayResultByPayOrder(payOrder); - } - - /** - * 首次单个异步通道支付 + * 首次支付 * 拆分为多阶段,1. 保存订单记录信息 2 调起支付 3. 支付成功后操作 */ - private PayResult firstAsyncPay(PayParam payParam){ - PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); - - // 获取支付方式,通过工厂生成对应的策略组 - List strategies = PayStrategyFactory.createAsyncLast(payParam.getPayChannels()); - if (CollectionUtil.isEmpty(strategies)) { - throw new PayUnsupportedMethodException(); - } - // 获取异步通道 - AbsPayStrategy asyncPayStrategy = Optional.ofNullable(strategies.get(0)) - .orElseThrow(() -> new PayFailureException("数据和代码异常, 请排查代码")); - + public PayResult firstPay(PayParam payParam){ + // 获取支付策略类 + AbsPayStrategy payStrategy = PayStrategyFactory.create(payParam.getChannel()); // 初始化支付的参数 - asyncPayStrategy.setPayParam(payParam); - - // 执行支付前处理动作, 进行各种校验 - asyncPayStrategy.doBeforePayHandler(); - // 执行支付前的保存动作, 保持订单和通道订单的原子性 - PayOrder payOrder = SpringUtil.getBean(this.getClass()).firstPreAsyncPay(asyncPayStrategy, payParam); - - // 支付操作 - try { - asyncPayStrategy.doPayHandler(); - } catch (Exception e) { - // 记录错误原因 - PayOrderExtra payOrderExtra = payInfo.getPayOrderExtra(); - payOrderExtra.setErrorMsg(e.getMessage()); - payOrderExtraManager.update(payOrderExtra); - throw e; - } - // 支付调起成功后操作, 使用事务来保证数据一致性 - return SpringUtil.getBean(this.getClass()).firstAsyncPaySuccess(asyncPayStrategy,payOrder); - - } - - /** - * 异步单通道支付的订单预保存, 保存订单和通道订单 - */ - @Transactional(rollbackFor = Exception.class) - public PayOrder firstPreAsyncPay(AbsPayStrategy asyncPayStrategy, PayParam payParam){ - // 创建支付订单和扩展记录并返回支付订单对象 + payStrategy.setPayParam(payParam); + // 执行支付前处理动作, 进行各种校验, 校验通过才会进行下面的操作 + payStrategy.doBeforePayHandler(); + // 执行支付前的保存动作, 保存支付订单和扩展记录 PayOrder payOrder = payAssistService.createPayOrder(payParam); - asyncPayStrategy.setOrder(payOrder); - // 生成通道支付订单 - asyncPayStrategy.generateChannelOrder(); - return payOrder; - } - - /** - * 首次单通道异步支付成功后操作, 更新订单和扥爱松 - */ - @Transactional(rollbackFor = Exception.class) - public PayResult firstAsyncPaySuccess(AbsPayStrategy asyncPayStrategy, PayOrder payOrder){ - PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); - // 支付调用成功操作, - asyncPayStrategy.doSuccessHandler(); - // 如果支付完成, 进行订单完成处理, 同时发送回调消息 - if (payInfo.isPayComplete()) { - // TODO 使用网关返回的时间 - payOrder.setGatewayOrderNo(payInfo.getGatewayOrderNo()) - .setStatus(SUCCESS.getCode()) - .setPayTime(LocalDateTime.now()); - } - payOrderService.updateById(payOrder); - // 扩展记录更新 - PayOrderExtra payOrderExtra = payInfo.getPayOrderExtra(); - payOrderExtra.setErrorMsg(null); - payOrderExtraManager.update(payOrderExtra); - // 如果支付完成 发送通知 - if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){ - clientNoticeService.registerPayNotice(payOrder, payOrderExtra, payInfo.getPayChannelOrders()); - } - return PayBuilder.buildPayResultByPayOrder(payOrder); - } - - /** - * 首次组合支付, 包含异步支付通道 - */ - private PayResult firstCombinationPay(PayParam payParam){ - PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); - // ------------------------- 进行同步支付, 成功后返回异步通道策略类 ------------------------------- - AbsPayStrategy asyncPayStrategy = SpringUtil.getBean(this.getClass()).firstCombinationSyncPay(payParam); - // ------------------------- 进行异步支付 ------------------------------- - try { - // 异步支付操作 - asyncPayStrategy.doPayHandler(); - } catch (Exception e) { - // 记录错误原因 - PayOrderExtra payOrderExtra = payInfo.getPayOrderExtra(); - payOrderExtra.setErrorMsg(e.getMessage()); - payOrderExtraManager.update(payOrderExtra); - throw e; - } - // 支付调起成功后操作, 使用事务来保证数据一致性 - return SpringUtil.getBean(this.getClass()).firstCombinationPaySuccess(asyncPayStrategy); - } - - /** - * 首次组合支付, 先进行同步支付, 如果成功返回异步支付策略 - * 注意: 同时也对异步支付通道进行校验和订单的保存, 保证整个订单操作的原子性 - */ - @Transactional(rollbackFor = Exception.class) - public AbsPayStrategy firstCombinationSyncPay(PayParam payParam){ - - // 获取支付方式,通过工厂生成对应的策略组 - List strategies = PayStrategyFactory.createAsyncLast(payParam.getPayChannels()); - if (CollectionUtil.isEmpty(strategies)) { - throw new PayUnsupportedMethodException(); - } - // 初始化支付的参数 - for (AbsPayStrategy strategy : strategies) { - strategy.setPayParam(payParam); - } - - // 初始化支付参数 - strategies.forEach(strategy -> strategy.setPayParam(payParam)); - - // 执行支付前处理动作, 对各通道进行检验 - strategies.forEach(AbsPayStrategy::doBeforePayHandler); - // 创建支付订单和扩展记录并返回支付订单对象 - PayOrder payOrder = payAssistService.createPayOrder(payParam); - strategies.forEach(strategy -> strategy.setOrder(payOrder)); - - // 生成支付通道订单, 同时也执行异步支付通道订单的保存, 保证订单操作的原子性 - strategies.forEach(AbsPayStrategy::generateChannelOrder); - - // 取出同步通道 然后进行同步通道的支付操作 - List syncStrategies = strategies.stream() - .filter(strategy -> !ASYNC_TYPE.contains(strategy.getChannel())) - .collect(Collectors.toList()); - syncStrategies.forEach(strategy -> strategy.setPayParam(payParam)); - - // 支付操作 - syncStrategies.forEach(AbsPayStrategy::doPayHandler); - // 支付调起成功操作, 进行扣款、创建记录类类似的操作 - syncStrategies.forEach(AbsPayStrategy::doSuccessHandler); - // 保存通道支付订单 - payAssistService.savePayChannelOrder(strategies); - - return strategies.stream() - .filter(o-> ASYNC_TYPE.contains(o.getChannel())) - .findFirst() - .orElseThrow(()->new PayFailureException("支付代码异常,请检查")); - } - - /** - * 首次组合支付成功后操作 - */ - @Transactional(rollbackFor = Exception.class) - public PayResult firstCombinationPaySuccess(AbsPayStrategy asyncPayStrategy){ - PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); - PayOrder payOrder = payInfo.getPayOrder(); - // 支付调起成功的处理 - asyncPayStrategy.doSuccessHandler(); - // 如果支付完成, 进行订单完成处理, 同时发送回调消息 - if (payInfo.isPayComplete()) { - // TODO 使用网关返回的时间 - payOrder.setGatewayOrderNo(payInfo.getGatewayOrderNo()) - .setStatus(SUCCESS.getCode()) - .setPayTime(LocalDateTime.now()); - } - payOrderService.updateById(payOrder); - // 扩展记录更新 - PayOrderExtra payOrderExtra = payInfo.getPayOrderExtra(); - payOrderExtra.setErrorMsg(null); - payOrderExtraManager.update(payOrderExtra); - // 如果支付完成 发送通知 - if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){ - clientNoticeService.registerPayNotice(payOrder, payOrderExtra, payInfo.getPayChannelOrders()); - } - return PayBuilder.buildPayResultByPayOrder(payOrder); - } - - /** - * 重复支付-单异步通道支付 - */ - public PayResult repeatAsyncPay(PayParam payParam, PayOrder payOrder){ - // 查询支付扩展订单信息 - PayOrderExtra payOrderExtra = payOrderExtraManager.findById(payOrder.getId()); - //获取异步支付通道参数并构建支付策略 - PayChannelParam payChannelParam = payAssistService.switchAsyncPayParam(payParam, payOrder); - AbsPayStrategy asyncPayStrategy = PayStrategyFactory.create(payChannelParam); - // 初始化支付的参数 - asyncPayStrategy.initPayParam(payOrder, payParam); - // 执行支付前处理动作 - asyncPayStrategy.doBeforePayHandler(); - // 更新支付通道订单的信息 - asyncPayStrategy.generateChannelOrder(); + payStrategy.setOrder(payOrder); try { // 支付操作 - asyncPayStrategy.doPayHandler(); + payStrategy.doPayHandler(); } catch (Exception e) { - // 记录错误原因 - payOrderExtra.setErrorMsg(e.getMessage()); - payOrderExtraManager.update(payOrderExtra); + payOrder.setErrorMsg(e.getMessage()); + payOrderService.updateById(payOrder); throw e; } // 支付调起成功后操作, 使用事务来保证数据一致性 - return SpringUtil.getBean(this.getClass()).repeatPaySuccess(asyncPayStrategy, payOrder, payOrderExtra); + return SpringUtil.getBean(this.getClass()).firstPaySuccess(payOrder); } /** - * 重复发起组合支付(包含异步支付) + * 首次成功后操作, 更新订单信息 */ - public PayResult repeatCombinationPay(PayParam payParam, PayOrder payOrder){ + @Transactional(rollbackFor = Exception.class) + public PayResult firstPaySuccess(PayOrder payOrder){ PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); - PayOrderExtra payOrderExtra = payInfo.getPayOrderExtra(); - PayChannelParam payChannelParam = payAssistService.switchAsyncPayParam(payParam, payOrder); - // 取出异步通道 然后进行支付 - AbsPayStrategy asyncPayStrategy = PayStrategyFactory.create(payChannelParam); - // 初始化参数 - asyncPayStrategy.initPayParam(payOrder, payParam); - // 支付前准备 - asyncPayStrategy.doBeforePayHandler(); - // 更新异步支付通道订单信息 - asyncPayStrategy.generateChannelOrder(); + // 如果支付完成, 进行订单完成处理, 同时发送回调消息 + if (payInfo.isComplete()) { + payOrder.setOutOrderNo(payInfo.getOutOrderNo()) + .setStatus(SUCCESS.getCode()) + .setPayTime(payInfo.getCompleteTime()); + } + payOrderService.updateById(payOrder); + // 扩展记录更新 + payOrder.setErrorCode(null); + payOrder.setErrorMsg(null); + payOrderService.updateById(payOrder); + // 如果支付完成 发送通知 + if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){ + clientNoticeService.registerPayNotice(payOrder, payInfo.getPayOrderExtra()); + } + return PayBuilder.buildResultByPayOrder(payOrder); + } + + /** + * 重复支付 + */ + public PayResult repeatPay(PayParam payParam, PayOrder payOrder){ + // 获取支付策略类 + AbsPayStrategy payStrategy = PayStrategyFactory.create(payParam.getChannel()); + // 初始化支付的参数 + payStrategy.initPayParam(payOrder, payParam); + // 执行支付前处理动作 + payStrategy.doBeforePayHandler(); + // 查询订单扩展记录 + PayOrderExtra payOrderExtra = payOrderExtraManager.findById(payOrder.getId()).orElseThrow(() -> new DataNotExistException("支付订单不完整")); + // 执行支付前的更新动作, 更新并保存订单和扩展的数据 + payAssistService.updatePayOrder(payParam, payOrder, payOrderExtra); + try { - // 异步支付操作 - asyncPayStrategy.doPayHandler(); + // 支付操作 + payStrategy.doPayHandler(); } catch (Exception e) { // 记录错误原因 - payOrderExtra.setErrorMsg(e.getMessage()); - payOrderExtraManager.update(payOrderExtra); + payOrder.setErrorMsg(e.getMessage()); + payOrderService.updateById(payOrder); throw e; } // 支付调起成功后操作, 使用事务来保证数据一致性 - return SpringUtil.getBean(this.getClass()).repeatPaySuccess(asyncPayStrategy, payOrder,payOrderExtra); - + return SpringUtil.getBean(this.getClass()).repeatPaySuccess(payOrder, payOrderExtra); } /** * 重复支付成功后操作 */ @Transactional(rollbackFor = Exception.class) - public PayResult repeatPaySuccess(AbsPayStrategy asyncPayStrategy, PayOrder payOrder, PayOrderExtra payOrderExtra) { + public PayResult repeatPaySuccess(PayOrder payOrder, PayOrderExtra payOrderExtra) { PayLocal payInfo = PaymentContextLocal.get().getPayInfo(); - asyncPayStrategy.doSuccessHandler(); // 如果支付完成, 进行订单完成处理, 同时发送回调消息 - if (payInfo.isPayComplete()) { - // TODO 使用网关返回的时间 - payOrder.setGatewayOrderNo(payInfo.getGatewayOrderNo()) + if (payInfo.isComplete()) { + payOrder.setOutOrderNo(payInfo.getOutOrderNo()) .setStatus(SUCCESS.getCode()) - .setPayTime(LocalDateTime.now()); + .setPayTime(payInfo.getCompleteTime()); } payOrderService.updateById(payOrder); // 扩展记录更新 - payOrderExtra.setErrorMsg(null); - payOrderExtraManager.update(payOrderExtra); + payOrder.setErrorMsg(null); + payOrder.setErrorCode(null); + payOrderService.updateById(payOrder); // 如果支付完成 发送通知 if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){ // 查询通道订单 - List payChannelOrders = payChannelOrderManager.findAllByPaymentId(payOrder.getOrderNo()); - clientNoticeService.registerPayNotice(payOrder, payOrderExtra, payChannelOrders); + clientNoticeService.registerPayNotice(payOrder, payOrderExtra); } - return PayBuilder.buildPayResultByPayOrder(payOrder); + return PayBuilder.buildResultByPayOrder(payOrder); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/AliPayStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/AliPayStrategy.java index cf381387..ef90368c 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/AliPayStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/AliPayStrategy.java @@ -1,17 +1,11 @@ package cn.bootx.platform.daxpay.service.core.payment.pay.strategy; import cn.bootx.platform.daxpay.code.PayChannelEnum; -import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.param.channel.AliPayParam; -import cn.bootx.platform.daxpay.service.common.context.PayLocal; -import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig; import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayConfigService; -import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayRecordService; import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayService; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService; import cn.bootx.platform.daxpay.service.func.AbsPayStrategy; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; @@ -35,14 +29,10 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT @RequiredArgsConstructor public class AliPayStrategy extends AbsPayStrategy { - private final PayChannelOrderService channelOrderService; - private final AliPayService aliPayService; private final AliPayConfigService alipayConfigService; - private final AliPayRecordService aliRecordService; - private AliPayConfig alipayConfig; private AliPayParam aliPayParam; @@ -59,7 +49,7 @@ public class AliPayStrategy extends AbsPayStrategy { public void doBeforePayHandler() { try { // 支付宝参数验证 - Map channelParam = this.getPayChannelParam().getChannelParam(); + Map channelParam = this.getPayParam().getExtraParam(); if (CollUtil.isNotEmpty(channelParam)) { this.aliPayParam = BeanUtil.toBean(channelParam, AliPayParam.class); } @@ -70,15 +60,10 @@ public class AliPayStrategy extends AbsPayStrategy { catch (JSONException e) { throw new PayFailureException("支付参数错误"); } - // 检查金额 - PayChannelParam payMode = this.getPayChannelParam(); - if (payMode.getAmount() <= 0) { - throw new PayAmountAbnormalException(); - } // 检查并获取支付宝支付配置 this.initAlipayConfig(); - // 校验 - aliPayService.validation(this.getPayChannelParam(), alipayConfig); + // 支付宝相关校验 + aliPayService.validation(this.getPayParam(), alipayConfig); } /** @@ -86,31 +71,7 @@ public class AliPayStrategy extends AbsPayStrategy { */ @Override public void doPayHandler() { - aliPayService.pay(this.getOrder(), this.getPayChannelParam(), this.aliPayParam, this.alipayConfig); - } - - /** - * 不使用默认的生成通道支付单方法, 异步支付通道的支付订单自己管理 - * channelOrderService.switchAsyncPayChannel 进行切换 - */ - @Override - public void generateChannelOrder() { - // 创建或切换支付通道订单 - channelOrderService.switchAsyncPayChannel(this.getOrder(), this.getPayChannelParam()); - } - - /** - * 支付调起成功, 保存或更新通道支付订单 - */ - @Override - public void doSuccessHandler() { - PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo(); - // 更新通道支付订单 - PayChannelOrder payChannelOrder = channelOrderService.switchAsyncPayChannel(this.getOrder(), this.getPayChannelParam()); - // 支付完成, 保存记录 - if (asyncPayInfo.isPayComplete()) { - aliRecordService.pay(this.getOrder(), payChannelOrder); - } + aliPayService.pay(this.getOrder(), this.aliPayParam, this.alipayConfig); } /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/UnionPayStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/UnionPayStrategy.java index aafdd996..32c00cd2 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/UnionPayStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/UnionPayStrategy.java @@ -1,17 +1,11 @@ package cn.bootx.platform.daxpay.service.core.payment.pay.strategy; import cn.bootx.platform.daxpay.code.PayChannelEnum; -import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.param.channel.UnionPayParam; -import cn.bootx.platform.daxpay.service.common.context.PayLocal; -import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayConfig; import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayConfigService; -import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayRecordService; import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayService; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService; import cn.bootx.platform.daxpay.service.func.AbsPayStrategy; import cn.bootx.platform.daxpay.service.sdk.union.api.UnionPayKit; import cn.hutool.core.bean.BeanUtil; @@ -38,14 +32,10 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT @RequiredArgsConstructor public class UnionPayStrategy extends AbsPayStrategy { - private final PayChannelOrderService channelOrderService; - private final UnionPayService unionPayService; private final UnionPayConfigService unionPayConfigService; - private final UnionPayRecordService unionPayRecordService; - private UnionPayParam unionPayParam; private UnionPayConfig unionPayConfig; @@ -61,7 +51,7 @@ public class UnionPayStrategy extends AbsPayStrategy { public void doBeforePayHandler() { try { // 云闪付参数验证 - Map channelParam = this.getPayChannelParam().getChannelParam(); + Map channelParam = this.getPayParam().getExtraParam(); if (CollUtil.isNotEmpty(channelParam)) { this.unionPayParam = BeanUtil.toBean(channelParam, UnionPayParam.class); } @@ -72,14 +62,9 @@ public class UnionPayStrategy extends AbsPayStrategy { catch (JSONException e) { throw new PayFailureException("支付参数错误"); } - // 检查金额 - PayChannelParam payMode = this.getPayChannelParam(); - if (payMode.getAmount() <= 0) { - throw new PayAmountAbnormalException(); - } // 检查并获取云闪付支付配置 this.unionPayConfig = unionPayConfigService.getAndCheckConfig(); - unionPayService.validation(this.getPayChannelParam(), unionPayConfig); + unionPayService.validation(this.getPayParam(), unionPayConfig); } /** @@ -88,32 +73,7 @@ public class UnionPayStrategy extends AbsPayStrategy { @Override public void doPayHandler() { UnionPayKit unionPayKit = unionPayConfigService.initPayService(unionPayConfig); - unionPayService.pay(this.getOrder(), this.getPayChannelParam(), this.unionPayParam, unionPayKit); + unionPayService.pay(this.getOrder(), this.unionPayParam, unionPayKit); } - /** - * 不使用默认的生成通道支付单方法, 异步支付通道的支付订单自己管理 - * channelOrderService.switchAsyncPayChannel 进行切换 - */ - @Override - public void generateChannelOrder() { - // 创建或切换支付通道订单 - channelOrderService.switchAsyncPayChannel(this.getOrder(), this.getPayChannelParam()); - } - - /** - * 支付调起成功, 保存或更新通道支付订单 - */ - @Override - public void doSuccessHandler() { - PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo(); - // 更新支付通道信息 - PayChannelOrder payChannelOrder = channelOrderService.switchAsyncPayChannel(this.getOrder(), this.getPayChannelParam()); - // 支付完成, 保存记录 - if (asyncPayInfo.isPayComplete()) { - unionPayRecordService.pay(this.getOrder(), payChannelOrder); - } - } - - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/WalletPayStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/WalletPayStrategy.java index 93fc3d0b..f301a70a 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/WalletPayStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/WalletPayStrategy.java @@ -11,7 +11,6 @@ import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.WalletConfig; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletConfigService; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletPayService; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletQueryService; -import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletRecordService; import cn.bootx.platform.daxpay.service.func.AbsPayStrategy; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; @@ -42,12 +41,8 @@ public class WalletPayStrategy extends AbsPayStrategy { private final WalletQueryService walletQueryService; - private final WalletRecordService walletRecordService; - private Wallet wallet; - private WalletConfig walletConfig; - @Override public PayChannelEnum getChannel() { return PayChannelEnum.WALLET; @@ -61,7 +56,7 @@ public class WalletPayStrategy extends AbsPayStrategy { WalletPayParam walletPayParam = new WalletPayParam(); try { // 钱包参数验证 - Map channelParam = this.getPayChannelParam().getChannelParam(); + Map channelParam = this.getPayParam().getExtraParam(); if (CollUtil.isNotEmpty(channelParam)) { walletPayParam = BeanUtil.toBean(channelParam, WalletPayParam.class); } @@ -69,7 +64,7 @@ public class WalletPayStrategy extends AbsPayStrategy { throw new PayFailureException("支付参数错误"); } - this.walletConfig = walletConfigService.getAndCheckConfig(); + WalletConfig walletConfig = walletConfigService.getAndCheckConfig(); // 获取钱包 this.wallet = walletQueryService.getWallet(walletPayParam); @@ -81,14 +76,17 @@ public class WalletPayStrategy extends AbsPayStrategy { throw new WalletBannedException(); } // 判断是否超过限额 - if (getPayChannelParam().getAmount() > this.walletConfig.getSingleLimit()){ + if (this.getPayParam().getAmount() > walletConfig.getSingleLimit()){ throw new PayFailureException("钱包支付金额超过限额"); } - // 判断余额 - if (this.wallet.getBalance() < getPayChannelParam().getAmount()) { + if (this.wallet.getBalance() < this.getPayParam().getAmount()) { throw new WalletLackOfBalanceException(); } + // 分账 + if (this.getPayParam().isAllocation()){ + throw new PayFailureException("钱包支付不支持分账"); + } } /** @@ -96,7 +94,6 @@ public class WalletPayStrategy extends AbsPayStrategy { */ @Override public void doPayHandler() { - walletPayService.pay(getPayChannelParam().getAmount(), this.wallet); - walletRecordService.pay(this.getChannelOrder(), this.getOrder().getTitle(),this.wallet); + walletPayService.pay(this.getPayParam().getAmount(), this.wallet); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/WeChatPayStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/WeChatPayStrategy.java index d14912cb..a305353d 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/WeChatPayStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/pay/strategy/WeChatPayStrategy.java @@ -1,15 +1,9 @@ package cn.bootx.platform.daxpay.service.core.payment.pay.strategy; import cn.bootx.platform.daxpay.code.PayChannelEnum; -import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException; -import cn.bootx.platform.daxpay.service.common.context.PayLocal; -import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig; import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayConfigService; -import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayRecordService; import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayService; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; -import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService; import cn.bootx.platform.daxpay.service.func.AbsPayStrategy; import cn.bootx.platform.daxpay.service.param.channel.wechat.WeChatPayParam; import cn.hutool.core.bean.BeanUtil; @@ -33,14 +27,10 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT @RequiredArgsConstructor public class WeChatPayStrategy extends AbsPayStrategy { - private final PayChannelOrderService channelOrderService; - private final WeChatPayConfigService weChatPayConfigService; private final WeChatPayService weChatPayService; - private final WeChatPayRecordService weChatPayRecordService; - private WeChatPayConfig weChatPayConfig; private WeChatPayParam weChatPayParam; @@ -59,31 +49,15 @@ public class WeChatPayStrategy extends AbsPayStrategy { @Override public void doBeforePayHandler() { // 微信参数验证 - Map channelParam = this.getPayChannelParam().getChannelParam(); + Map channelParam = this.getPayParam().getExtraParam(); if (CollUtil.isNotEmpty(channelParam)) { this.weChatPayParam = BeanUtil.toBean(channelParam, WeChatPayParam.class); } else { this.weChatPayParam = new WeChatPayParam(); } - - // 检查金额 - PayChannelParam payMode = this.getPayChannelParam(); - if (payMode.getAmount() <= 0) { - throw new PayAmountAbnormalException(); - } - // 检查并获取微信支付配置 this.initWeChatPayConfig(); - weChatPayService.validation(this.getPayChannelParam(), weChatPayConfig); - } - - /** - * 不使用默认的生成通道支付单方法, 异步支付通道的支付订单自己管理 - */ - @Override - public void generateChannelOrder() { - // 创建或切换支付通道订单 - channelOrderService.switchAsyncPayChannel(this.getOrder(), this.getPayChannelParam()); + weChatPayService.validation(this.getPayParam(), weChatPayConfig); } /** @@ -91,21 +65,7 @@ public class WeChatPayStrategy extends AbsPayStrategy { */ @Override public void doPayHandler() { - weChatPayService.pay(this.getOrder(), this.weChatPayParam, this.getPayChannelParam(), this.weChatPayConfig); - } - - /** - * 支付调起成功 , 保存或更新通道支付订单 - */ - @Override - public void doSuccessHandler() { - PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo(); - // 更新通道支付订单 - PayChannelOrder payChannelOrder = channelOrderService.switchAsyncPayChannel(this.getOrder(), this.getPayChannelParam()); - // 是否支付完成, 保存流水记录 - if (asyncPayInfo.isPayComplete()){ - weChatPayRecordService.pay(this.getOrder(), payChannelOrder); - } + weChatPayService.pay(this.getOrder(), this.weChatPayParam, this.weChatPayConfig); } /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/AlipayReconcileStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/AlipayReconcileStrategy.java index 387047c9..38330e5f 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/AlipayReconcileStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/AlipayReconcileStrategy.java @@ -46,8 +46,6 @@ public class AlipayReconcileStrategy extends AbsReconcileStrategy { private final DaxPaySequenceHandler daxPaySequenceHandler; - private AliPayConfig config; - /** * 策略标识 @@ -79,8 +77,8 @@ public class AlipayReconcileStrategy extends AbsReconcileStrategy { */ @Override public void doBeforeHandler() { - this.config = configService.getConfig(); - configService.initConfig(this.config); + AliPayConfig config = configService.getConfig(); + configService.initConfig(config); } /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/UnionPayReconcileStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/UnionPayReconcileStrategy.java index 69d06994..f2bebc33 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/UnionPayReconcileStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/UnionPayReconcileStrategy.java @@ -4,9 +4,7 @@ import cn.bootx.platform.common.core.util.LocalDateTimeUtil; import cn.bootx.platform.common.sequence.func.Sequence; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.service.core.channel.union.convert.UnionPayConvert; -import cn.bootx.platform.daxpay.service.core.channel.union.dao.UnionPayRecordManager; import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayConfig; -import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayRecord; import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayConfigService; import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayReconcileService; import cn.bootx.platform.daxpay.service.core.payment.reconcile.domain.GeneralReconcileRecord; @@ -45,8 +43,6 @@ public class UnionPayReconcileStrategy extends AbsReconcileStrategy { private final UnionPayReconcileService reconcileService; - private final UnionPayRecordManager recordManager; - private final DaxPaySequenceHandler daxPaySequenceHandler; private UnionPayKit unionPayKit; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/WechatPayReconcileStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/WechatPayReconcileStrategy.java index 354cd1e2..9d1172a3 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/WechatPayReconcileStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/WechatPayReconcileStrategy.java @@ -42,8 +42,6 @@ public class WechatPayReconcileStrategy extends AbsReconcileStrategy { private final WeChatPayConfigService weChatPayConfigService; - private final WeChatPayRecordManager recordManager; - private final DaxPaySequenceHandler daxPaySequenceHandler; private WeChatPayConfig config; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/factory/RefundStrategyFactory.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/factory/RefundStrategyFactory.java index 8968dc72..884387d2 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/factory/RefundStrategyFactory.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/factory/RefundStrategyFactory.java @@ -2,20 +2,12 @@ package cn.bootx.platform.daxpay.service.core.payment.refund.factory; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException; -import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder; -import cn.bootx.platform.daxpay.service.core.payment.refund.strategy.*; +import cn.bootx.platform.daxpay.service.core.payment.refund.strategy.AliRefundStrategy; +import cn.bootx.platform.daxpay.service.core.payment.refund.strategy.UnionRefundStrategy; +import cn.bootx.platform.daxpay.service.core.payment.refund.strategy.WalletRefundStrategy; +import cn.bootx.platform.daxpay.service.core.payment.refund.strategy.WeChatRefundStrategy; import cn.bootx.platform.daxpay.service.func.AbsRefundStrategy; -import cn.hutool.core.collection.CollectionUtil; import cn.hutool.extra.spring.SpringUtil; -import lombok.val; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -import static cn.bootx.platform.daxpay.code.PayChannelEnum.ASYNC_TYPE_CODE; /** * 退款策略工厂 @@ -24,28 +16,15 @@ import static cn.bootx.platform.daxpay.code.PayChannelEnum.ASYNC_TYPE_CODE; */ public class RefundStrategyFactory { - /** - * 通过订单生成退款策略 - */ - public static List createAsyncFrontByOrder(List refundChannelOrders) { - // 生成通道订单参数 - List channelParams = refundChannelOrders.stream() - .map(o -> new RefundChannelParam() - .setAmount(o.getAmount()) - .setChannel(o.getChannel())) - .collect(Collectors.toList()); - return createAsyncFront(channelParams); - } - /** * 根据传入的支付通道创建策略 * @return 支付策略 */ - public static AbsRefundStrategy createAsyncFront(RefundChannelParam refundChannelParam) { + public static AbsRefundStrategy create(String channel) { AbsRefundStrategy strategy; - PayChannelEnum channelEnum = PayChannelEnum.findByCode(refundChannelParam.getChannel()); + PayChannelEnum channelEnum = PayChannelEnum.findByCode(channel); switch (channelEnum) { case ALI: strategy = SpringUtil.getBean(AliRefundStrategy.class); @@ -62,62 +41,7 @@ public class RefundStrategyFactory { default: throw new PayUnsupportedMethodException(); } - strategy.setRefundChannelParam(refundChannelParam); return strategy; } - /** - * 根据传入的支付类型批量创建策略, 异步支付在后面 - * 同步支付逻辑完后才执行异步支付的逻辑, 预防异步执行成功, 然同步执行失败. 导致异步支付无法回滚的问题 - */ - public static List createAsyncLast(List refundChannelParams) { - return createAsyncFront(refundChannelParams, true); - } - - /** - * 根据传入的支付类型批量创建策略, 异步支付在前面 - */ - public static List createAsyncFront(List refundChannelParams) { - return createAsyncFront(refundChannelParams, false); - } - - /** - * 根据传入的支付类型批量创建策略 - * @param refundChannelParams 支付类型 - * @return 支付策略 - */ - private static List createAsyncFront(List refundChannelParams, boolean description) { - if (CollectionUtil.isEmpty(refundChannelParams)) { - return Collections.emptyList(); - } - List list = new ArrayList<>(refundChannelParams.size()); - - // 同步支付 - val syncRefundModeParams = refundChannelParams.stream() - .filter(Objects::nonNull) - .filter(payModeParam -> !ASYNC_TYPE_CODE.contains(payModeParam.getChannel())) - .collect(Collectors.toList()); - - // 异步支付 - val asyncRefundModeParams = refundChannelParams.stream() - .filter(Objects::nonNull) - .filter(payModeParam -> ASYNC_TYPE_CODE.contains(payModeParam.getChannel())) - .collect(Collectors.toList()); - - List sortList = new ArrayList<>(refundChannelParams.size()); - - // 异步在后面 - if (description) { - sortList.addAll(syncRefundModeParams); - sortList.addAll(asyncRefundModeParams); - } - else { - sortList.addAll(asyncRefundModeParams); - sortList.addAll(syncRefundModeParams); - } - - // 此处有一个根据Type的反转排序, - sortList.stream().filter(Objects::nonNull).forEach(payMode -> list.add(createAsyncFront(payMode))); - return list; - } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundAssistService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundAssistService.java index 74731f60..a56c7da7 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundAssistService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundAssistService.java @@ -1,8 +1,6 @@ package cn.bootx.platform.daxpay.service.core.payment.refund.service; -import cn.bootx.platform.common.core.exception.ValidationFailedException; -import cn.bootx.platform.common.core.util.CollUtil; -import cn.bootx.platform.daxpay.code.PayChannelEnum; +import cn.bootx.platform.common.core.exception.DataNotExistException; import cn.bootx.platform.daxpay.code.PayStatusEnum; import cn.bootx.platform.daxpay.code.RefundStatusEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; @@ -14,14 +12,11 @@ import cn.bootx.platform.daxpay.service.common.context.RefundLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService; -import cn.bootx.platform.daxpay.service.core.order.refund.dao.RefundChannelOrderManager; import cn.bootx.platform.daxpay.service.core.order.refund.dao.RefundOrderExtraManager; import cn.bootx.platform.daxpay.service.core.order.refund.dao.RefundOrderManager; -import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder; import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrder; import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrderExtra; import cn.bootx.platform.daxpay.util.OrderNoGenerateUtil; -import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -33,7 +28,6 @@ import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; import static cn.bootx.platform.daxpay.code.RefundStatusEnum.SUCCESS; @@ -52,8 +46,6 @@ public class RefundAssistService { private final RefundOrderExtraManager refundOrderExtraManager; - private final RefundChannelOrderManager payRefundChannelOrderManager; - /** * 初始化上下文 */ @@ -84,17 +76,34 @@ public class RefundAssistService { } } + /** + * 根据退款参数获取退款订单 + */ + public RefundOrder getRefundOrder(RefundParam param){ + // 查询退款单 + RefundOrder refundOrder = null; + if (Objects.nonNull(param.getRefundNo())){ + refundOrder = refundOrderManager.findById(param.getRefundNo()) + .orElseThrow(() -> new DataNotExistException("未查询到支付订单")); + } + if (Objects.isNull(refundOrder)){ + refundOrder = refundOrderManager.findByRefundNo(param.getRefundNo()) + .orElseThrow(() -> new DataNotExistException("未查询到支付订单")); + } + return refundOrder; + } + /** * 根据退款参数获取支付订单 */ public PayOrder getPayOrder(RefundParam param){ PayOrder payOrder = null; - if (Objects.nonNull(param.getPaymentId())){ - payOrder = payOrderQueryService.findById(param.getPaymentId()) + if (Objects.nonNull(param.getOrderNo())){ + payOrder = payOrderQueryService.findByOrderNo(param.getOrderNo()) .orElseThrow(() -> new PayFailureException("未查询到支付订单")); } if (Objects.isNull(payOrder)){ - payOrder = payOrderQueryService.findByBusinessNo(param.getBusinessNo()) + payOrder = payOrderQueryService.findByOutOrderNo(param.getBizOrderNo()) .orElseThrow(() -> new PayFailureException("未查询到支付订单")); } return payOrder; @@ -103,18 +112,7 @@ public class RefundAssistService { /** * 检查并处理退款参数 */ - public void checkAndDisposeParam(RefundParam param, PayOrder payOrder){ - // 全额退款和部分退款校验 - if (!param.isRefundAll()) { - if (CollUtil.isEmpty(param.getRefundChannels())) { - throw new ValidationFailedException("退款通道参数不能为空"); - } - } - - // 简单退款校验 - if (payOrder.isCombinationPay()){ - throw new PayFailureException("组合支付不可以使用简单退款方式"); - } + public void checkAndParam(RefundParam param, PayOrder payOrder){ // 状态判断, 支付中/失败/取消等不能进行退款 List tradesStatus = Arrays.asList( @@ -125,22 +123,11 @@ public class RefundAssistService { PayStatusEnum.FAIL.getCode()); if (tradesStatus.contains(payOrder.getStatus())) { PayStatusEnum statusEnum = PayStatusEnum.findByCode(payOrder.getStatus()); - throw new PayFailureException("当前状态["+statusEnum.getName()+"]不允许发起退款操作"); - } - - // 过滤掉金额为空和0的退款参数 - if (!param.isRefundAll()) { - List channelParams = param.getRefundChannels() - .stream() - .filter(r -> Objects.nonNull(r.getAmount())) - .filter(r -> r.getAmount() > 0) - .collect(Collectors.toList()); - param.setRefundChannels(channelParams); + throw new PayFailureException("当前订单状态["+statusEnum.getName()+"]不允许发起退款操作"); } // 退款号唯一校验 - if (StrUtil.isNotBlank(param.getRefundNo()) - && refundOrderManager.existsByRefundNo(param.getRefundNo())){ + if (StrUtil.isNotBlank(param.getBizRefundNo()) && refundOrderManager.existsByRefundNo(param.getBizRefundNo())){ throw new PayFailureException("退款单号已存在"); } } @@ -148,78 +135,38 @@ public class RefundAssistService { /** * 预先创建退款相关订单并保存, 使用新事务, 防止丢单 */ - @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) - public RefundOrder createOrderAndChannel(RefundParam refundParam, PayOrder payOrder, List refundChannelOrders) { - // 此次的总退款金额 - Integer amount = refundParam.getRefundChannels() - .stream() - .map(RefundChannelParam::getAmount) - .reduce(0, Integer::sum); - int refundableBalance = payOrder.getRefundableBalance(); - + @Transactional(rollbackFor = Exception.class) + public RefundOrder createOrder(RefundParam refundParam, PayOrder payOrder) { // 生成退款订单 RefundOrder refundOrder = new RefundOrder() + .setOrderId(payOrder.getId()) .setOrderNo(payOrder.getOrderNo()) - .setStatus(RefundStatusEnum.PROGRESS.getCode()) - .setBusinessNo(payOrder.getBusinessNo()) + .setBizOrderNo(payOrder.getBizOrderNo()) .setRefundNo(OrderNoGenerateUtil.refund()) - .setRefundBusinessNo(refundParam.getRefundNo()) + .setBizRefundNo(refundParam.getBizRefundNo()) + .setStatus(RefundStatusEnum.PROGRESS.getCode()) .setOrderAmount(payOrder.getAmount()) - .setAmount(amount) - .setRefundableBalance(refundableBalance) + .setAmount(refundParam.getAmount()) .setTitle(payOrder.getTitle()) .setReason(refundParam.getReason()); - - // 退款参数中是否存在异步通道 - RefundChannelParam asyncChannel = refundParam.getRefundChannels() - .stream() - .filter(r -> PayChannelEnum.ASYNC_TYPE_CODE.contains(r.getChannel())) - .findFirst() - .orElse(null); - if (Objects.nonNull(asyncChannel)){ - refundOrder.setAsyncChannel(asyncChannel.getChannel()); - refundOrder.setAsyncPay(true); - } - - // 主键使用预先生成的ID, 如果有异步通道, 关联的退款号就是这个ID - refundOrder.setId(IdUtil.getSnowflakeNextId()); - - - RefundOrderExtra refundOrderExtra = this.createRefundOrderExtra(refundParam, refundOrder.getId()); - refundChannelOrders.forEach(r->r.setRefundId(refundOrder.getId())); - refundOrderExtraManager.save(refundOrderExtra); - payRefundChannelOrderManager.saveAll(refundChannelOrders); - return refundOrderManager.save(refundOrder); - } - - /** - * 创建退款扩展订单 - */ - public RefundOrderExtra createRefundOrderExtra(RefundParam refundParam, Long refundOrderId){ - PlatformLocal platform = PaymentContextLocal.get().getPlatformInfo(); - ApiInfoLocal apiInfo = PaymentContextLocal.get().getApiInfo(); + refundOrderManager.save(refundOrder); NoticeLocal notice = PaymentContextLocal.get().getNoticeInfo(); - String reqId = PaymentContextLocal.get() - .getRequestInfo() - .getReqId(); RefundOrderExtra orderExtra = new RefundOrderExtra() .setClientIp(refundParam.getClientIp()) - .setReqId(reqId) .setReqTime(refundParam.getReqTime()) .setAttach(refundParam.getAttach()) - .setReqSign(refundParam.getSign()) - .setReqSignType(platform.getSignType()) - .setNoticeSign(apiInfo.isNoticeSign()) .setNotifyUrl(notice.getNotifyUrl()); - orderExtra.setId(refundOrderId); - return orderExtra; + orderExtra.setId(refundOrder.getId()); + + refundOrderExtraManager.save(orderExtra); + return refundOrder; } /** * 更新退款成功信息 */ @Transactional(rollbackFor = Exception.class) - public void updateOrderAndChannel(RefundOrder refundOrder, List refundChannelOrders){ + public void updateOrder(RefundOrder refundOrder, RefundOrderExtra orderExtra){ RefundLocal asyncRefundInfo = PaymentContextLocal.get().getRefundInfo(); refundOrder.setStatus(asyncRefundInfo.getStatus().getCode()) .setGatewayOrderNo(asyncRefundInfo.getGatewayOrderNo()); @@ -228,7 +175,6 @@ public class RefundAssistService { refundOrder.setRefundTime(LocalDateTime.now()); } refundOrderManager.updateById(refundOrder); - payRefundChannelOrderManager.updateAllById(refundChannelOrders); } /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundService.java index 37155240..2fd35c0a 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/service/RefundService.java @@ -1,6 +1,5 @@ package cn.bootx.platform.daxpay.service.core.payment.refund.service; -import cn.bootx.platform.common.core.annotation.CountTime; import cn.bootx.platform.common.core.exception.DataNotExistException; import cn.bootx.platform.common.core.exception.RepetitiveOperationException; import cn.bootx.platform.common.core.function.CollectorsFunction; @@ -8,31 +7,25 @@ import cn.bootx.platform.common.core.util.ValidationUtil; import cn.bootx.platform.daxpay.code.PayStatusEnum; import cn.bootx.platform.daxpay.code.RefundStatusEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; -import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException; import cn.bootx.platform.daxpay.param.payment.refund.RefundParam; import cn.bootx.platform.daxpay.result.pay.RefundResult; import cn.bootx.platform.daxpay.service.common.context.RefundLocal; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; -import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService; -import cn.bootx.platform.daxpay.service.core.order.refund.dao.RefundChannelOrderManager; import cn.bootx.platform.daxpay.service.core.order.refund.dao.RefundOrderManager; import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder; import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrder; import cn.bootx.platform.daxpay.service.core.payment.notice.service.ClientNoticeService; import cn.bootx.platform.daxpay.service.core.payment.refund.factory.RefundStrategyFactory; import cn.bootx.platform.daxpay.service.func.AbsRefundStrategy; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.collection.CollectionUtil; 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.Propagation; import org.springframework.transaction.annotation.Transactional; import java.util.*; @@ -55,135 +48,67 @@ public class RefundService { private final ClientNoticeService clientNoticeService; - private final PayChannelOrderManager payChannelOrderManager; - private final RefundOrderManager refundOrderManager; - private final RefundChannelOrderManager refundChannelOrderManager; - private final LockTemplate lockTemplate; - /** - * 支付退款 - */ - @CountTime - @Transactional(rollbackFor = Exception.class ) - public RefundResult refund(RefundParam param){ - return this.refundAdapter(param,false); - } - - /** - * 简单退款 - */ - @CountTime - @Transactional(rollbackFor = Exception.class ) - public RefundResult simpleRefund(SimpleRefundParam param){ - ValidationUtil.validateParam(param); - // 构建退款参数 - RefundParam refundParam = new RefundParam(); - BeanUtil.copyProperties(param,refundParam); - if (!param.isRefundAll()){ - RefundChannelParam channelParam = new RefundChannelParam().setAmount(param.getAmount()); - refundParam.setRefundChannels(Collections.singletonList(channelParam)); - } - return this.refundAdapter(refundParam,true); - } - - /** - * 支付退款适配方法, 处理简单退款与普通退款, 全部退款和部分退款的参数转换 - * @param param 退款参数 - * @param simple 是否简单退款 - */ - private RefundResult refundAdapter(RefundParam param, boolean simple){ - // 获取支付订单 - PayOrder payOrder = refundAssistService.getPayOrder(param); - // 第一次检查退款参数, 校验一些特殊情况 - refundAssistService.checkAndDisposeParam(param, payOrder); - - // 组装退款参数, 处理全部退款和简单退款情况 - List payChannelOrders = payChannelOrderManager.findAllByPaymentId(payOrder.getOrderNo()); - // 是否全部退款 - if (param.isRefundAll()){ - // 全部退款根据支付订单的退款信息构造退款参数 - List channelParams = payChannelOrders - .stream() - .map(o -> new RefundChannelParam() - .setChannel(o.getChannel()) - .setAmount(o.getRefundableBalance())) - .collect(Collectors.toList()); - param.setRefundChannels(channelParams); - } else if (simple) { - // 如果不是全部退款且是简单退款的情况下, 设置要退款金额 - String channel = payChannelOrders.get(0).getChannel(); - param.getRefundChannels().get(0).setChannel(channel); - } - - // 参数校验 - ValidationUtil.validateParam(param); - // ----------------------------- 发起退款操作 -------------------------------------------- - // 加锁 - LockInfo lock = lockTemplate.lock("payment:refund:" + payOrder.getId(),10000,200); - if (Objects.isNull(lock)){ - throw new RepetitiveOperationException("退款处理中,请勿重复操作"); - } - try { - // 退款上下文初始化 - refundAssistService.initRefundContext(param); - // 分支付通道进行退款 - return this.refundByChannel(param,payOrder,payChannelOrders); - } finally { - lockTemplate.releaseLock(lock); - } - } - /** * 分支付通道进行退款 * 1. 创建退款订单和通道订单并保存(单独事务) * 2. 调用API发起退款(异步退款) * 3. 根据API返回信息更新退款订单信息 */ - public RefundResult refundByChannel(RefundParam refundParam, PayOrder payOrder, List payChannelOrders){ - // 1.1 基础数据准备 - Map orderChannelMap = payChannelOrders.stream() - .collect(Collectors.toMap(PayChannelOrder::getChannel, Function.identity(), CollectorsFunction::retainLatest)); - List refundChannels = refundParam.getRefundChannels(); - - // 1.2获取退款参数方式,通过工厂生成对应的策略组 - List payRefundStrategies = RefundStrategyFactory.createAsyncLast(refundChannels); - if (CollectionUtil.isEmpty(payRefundStrategies)) { - throw new PayUnsupportedMethodException(); + public RefundResult refund(RefundParam param){ + // 参数校验 + ValidationUtil.validateParam(param); + // 加锁 + LockInfo lock = lockTemplate.lock("payment:refund:" + param.getBizRefundNo(),10000,200); + if (Objects.isNull(lock)){ + throw new RepetitiveOperationException("退款处理中,请勿重复操作"); } - // 1.3初始化退款策略的参数 - for (AbsRefundStrategy refundStrategy : payRefundStrategies) { - PayChannelOrder payChannelOrder = orderChannelMap.get(refundStrategy.getChannel().getCode()); - if (Objects.isNull(payChannelOrder)){ - throw new PayFailureException("[数据异常]进行退款的通道没有对应的支付单, 无法退款"); + try { + // 判断是否是首次发起退款 + Optional refund = refundOrderManager.findByBizRefundNo(param.getBizRefundNo()); + if (refund.isPresent()){ + return this.repeatRefund(param,refund.get()); + } else { + return this.firstRefund(param); } - refundStrategy.initRefundParam(payOrder, payChannelOrder); + } finally { + lockTemplate.releaseLock(lock); } + } - // 2.1 退款前校验操作 - payRefundStrategies.forEach(AbsRefundStrategy::doBeforeCheckHandler); + /** + * 首次退款 + */ + public RefundResult firstRefund(RefundParam param){ - // 2.2 生成通道退款订单对象 - payRefundStrategies.forEach(AbsRefundStrategy::generateChannelOrder); + // 获取支付订单 + PayOrder payOrder = refundAssistService.getPayOrder(param); + // 检查退款参数 + refundAssistService.checkAndParam(param, payOrder); - // 2.3 退款操作的预处理, 使用独立的新事物进行发起, 返回创建成功的退款订单, 成功后才可以进行下一阶段的操作 - RefundOrder refundOrder = SpringUtil.getBean(this.getClass()).preRefundMethod(refundParam, payOrder, payRefundStrategies); + // ----------------------------- 发起退款操作 -------------------------------------------- - // 2.4 设置退款订单对象 - payRefundStrategies.forEach(r->r.setRefundOrder(refundOrder)); + // 通过退款参数获取退款策略 + AbsRefundStrategy refundStrategy = RefundStrategyFactory.create(payOrder.getChannel()); + // 设置支付订单数据 + refundStrategy.setPayOrder(payOrder); + // 进行退款前预处理 + refundStrategy.doBeforeRefundHandler(); + + // 退款操作的预处理, 使用独立的新事物进行发起, 返回创建成功的退款订单, 成功后才可以进行下一阶段的操作 + RefundOrder refundOrder = SpringUtil.getBean(this.getClass()).preRefundMethod(refundParam, payOrder, refundStrategy); try { - // 3.1 退款前准备操作 - payRefundStrategies.forEach(AbsRefundStrategy::doBeforeRefundHandler); // 3.2 执行退款策略 - payRefundStrategies.forEach(AbsRefundStrategy::doRefundHandler); + refundStrategy.forEach(AbsRefundStrategy::doRefundHandler); // 3.3 执行退款发起成功后操作 - payRefundStrategies.forEach(AbsRefundStrategy::doSuccessHandler); + refundStrategy.forEach(AbsRefundStrategy::doSuccessHandler); // 4.进行成功处理, 分别处理退款订单, 通道退款订单, 支付订单 - List refundChannelOrders = payRefundStrategies.stream() + List refundChannelOrders = refundStrategy.stream() .map(AbsRefundStrategy::getRefundChannelOrder) .collect(Collectors.toList()); this.successHandler(refundOrder, refundChannelOrders, payOrder); @@ -200,75 +125,46 @@ public class RefundService { } /** - * 退款一阶段: 进行支付订单和支付通道订单的预扣, 预创建退款订单并保存, 使用独立的新事物进行发起 + * 退款一阶段: 进行支付订单退款金额的预扣, 创建退款订单并保存 */ - @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class ) - public RefundOrder preRefundMethod(RefundParam refundParam, PayOrder payOrder, List payRefundStrategies) { + @Transactional(rollbackFor = Exception.class ) + public RefundOrder preRefundMethod(RefundParam refundParam, PayOrder payOrder) { // --------------------------- 支付订单 ------------------------------------- // 预扣支付相关订单要退款的金额并进行更新 - payRefundStrategies.forEach(AbsRefundStrategy::doPreDeductOrderHandler); - List channelOrders = payRefundStrategies.stream() - .map(AbsRefundStrategy::getPayChannelOrder) - .collect(Collectors.toList()); - payChannelOrderManager.updateAllById(channelOrders); - // 此次的总退款金额 - Integer amount = refundParam.getRefundChannels() - .stream() - .map(RefundChannelParam::getAmount) - .reduce(0, Integer::sum); - int orderRefundableBalance = payOrder.getRefundableBalance() - amount; + int orderRefundableBalance = payOrder.getRefundableBalance() - refundParam.getAmount(); payOrder.setRefundableBalance(orderRefundableBalance) .setStatus(PayStatusEnum.REFUNDING.getCode()); payOrderService.updateById(payOrder); - // ----------------------- 退款订单 ------------------------- - List refundChannelOrders = payRefundStrategies.stream() - .map(AbsRefundStrategy::getRefundChannelOrder) - .collect(Collectors.toList()); - return refundAssistService.createOrderAndChannel(refundParam, payOrder,refundChannelOrders); + // ----------------------- 退款订单创建 ------------------------- + return refundAssistService.createOrder(refundParam, payOrder); } /** - * 重新发退款处理 + * 重新发起退款处理 * 1. 查出相关退款订单 * 2. 构建退款策略, 发起退款 */ - public void resetRefund(Long id){ - // 查询 - RefundOrder refundOrder = refundOrderManager.findById(id) - .orElseThrow(() -> new DataNotExistException("未查找到退款订单")); - + public RefundResult repeatRefund(RefundParam param, RefundOrder refundOrder){ // 退款失败才可以重新发起退款, 重新发起退款 if (!Objects.equals(refundOrder.getStatus(), RefundStatusEnum.FAIL.getCode())){ throw new PayFailureException("退款状态不正确, 无法重新发起退款"); } - // 构建策略 - List refundChannels = refundChannelOrderManager - .findAllByRefundId(refundOrder.getId()); - PayOrder payOrder = payOrderService.findById(refundOrder.getId()) - .orElseThrow(() -> new DataNotExistException("未查找到支付订单")); - List payChannelOrders = payChannelOrderManager.findAllByPaymentId(payOrder.getOrderNo()); - Map orderChannelMap = payChannelOrders.stream() - .collect(Collectors.toMap(PayChannelOrder::getChannel, Function.identity(), CollectorsFunction::retainLatest)); - - List strategies = RefundStrategyFactory.createAsyncFrontByOrder(refundChannels); - for (AbsRefundStrategy strategy : strategies) { - strategy.initRefundParam(payOrder, orderChannelMap.get(strategy.getChannel().getCode())); - } + AbsRefundStrategy refundStrategy = RefundStrategyFactory.create(refundOrder.getRefundNo()); // 设置退款订单对象 - strategies.forEach(r->r.setRefundOrder(refundOrder)); + refundStrategy.setRefundOrder(refundOrder); try { // 3.1 退款前准备操作 - strategies.forEach(AbsRefundStrategy::doBeforeRefundHandler); + refundStrategy.forEach(AbsRefundStrategy::doBeforeRefundHandler); // 3.2 执行退款策略 - strategies.forEach(AbsRefundStrategy::doRefundHandler); + refundStrategy.forEach(AbsRefundStrategy::doRefundHandler); // 3.3 执行退款发起成功后操作 - strategies.forEach(AbsRefundStrategy::doSuccessHandler); + refundStrategy.forEach(AbsRefundStrategy::doSuccessHandler); // 4.进行成功处理, 分别处理退款订单, 通道退款订单, 支付订单 - List refundChannelOrders = strategies.stream() + List refundChannelOrders = refundStrategy.stream() .map(AbsRefundStrategy::getRefundChannelOrder) .collect(Collectors.toList()); this.successHandler(refundOrder, refundChannelOrders, payOrder); @@ -299,7 +195,7 @@ public class RefundService { payOrderService.updateById(payOrder); // 更新退款订单和相关通道订单 - refundAssistService.updateOrderAndChannel(refundOrder,refundChannelOrders); + refundAssistService.updateOrder(refundOrder,refundChannelOrders); // 发送通知 List list = Arrays.asList(RefundStatusEnum.SUCCESS.getCode(), RefundStatusEnum.CLOSE.getCode(), RefundStatusEnum.FAIL.getCode()); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/AliRefundStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/AliRefundStrategy.java index bac7936c..bfcb5ab3 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/AliRefundStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/AliRefundStrategy.java @@ -5,9 +5,7 @@ import cn.bootx.platform.daxpay.code.RefundStatusEnum; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig; import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayConfigService; -import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayRecordService; import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayRefundService; -import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService; import cn.bootx.platform.daxpay.service.func.AbsRefundStrategy; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Scope; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/UnionRefundStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/UnionRefundStrategy.java index f2b042c5..bb713d4a 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/UnionRefundStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/UnionRefundStrategy.java @@ -5,9 +5,7 @@ import cn.bootx.platform.daxpay.code.RefundStatusEnum; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.union.entity.UnionPayConfig; import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayConfigService; -import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayRecordService; import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayRefundService; -import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService; import cn.bootx.platform.daxpay.service.func.AbsRefundStrategy; import cn.bootx.platform.daxpay.service.sdk.union.api.UnionPayKit; import lombok.RequiredArgsConstructor; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/WalletRefundStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/WalletRefundStrategy.java index caab84e6..a47daded 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/WalletRefundStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/WalletRefundStrategy.java @@ -7,7 +7,6 @@ import cn.bootx.platform.daxpay.param.channel.WalletPayParam; import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletPayService; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletQueryService; -import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletRecordService; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import cn.bootx.platform.daxpay.service.func.AbsRefundStrategy; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/WeChatRefundStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/WeChatRefundStrategy.java index bbcd4d7d..2f5ab37c 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/WeChatRefundStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/refund/strategy/WeChatRefundStrategy.java @@ -5,9 +5,7 @@ import cn.bootx.platform.daxpay.code.RefundStatusEnum; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig; import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayConfigService; -import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayRecordService; import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WechatPayRefundService; -import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService; import cn.bootx.platform.daxpay.service.func.AbsRefundStrategy; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Scope; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/AliPayRepairStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/AliPayRepairStrategy.java index dae73fba..fc20e896 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/AliPayRepairStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/AliPayRepairStrategy.java @@ -6,7 +6,6 @@ import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig; import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayCloseService; import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayConfigService; -import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayRecordService; import cn.bootx.platform.daxpay.service.func.AbsPayRepairStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/UnionPayRepairStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/UnionPayRepairStrategy.java index c1cdf87f..7f5736d3 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/UnionPayRepairStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/UnionPayRepairStrategy.java @@ -3,7 +3,6 @@ package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.pay; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.code.PayStatusEnum; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; -import cn.bootx.platform.daxpay.service.core.channel.union.service.UnionPayRecordService; import cn.bootx.platform.daxpay.service.func.AbsPayRepairStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/WalletPayRepairStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/WalletPayRepairStrategy.java index a1ab135a..de18a819 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/WalletPayRepairStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/WalletPayRepairStrategy.java @@ -6,7 +6,6 @@ import cn.bootx.platform.daxpay.param.channel.WalletPayParam; import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletPayService; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletQueryService; -import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletRecordService; import cn.bootx.platform.daxpay.service.func.AbsPayRepairStrategy; import cn.hutool.json.JSONUtil; import lombok.RequiredArgsConstructor; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/WeChatPayRepairStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/WeChatPayRepairStrategy.java index dc190bde..578f7426 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/WeChatPayRepairStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/pay/WeChatPayRepairStrategy.java @@ -6,7 +6,6 @@ import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig; import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayCloseService; import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayConfigService; -import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayRecordService; import cn.bootx.platform.daxpay.service.func.AbsPayRepairStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/AliRefundRepairStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/AliRefundRepairStrategy.java index 1e798a82..cfb7fb71 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/AliRefundRepairStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/AliRefundRepairStrategy.java @@ -2,7 +2,6 @@ package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.refund; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; -import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayRecordService; import cn.bootx.platform.daxpay.service.func.AbsRefundRepairStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/WalletRefundRepairStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/WalletRefundRepairStrategy.java index d2e45f8f..b8970c7d 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/WalletRefundRepairStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/WalletRefundRepairStrategy.java @@ -7,7 +7,6 @@ import cn.bootx.platform.daxpay.param.channel.WalletPayParam; import cn.bootx.platform.daxpay.service.core.channel.wallet.entity.Wallet; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletPayService; import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletQueryService; -import cn.bootx.platform.daxpay.service.core.channel.wallet.service.WalletRecordService; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder; import cn.bootx.platform.daxpay.service.func.AbsRefundRepairStrategy; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/WeChatRefundRepairStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/WeChatRefundRepairStrategy.java index 87030e4b..69f3f532 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/WeChatRefundRepairStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/repair/strategy/refund/WeChatRefundRepairStrategy.java @@ -2,7 +2,6 @@ package cn.bootx.platform.daxpay.service.core.payment.repair.strategy.refund; import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; -import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayRecordService; import cn.bootx.platform.daxpay.service.func.AbsRefundRepairStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/PaySyncService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/PaySyncService.java index f67d3333..377563ab 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/PaySyncService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/sync/service/PaySyncService.java @@ -69,7 +69,7 @@ public class PaySyncService { .orElseThrow(() -> new PayFailureException("未查询到支付订单")); } if (Objects.isNull(payOrder)){ - payOrder = payOrderQueryService.findByBusinessNo(param.getBusinessNo()) + payOrder = payOrderQueryService.findByOutOrderNo(param.getBusinessNo()) .orElseThrow(() -> new PayFailureException("未查询到支付订单")); } // 如果不是异步支付, 直接返回返回 diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/convert/TradeFlowRecordConvert.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/convert/TradeFlowRecordConvert.java new file mode 100644 index 00000000..1bdde833 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/convert/TradeFlowRecordConvert.java @@ -0,0 +1,12 @@ +package cn.bootx.platform.daxpay.service.core.record.flow.convert; + +import org.mapstruct.Mapper; + +/** + * + * @author xxm + * @since 2024/4/21 + */ +@Mapper +public interface TradeFlowRecordConvert { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/dao/TradeFlowRecordManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/dao/TradeFlowRecordManager.java new file mode 100644 index 00000000..d5d9d9db --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/dao/TradeFlowRecordManager.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.core.record.flow.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.record.flow.entity.TradeFlowRecord; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +/** + * + * @author xxm + * @since 2024/4/21 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class TradeFlowRecordManager extends BaseManager { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/dao/TradeFlowRecordMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/dao/TradeFlowRecordMapper.java new file mode 100644 index 00000000..20afe45f --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/dao/TradeFlowRecordMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.record.flow.dao; + +import cn.bootx.platform.daxpay.service.core.record.flow.entity.TradeFlowRecord; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/4/21 + */ +@Mapper +public interface TradeFlowRecordMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/entity/TradeFlowRecord.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/entity/TradeFlowRecord.java new file mode 100644 index 00000000..738476bd --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/entity/TradeFlowRecord.java @@ -0,0 +1,61 @@ +package cn.bootx.platform.daxpay.service.core.record.flow.entity; + +import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.platform.daxpay.code.PayChannelEnum; +import cn.bootx.platform.daxpay.service.code.TradeFlowRecordTypeEnum; +import cn.bootx.table.modify.annotation.DbColumn; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.time.LocalDateTime; + +/** + * 资金流水记录 + * @author xxm + * @since 2024/4/21 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "资金流水记录") +public class TradeFlowRecord extends MpCreateEntity { + /** 支付订单标题 */ + @DbColumn(comment = "标题") + private String title; + + /** 金额 */ + @DbColumn(comment = "金额") + private Integer amount; + + /** + * 业务类型 + * @see TradeFlowRecordTypeEnum + */ + @DbColumn(comment = "业务类型") + private String type; + + /** + * 支付通道 + * @see PayChannelEnum + */ + @DbColumn(comment = "支付通道") + private String channel; + + /** 本地交易号 */ + @DbColumn(comment = "本地订单号") + private String identifyNo; + + /** 商户交易号 */ + @DbColumn(comment = "商户交易号") + private String bizIdentifyNo; + + /** 三方系统交易号 */ + @DbColumn(comment = "三方系统交易号") + private String outIdentifyNo; + + /** 网关完成时间 */ + @DbColumn(comment = "网关完成时间") + private LocalDateTime gatewayTime; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/service/TradeFlowRecordService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/service/TradeFlowRecordService.java new file mode 100644 index 00000000..8ff98a57 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/flow/service/TradeFlowRecordService.java @@ -0,0 +1,16 @@ +package cn.bootx.platform.daxpay.service.core.record.flow.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 交易流水记录服务类 + * @author xxm + * @since 2024/4/21 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class TradeFlowRecordService { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsCallbackStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsCallbackStrategy.java index 1411f9a3..a80d0fd4 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsCallbackStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsCallbackStrategy.java @@ -108,7 +108,7 @@ public abstract class AbsCallbackStrategy implements PayStrategy { .setChannel(this.getChannel().getCode()) .setNotifyInfo(JSONUtil.toJsonStr(callbackInfo.getCallbackParam())) .setOrderId(callbackInfo.getOrderId()) - .setGatewayOrderNo(callbackInfo.getGatewayOrderNo()) + .setGatewayOrderNo(callbackInfo.getOutOrderNo()) .setCallbackType(callbackInfo.getCallbackType().getCode()) .setRepairOrderNo(callbackInfo.getPayRepairNo()) .setStatus(callbackInfo.getCallbackStatus().getCode()) diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsPayStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsPayStrategy.java index e4b572e9..02d553d3 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsPayStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsPayStrategy.java @@ -1,15 +1,10 @@ package cn.bootx.platform.daxpay.service.func; -import cn.bootx.platform.daxpay.code.PayStatusEnum; import cn.bootx.platform.daxpay.param.payment.pay.PayParam; -import cn.bootx.platform.daxpay.service.core.order.pay.builder.PayBuilder; -import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder; import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; import lombok.Getter; import lombok.Setter; -import java.time.LocalDateTime; - /** * 抽象支付策略基类 同步支付 异步支付 错误处理 关闭支付 撤销支付 支付网关同步 退款 * @@ -23,15 +18,9 @@ public abstract class AbsPayStrategy implements PayStrategy{ /** 支付订单 */ private PayOrder order = null; - /** 通道支付订单, 异步支付通道单独处理通道支付订单 */ - private PayChannelOrder channelOrder = null; - /** 支付参数 */ private PayParam payParam = null; - /** 支付方式参数 支付参数中的与这个不一致, 以这个为准 */ - private PayChannelParam payChannelParam = null; - /** * 初始化支付的参数支付上下文 @@ -48,26 +37,9 @@ public abstract class AbsPayStrategy implements PayStrategy{ public void doBeforePayHandler() { } - /** - * 生成通道支付单, 如果不需要可以进行覆盖 - * 异步支付通道都进行了重新, 通道支付单由自己控制 - */ - public void generateChannelOrder() { - PayChannelOrder payChannelOrder = PayBuilder.buildPayChannelOrder(this.getPayChannelParam()); - payChannelOrder.setPaymentId(this.getOrder().getOrderNo()); - this.channelOrder = payChannelOrder; - } - /** * 支付操作 */ public abstract void doPayHandler(); - /** - * 支付调起成功的处理方式 - */ - public void doSuccessHandler() { - this.channelOrder.setStatus(PayStatusEnum.SUCCESS.getCode()).setPayTime(LocalDateTime.now()); - } - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsRefundStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsRefundStrategy.java index 126a7853..4cab87d4 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsRefundStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsRefundStrategy.java @@ -25,46 +25,9 @@ public abstract class AbsRefundStrategy implements PayStrategy{ /** 支付订单 */ private PayOrder payOrder = null; - /** 退款订单 已经持久化, 后续需要更新 */ + /** 退款订单 */ private RefundOrder refundOrder = null; - /** 当前通道的订单 */ - private PayChannelOrder payChannelOrder = null; - - /** 当前通道的退款参数 退款参数中的与这个不一致, 以这个为准 */ - private RefundChannelParam refundChannelParam = null; - - /** 当前通道的退款订单 未持久化, 需要后续更新 */ - private RefundChannelOrder refundChannelOrder; - - /** - * 初始化参数 - */ - public void initRefundParam(PayOrder payOrder, PayChannelOrder payChannelOrder) { - this.payOrder = payOrder; - this.payChannelOrder = payChannelOrder; - } - - - /** - * 退款前预扣通道支付订单的金额 - */ - public void doPreDeductOrderHandler(){ - PayChannelOrder payChannelOrder = this.getPayChannelOrder(); - int refundableBalance = payChannelOrder.getRefundableBalance() - this.getRefundChannelParam().getAmount(); - payChannelOrder.setRefundableBalance(refundableBalance) - .setStatus(PayStatusEnum.REFUNDING.getCode()); - } - - /** - * 退款前对退款数据校验 - */ - public void doBeforeCheckHandler() { - // 退款金额不可以大于可退余额 - if (this.getRefundChannelParam().getAmount() > this.getPayChannelOrder().getRefundableBalance()) { - throw new PayFailureException("["+ this.getChannel().getName() +"]退款金额大于可退余额"); - } - } /** * 退款前对处理, 主要进行配置的加载和检查 @@ -96,19 +59,4 @@ public abstract class AbsRefundStrategy implements PayStrategy{ .setStatus(status.getCode()); } - /** - * 生成通道退款订单对象 - */ - public void generateChannelOrder() { - int refundableAmount = this.getPayChannelOrder().getRefundableBalance() - this.getRefundChannelParam().getAmount(); - - this.refundChannelOrder = new RefundChannelOrder() - .setPayChannelId(this.getPayChannelOrder().getId()) - .setAsync(this.getPayChannelOrder().isAsync()) - .setChannel(this.getPayChannelOrder().getChannel()) - .setOrderAmount(this.getPayChannelOrder().getAmount()) - .setRefundableAmount(refundableAmount) - .setAmount(this.getRefundChannelParam().getAmount()); - } - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/order/PayOrderRefundParam.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/order/PayOrderRefundParam.java index b99fc7a1..226b87ce 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/order/PayOrderRefundParam.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/order/PayOrderRefundParam.java @@ -1,11 +1,10 @@ package cn.bootx.platform.daxpay.service.param.order; +import cn.bootx.platform.daxpay.code.PayChannelEnum; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.experimental.Accessors; -import java.util.List; - /** * 支付订单退款发起参数 * @author xxm @@ -16,15 +15,22 @@ import java.util.List; @Schema(title = "支付订单退款发起参数") public class PayOrderRefundParam { - /** 支付id */ - @Schema(description = "支付id") - private Long paymentId; + /** 支付订单号 */ + @Schema(description = "支付订单号") + private Long orderNo; + + /** + * 支付通道 + * @see PayChannelEnum#getCode() + */ + private String channel; + + /** + * 退款金额 + */ + private Integer amount; /** 原因 */ @Schema(description = "原因") private String reason; - - /** 退款明细 */ - @Schema(description = "退款明细") - private List refundChannels; }