From 6825ce4cfe5cf2cb0467b374a1a65c609d3252b7 Mon Sep 17 00:00:00 2001 From: xxm1995 Date: Sun, 7 Apr 2024 19:04:13 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E5=88=86=E8=B4=A6=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _doc/Task.md | 5 +- .../platform/daxpay/code/PaymentApiCode.java | 4 + .../pay/allocation/AllocationFinishParam.java | 23 ++++ .../AllocationStartParam.java} | 22 ++-- .../allocation/QueryAllocationOrderParam.java | 23 ++++ .../result/allocation/AllocationResult.java | 28 +++++ .../daxpay/result/pay/RefundSyncResult.java | 7 +- .../gateway/controller/TestController.java | 13 --- .../gateway/controller/UniPayController.java | 26 ++++- .../service/code/AllocationStatusEnum.java | 29 +++++ .../service/AliPayAllocationService.java | 48 ++++---- .../service/WeChatPayAllocationService.java | 106 +++++++++++++++++ .../allocation/convert/AllocationConvert.java | 24 ++++ .../dao/AllocationOrderDetailManager.java | 18 +++ .../dao/AllocationOrderDetailMapper.java | 14 +++ .../dao/AllocationOrderManager.java | 27 +++++ .../allocation/dao/AllocationOrderMapper.java | 14 +++ .../allocation/entity/AllocationOrder.java | 74 +++++++++++- .../entity/AllocationOrderDetail.java | 50 +++++++- .../allocation/entity/OrderAndDetail.java | 21 ++++ .../service/AllocationOrderService.java | 96 ++++++++++++++++ .../dao/AllocationGroupManager.java | 19 +++ .../allocation/entity/AllocationGroup.java | 3 + .../allocation/factory/AllocationFactory.java | 37 ++++++ .../service/AllocationGroupService.java | 13 +++ .../service/AllocationOrderSyncService.java | 16 +++ .../allocation/service/AllocationService.java | 108 ++++++++++++++++-- .../allocation/AliPayAllocationStrategy.java | 55 ++++++++- .../WeChatPayAllocationStrategy.java | 53 ++++++++- .../dto/allocation/AllocationGroupDto.java | 4 + .../allocation/AllocationOrderDetailDto.java | 19 +++ .../order/allocation/AllocationOrderDto.java | 21 ++++ .../func/AbsAllocationReceiverStrategy.java | 7 +- .../service/func/AbsAllocationStrategy.java | 47 ++++++++ .../service/func/AbsRefundRepairStrategy.java | 2 +- .../service/func/AbsRefundStrategy.java | 2 +- .../param/order/AllocationOrderQuery.java | 18 +++ 37 files changed, 1027 insertions(+), 69 deletions(-) create mode 100644 daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/AllocationFinishParam.java rename daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/{AllocationParam.java => allocation/AllocationStartParam.java} (52%) create mode 100644 daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/QueryAllocationOrderParam.java create mode 100644 daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/allocation/AllocationResult.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AllocationStatusEnum.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayAllocationService.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/convert/AllocationConvert.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderDetailManager.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderDetailMapper.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderManager.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderMapper.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/OrderAndDetail.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/service/AllocationOrderService.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/factory/AllocationFactory.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationOrderSyncService.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/allocation/AllocationOrderDetailDto.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/allocation/AllocationOrderDto.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsAllocationStrategy.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/order/AllocationOrderQuery.java diff --git a/_doc/Task.md b/_doc/Task.md index 42649bddd..b0c09be35 100644 --- a/_doc/Task.md +++ b/_doc/Task.md @@ -8,14 +8,13 @@ - [x] 管理 - [x] 绑定 - [ ] 分账订单管理 - - [ ] 订单创建 + - [x] 订单创建 - [ ] 发起分账 - - [ ] 订单完结 + - [ ] 分账完结 - [ ] 分账处理 - [ ] 发起分账 - [ ] 分账回调处理 - [ ] 分账情况查询, 分账结果/剩余可分账金额 - - [ ] - [x] 修复创建支付订单报错时, 订单保存数据不完整 2.0.6: 分账完善 diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PaymentApiCode.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PaymentApiCode.java index d4d090e50..dea8bf024 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PaymentApiCode.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PaymentApiCode.java @@ -17,6 +17,10 @@ public interface PaymentApiCode { String CLOSE = "close"; + String ALLOCATION = "allocation"; + + String ALLOCATION_FINISH = "allocationFinish"; + String SYNC_PAY = "syncPay"; String SYNC_REFUND = "syncRefund"; diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/AllocationFinishParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/AllocationFinishParam.java new file mode 100644 index 000000000..c6c224bb5 --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/AllocationFinishParam.java @@ -0,0 +1,23 @@ +package cn.bootx.platform.daxpay.param.pay.allocation; + +import cn.bootx.platform.daxpay.param.PaymentCommonParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 分账完结参数 + * @author xxm + * @since 2024/4/7 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Schema(title = "分账请求参数") +public class AllocationFinishParam extends PaymentCommonParam { + + @Schema(description = "分账订单ID") + private Long orderId; + + @Schema(description = "分账单号") + private String allocationNo; +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/AllocationParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/AllocationStartParam.java similarity index 52% rename from daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/AllocationParam.java rename to daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/AllocationStartParam.java index a0c40cc4e..61397a186 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/AllocationParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/AllocationStartParam.java @@ -1,23 +1,19 @@ -package cn.bootx.platform.daxpay.param.pay; +package cn.bootx.platform.daxpay.param.pay.allocation; import cn.bootx.platform.daxpay.param.PaymentCommonParam; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.experimental.Accessors; - -import javax.validation.constraints.NotNull; /** - * 分账请求参数 + * 开始分账请求参数 * @author xxm * @since 2024/4/6 */ @EqualsAndHashCode(callSuper = true) @Data -@Accessors(chain = true) -@Schema(title = "分账请求参数") -public class AllocationParam extends PaymentCommonParam { +@Schema(title = "开始分账请求参数") +public class AllocationStartParam extends PaymentCommonParam { @Schema(description = "支付单ID") private Long paymentId; @@ -25,8 +21,16 @@ public class AllocationParam extends PaymentCommonParam { @Schema(description = "业务号") private String businessNo; + @Schema(description = "分账单号(保证唯一)") + private String allocationNo; + + @Schema(description = "分账描述") + private String description; + + /** + * 不传输分账组使用默认分账组进行分账 + */ @Schema(description = "分账组ID") - @NotNull(message = "分账组ID不可为空") private Long allocationGroupId; } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/QueryAllocationOrderParam.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/QueryAllocationOrderParam.java new file mode 100644 index 000000000..911dc63cc --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/param/pay/allocation/QueryAllocationOrderParam.java @@ -0,0 +1,23 @@ +package cn.bootx.platform.daxpay.param.pay.allocation; + +import cn.bootx.platform.daxpay.param.PaymentCommonParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 分账订单查询参数 + * @author xxm + * @since 2024/4/7 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Schema(title = "支付订单查询参数") +public class QueryAllocationOrderParam extends PaymentCommonParam { + + @Schema(description = "分账订单ID") + private Long orderId; + + @Schema(description = "分账单号") + private String allocationNo; +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/allocation/AllocationResult.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/allocation/AllocationResult.java new file mode 100644 index 000000000..beeb11d00 --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/allocation/AllocationResult.java @@ -0,0 +1,28 @@ +package cn.bootx.platform.daxpay.result.allocation; + +import cn.bootx.platform.daxpay.result.CommonResult; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 分账请求结果 + * @author xxm + * @since 2024/4/7 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "分账请求结果") +public class AllocationResult extends CommonResult { + + @Schema(description = "分账订单ID") + private Long orderId; + + @Schema(description = "分账订单号, 如果请求时未传, 则默认使用分账订单ID") + private String allocationNo; + + @Schema(description = "分账状态") + private String status; +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/pay/RefundSyncResult.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/pay/RefundSyncResult.java index 47d89cc00..dbafb5c86 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/pay/RefundSyncResult.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/result/pay/RefundSyncResult.java @@ -1,7 +1,9 @@ package cn.bootx.platform.daxpay.result.pay; +import cn.bootx.platform.daxpay.result.CommonResult; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; /** @@ -9,12 +11,11 @@ import lombok.experimental.Accessors; * @author xxm * @since 2024/1/29 */ +@EqualsAndHashCode(callSuper = true) @Data @Accessors(chain = true) @Schema(title = "退款同步结果") -public class RefundSyncResult { - - +public class RefundSyncResult extends CommonResult { @Schema(description = "是否进行了修复") private boolean repair; diff --git a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java index 32210169f..1dab3f8d1 100644 --- a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java +++ b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java @@ -1,10 +1,8 @@ package cn.bootx.platform.daxpay.gateway.controller; -import cn.bootx.platform.common.core.annotation.IgnoreAuth; import cn.bootx.platform.common.core.exception.BizException; import cn.bootx.platform.common.core.rest.Res; import cn.bootx.platform.common.core.rest.ResResult; -import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayAllocationService; import cn.hutool.core.thread.ThreadUtil; import com.baomidou.lock.LockInfo; import com.baomidou.lock.LockTemplate; @@ -28,7 +26,6 @@ import java.util.Objects; @RequiredArgsConstructor public class TestController { private final LockTemplate lockTemplate; - private final AliPayAllocationService allocationService; @Operation(summary = "锁测试1") @GetMapping("/lock1") @@ -52,14 +49,4 @@ public class TestController { return Res.ok(name); } - - @IgnoreAuth - @Operation(summary = "支付宝分账") - @GetMapping("/ali") - public ResResult ali(){ - allocationService.allocation(null,null); - return Res.ok(); - } - - } 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 ae076ae68..a6ecb9df9 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 @@ -4,16 +4,20 @@ import cn.bootx.platform.common.core.annotation.CountTime; import cn.bootx.platform.common.core.annotation.IgnoreAuth; import cn.bootx.platform.daxpay.code.PaymentApiCode; import cn.bootx.platform.daxpay.param.pay.*; +import cn.bootx.platform.daxpay.param.pay.allocation.AllocationFinishParam; +import cn.bootx.platform.daxpay.param.pay.allocation.AllocationStartParam; import cn.bootx.platform.daxpay.result.DaxResult; +import cn.bootx.platform.daxpay.result.allocation.AllocationResult; import cn.bootx.platform.daxpay.result.pay.PayResult; import cn.bootx.platform.daxpay.result.pay.RefundResult; import cn.bootx.platform.daxpay.result.pay.SyncResult; import cn.bootx.platform.daxpay.service.annotation.PaymentApi; +import cn.bootx.platform.daxpay.service.core.payment.allocation.service.AllocationService; import cn.bootx.platform.daxpay.service.core.payment.close.service.PayCloseService; import cn.bootx.platform.daxpay.service.core.payment.pay.service.PayService; import cn.bootx.platform.daxpay.service.core.payment.refund.service.RefundService; -import cn.bootx.platform.daxpay.service.core.payment.sync.service.RefundSyncService; import cn.bootx.platform.daxpay.service.core.payment.sync.service.PaySyncService; +import cn.bootx.platform.daxpay.service.core.payment.sync.service.RefundSyncService; import cn.bootx.platform.daxpay.util.DaxRes; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -39,6 +43,7 @@ public class UniPayController { private final PaySyncService paySyncService; private final PayCloseService payCloseService; private final RefundSyncService refundSyncService; + private final AllocationService allocationService; @CountTime @@ -98,4 +103,23 @@ public class UniPayController { return DaxRes.ok(refundSyncService.sync(param)); } + @CountTime + @PaymentApi(PaymentApiCode.ALLOCATION) + @Operation(summary = "开启分账接口") + @PostMapping("/allocation") + public DaxResult allocation(@RequestBody AllocationStartParam param){ + return DaxRes.ok(allocationService.allocation(param)); + } + + @CountTime + @PaymentApi(PaymentApiCode.ALLOCATION_FINISH) + @Operation(summary = "分账完结接口") + @PostMapping("/allocationFinish") + public DaxResult allocationFinish(@RequestBody AllocationFinishParam param){ + allocationService.finish(param); + return DaxRes.ok(); + } + + + } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AllocationStatusEnum.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AllocationStatusEnum.java new file mode 100644 index 000000000..d35d00539 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/AllocationStatusEnum.java @@ -0,0 +1,29 @@ +package cn.bootx.platform.daxpay.service.code; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 分账状态枚举 + * @author xxm + * @since 2024/4/7 + */ +@Getter +@AllArgsConstructor +public enum AllocationStatusEnum { + + // 待分账 + WAITING("waiting", "待分账"), + PARTIAL_PROCESSING("partial_processing", "分账处理中"), + PARTIAL_SUCCESS("partial_success", "部分分账完成"), + FINISH_PROCESSING("finish_processing", "分账完结处理中"), + FINISH_SUCCESS("finish_success", "分账完成"), + PARTIAL_FAILED("partial_failed", "部分分账完成"), + FINISH_FAILED("finish_failed", "分账失败"), + CLOSED("closed", "分账关闭"), + UNKNOWN("unknown", "分账状态未知"); + + final String code; + final String name; + +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayAllocationService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayAllocationService.java index c67f84f39..2786895f6 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayAllocationService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayAllocationService.java @@ -2,9 +2,9 @@ package cn.bootx.platform.daxpay.service.core.channel.alipay.service; import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrder; import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrderDetail; -import cn.hutool.core.util.IdUtil; import com.alipay.api.domain.AlipayTradeOrderSettleModel; import com.alipay.api.domain.OpenApiRoyaltyDetailInfoPojo; +import com.alipay.api.domain.SettleExtendParams; import com.alipay.api.response.AlipayTradeOrderSettleResponse; import com.ijpay.alipay.AliPayApi; import lombok.RequiredArgsConstructor; @@ -12,8 +12,8 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; /** * 支付宝分账服务 @@ -25,32 +25,27 @@ import java.util.List; @RequiredArgsConstructor public class AliPayAllocationService { - private final AliPayConfigService aliPayConfigService; - /** * 发起分账 */ @SneakyThrows public void allocation(AllocationOrder allocationOrder, List orderDetails){ - - aliPayConfigService.initConfig(aliPayConfigService.getConfig()); - + // 分账主体参数 AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel(); + model.setOutRequestNo(String.valueOf(allocationOrder.getOutReqNo())); + model.setTradeNo(allocationOrder.getGatewayPayOrderNo()); + model.setRoyaltyMode("async"); -// model.setOutRequestNo(String.valueOf(allocationOrder.getId())); -// model.setTradeNo(allocationOrder.getGatewayOrderNo()); - - model.setOutRequestNo(IdUtil.getSnowflakeNextIdStr()); - model.setTradeNo(""); -// model.setRoyaltyMode("async"); - OpenApiRoyaltyDetailInfoPojo detailInfoPojo = new OpenApiRoyaltyDetailInfoPojo(); - detailInfoPojo.setTransIn(""); - detailInfoPojo.setAmount("0.01"); - - - List royaltyParameters = Collections.singletonList(detailInfoPojo); - + // 分账子参数 + List royaltyParameters = orderDetails.stream() + .map(o -> { + OpenApiRoyaltyDetailInfoPojo infoPojo = new OpenApiRoyaltyDetailInfoPojo(); + infoPojo.setAmount(String.valueOf(o.getAmount() / 100.0)); + infoPojo.setTransIn(o.getReceiverAccount()); + return infoPojo; + }) + .collect(Collectors.toList()); model.setRoyaltyParameters(royaltyParameters); AlipayTradeOrderSettleResponse response = AliPayApi.tradeOrderSettleToResponse(model); @@ -60,7 +55,18 @@ public class AliPayAllocationService { /** * 分账完结 */ - public void x2(){ + @SneakyThrows + public void finish(AllocationOrder allocationOrder){ + // 分账主体参数 + AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel(); + model.setOutRequestNo(String.valueOf(allocationOrder.getOutReqNo())); + model.setTradeNo(allocationOrder.getGatewayPayOrderNo()); + // 分账完结参数 + SettleExtendParams extendParams = new SettleExtendParams(); + extendParams.setRoyaltyFinish("true"); + model.setExtendParams(extendParams); + AlipayTradeOrderSettleResponse response = AliPayApi.tradeOrderSettleToResponse(model); + System.out.println(response); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayAllocationService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayAllocationService.java new file mode 100644 index 000000000..1e70b7620 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WeChatPayAllocationService.java @@ -0,0 +1,106 @@ +package cn.bootx.platform.daxpay.service.core.channel.wechat.service; + +import cn.bootx.platform.daxpay.code.AllocationReceiverTypeEnum; +import cn.bootx.platform.daxpay.exception.pay.PayFailureException; +import cn.bootx.platform.daxpay.service.code.WeChatPayCode; +import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrder; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrderDetail; +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.ijpay.core.enums.SignType; +import com.ijpay.core.kit.WxPayKit; +import com.ijpay.wxpay.WxPayApi; +import com.ijpay.wxpay.model.ProfitSharingModel; +import com.ijpay.wxpay.model.ReceiverModel; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayInputStream; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 微信分账服务 + * @author xxm + * @since 2024/4/7 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class WeChatPayAllocationService { + + /** + * 发起分账 + */ + @SneakyThrows + public void allocation(AllocationOrder allocationOrder, List orderDetails, WeChatPayConfig config){ + + List list = orderDetails.stream().map(o->{ + AllocationReceiverTypeEnum receiverTypeEnum = AllocationReceiverTypeEnum.findByCode(o.getReceiverType()); + return ReceiverModel.builder() + .type(receiverTypeEnum.getOutCode()) + .account(o.getReceiverAccount()) + .amount(o.getAmount()) + .description(allocationOrder.getDescription()) + .build(); + }).collect(Collectors.toList()); + + Map params = ProfitSharingModel.builder() + .mch_id(config.getWxMchId()) + .appid(config.getWxAppId()) + .nonce_str(WxPayKit.generateStr()) + .transaction_id(allocationOrder.getGatewayPayOrderNo()) + .out_order_no(WxPayKit.generateStr()) + .receivers(JSON.toJSONString(list)) + .build() + .createSign(config.getApiKeyV2(), SignType.HMACSHA256); + + byte[] fileBytes = Base64.decode(config.getP12()); + ByteArrayInputStream inputStream = new ByteArrayInputStream(fileBytes); + String xmlResult = WxPayApi.multiProfitSharing(params, inputStream, config.getWxMchId()); + Map result = WxPayKit.xmlToMap(xmlResult); + this.verifyErrorMsg(result); + } + + /** + * 完成分账 + */ + public void finish(AllocationOrder allocationOrder, WeChatPayConfig config){ + Map params = ProfitSharingModel.builder() + .mch_id(config.getWxMchId()) + .appid(config.getWxAppId()) + .nonce_str(WxPayKit.generateStr()) + .transaction_id(allocationOrder.getGatewayPayOrderNo()) + .out_order_no(allocationOrder.getOutReqNo()) + .description("分账完成") + .build() + .createSign(config.getApiKeyV2(), SignType.HMACSHA256); + + byte[] fileBytes = Base64.decode(config.getP12()); + ByteArrayInputStream inputStream = new ByteArrayInputStream(fileBytes); + String xmlResult = WxPayApi.profitSharingFinish(params, inputStream, config.getWxMchId()); + Map result = WxPayKit.xmlToMap(xmlResult); + this.verifyErrorMsg(result); + } + + /** + * 验证错误信息 + */ + private void verifyErrorMsg(Map result) { + String returnCode = result.get(WeChatPayCode.RETURN_CODE); + String resultCode = result.get(WeChatPayCode.RESULT_CODE); + if (!WxPayKit.codeIsOk(returnCode) || !WxPayKit.codeIsOk(resultCode)) { + String errorMsg = result.get(WeChatPayCode.ERR_CODE_DES); + if (StrUtil.isBlank(errorMsg)) { + errorMsg = result.get(WeChatPayCode.RETURN_MSG); + } + log.error("分账操作失败 {}", errorMsg); + throw new PayFailureException(errorMsg); + } + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/convert/AllocationConvert.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/convert/AllocationConvert.java new file mode 100644 index 000000000..2f6fc309b --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/convert/AllocationConvert.java @@ -0,0 +1,24 @@ +package cn.bootx.platform.daxpay.service.core.order.allocation.convert; + +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrder; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrderDetail; +import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDetailDto; +import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDto; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 分账实体类转换 + * @author xxm + * @since 2024/4/7 + */ +@Mapper +public interface AllocationConvert { + AllocationConvert CONVERT = Mappers.getMapper(AllocationConvert.class); + + + AllocationOrderDto convert(AllocationOrder in); + + AllocationOrderDetailDto convert(AllocationOrderDetail in); + +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderDetailManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderDetailManager.java new file mode 100644 index 000000000..63526d05a --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderDetailManager.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.core.order.allocation.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrderDetail; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +/** + * + * @author xxm + * @since 2024/4/7 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class AllocationOrderDetailManager extends BaseManager { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderDetailMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderDetailMapper.java new file mode 100644 index 000000000..cd4525a9b --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderDetailMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.order.allocation.dao; + +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrderDetail; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/4/7 + */ +@Mapper +public interface AllocationOrderDetailMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderManager.java new file mode 100644 index 000000000..30a064af9 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderManager.java @@ -0,0 +1,27 @@ +package cn.bootx.platform.daxpay.service.core.order.allocation.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrder; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +/** + * + * @author xxm + * @since 2024/4/7 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class AllocationOrderManager extends BaseManager { + + /** + * 根据分账单号查询 + */ + public Optional findByAllocationNo(String allocationNo){ + return findByField(AllocationOrder::getAllocationNo, allocationNo); + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderMapper.java new file mode 100644 index 000000000..7fe32d94e --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/dao/AllocationOrderMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.order.allocation.dao; + +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrder; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/4/7 + */ +@Mapper +public interface AllocationOrderMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/AllocationOrder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/AllocationOrder.java index 970da9913..ddce80628 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/AllocationOrder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/AllocationOrder.java @@ -1,11 +1,20 @@ package cn.bootx.platform.daxpay.service.core.order.allocation.entity; +import cn.bootx.platform.common.core.function.EntityBaseFunction; import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.platform.daxpay.service.core.order.allocation.convert.AllocationConvert; +import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDto; import cn.bootx.table.modify.annotation.DbColumn; +import cn.bootx.table.modify.mysql.annotation.DbMySqlIndex; +import cn.bootx.table.modify.mysql.constants.MySqlIndexType; +import com.baomidou.mybatisplus.annotation.FieldStrategy; +import com.baomidou.mybatisplus.annotation.TableField; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; +import java.time.LocalDateTime; + /** * 分账订单 * @author xxm @@ -14,7 +23,7 @@ import lombok.experimental.Accessors; @EqualsAndHashCode(callSuper = true) @Data @Accessors(chain = true) -public class AllocationOrder extends MpBaseEntity { +public class AllocationOrder extends MpBaseEntity implements EntityBaseFunction { /** * 支付订单ID @@ -23,11 +32,36 @@ public class AllocationOrder extends MpBaseEntity { private Long paymentId; /** - * 网关订单号 + * 网关支付订单号 */ - @DbColumn(comment = "网关订单号") - private String gatewayOrderNo; + @DbColumn(comment = "网关支付订单号") + private String gatewayPayOrderNo; + /** + * 网关分账单号 + */ + @DbColumn(comment = "网关分账单号") + private String gatewayAllocationNo; + + /** + * 分账单号 + */ + @DbMySqlIndex(comment = "分账单号索引", type = MySqlIndexType.UNIQUE) + @DbColumn(comment = "分账单号") + private String allocationNo; + + + /** + * 外部请求号 + */ + @DbColumn(comment = "外部请求号") + private String outReqNo; + + /** + * 所属通道 + */ + @DbColumn(comment = "所属通道") + private String channel; /** * 总分账金额 @@ -35,4 +69,36 @@ public class AllocationOrder extends MpBaseEntity { @DbColumn(comment = "总分账金额") private Integer amount; + /** + * 分账描述 + */ + @DbColumn(comment = "分账描述") + private String description; + + /** + * 状态 + */ + @DbColumn(comment = "状态") + private String status; + + /** + * 错误原因 + */ + @DbColumn(comment = "错误原因") + @TableField(updateStrategy = FieldStrategy.ALWAYS) + private String errorMsg; + + /** + * 完成时间 + */ + @DbColumn(comment = "完成时间") + private LocalDateTime finishTime; + + /** + * 转换 + */ + @Override + public AllocationOrderDto toDto() { + return AllocationConvert.CONVERT.convert(this); + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/AllocationOrderDetail.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/AllocationOrderDetail.java index 1a0846a8f..6be22cc89 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/AllocationOrderDetail.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/AllocationOrderDetail.java @@ -1,6 +1,12 @@ package cn.bootx.platform.daxpay.service.core.order.allocation.entity; +import cn.bootx.platform.common.core.function.EntityBaseFunction; import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity; +import cn.bootx.platform.daxpay.code.AllocationReceiverTypeEnum; +import cn.bootx.platform.daxpay.service.core.order.allocation.convert.AllocationConvert; +import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDetailDto; +import cn.bootx.platform.starter.data.perm.sensitive.SensitiveInfo; +import cn.bootx.table.modify.annotation.DbColumn; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @@ -13,7 +19,49 @@ import lombok.experimental.Accessors; @EqualsAndHashCode(callSuper = true) @Data @Accessors(chain = true) -public class AllocationOrderDetail extends MpBaseEntity { +public class AllocationOrderDetail extends MpBaseEntity implements EntityBaseFunction { + /** 分账订单ID */ + @DbColumn(comment = "分账订单ID") + private Long orderId; + /** 接收者ID */ + @DbColumn(comment = "接收者ID") + private Long receiverId; + + /** 分账比例 */ + @DbColumn(comment = "分账比例(万分之多少)") + private Integer rate; + + /** 分账金额 */ + @DbColumn(comment = "分账金额") + private Integer amount; + + /** + * 分账接收方类型 + * @see AllocationReceiverTypeEnum + */ + @DbColumn(comment = "分账接收方类型") + private String receiverType; + + /** 接收方账号 */ + @DbColumn(comment = "接收方账号") + @SensitiveInfo + private String receiverAccount; + + /** 接收方姓名 */ + @DbColumn(comment = "接收方姓名") + private String receiverName; + + /** 状态 */ + @DbColumn(comment = "状态") + private String status; + + /** + * 转换 + */ + @Override + public AllocationOrderDetailDto toDto() { + return AllocationConvert.CONVERT.convert(this); + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/OrderAndDetail.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/OrderAndDetail.java new file mode 100644 index 000000000..bb401c350 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/entity/OrderAndDetail.java @@ -0,0 +1,21 @@ +package cn.bootx.platform.daxpay.service.core.order.allocation.entity; + +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 分账订单和明细 + * @author xxm + * @since 2024/4/7 + */ +@Data +@Accessors(chain = true) +public class OrderAndDetail { + + /** 分账订单 */ + private AllocationOrder order; + /** 分账订单明细 */ + private List details; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/service/AllocationOrderService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/service/AllocationOrderService.java new file mode 100644 index 000000000..b7f6fc3f0 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/allocation/service/AllocationOrderService.java @@ -0,0 +1,96 @@ +package cn.bootx.platform.daxpay.service.core.order.allocation.service; + +import cn.bootx.platform.common.core.rest.param.PageParam; +import cn.bootx.platform.daxpay.param.pay.allocation.AllocationStartParam; +import cn.bootx.platform.daxpay.service.code.AllocationStatusEnum; +import cn.bootx.platform.daxpay.service.core.order.allocation.dao.AllocationOrderDetailManager; +import cn.bootx.platform.daxpay.service.core.order.allocation.dao.AllocationOrderManager; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrder; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrderDetail; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.OrderAndDetail; +import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder; +import cn.bootx.platform.daxpay.service.dto.allocation.AllocationGroupReceiverResult; +import cn.bootx.platform.daxpay.service.param.order.AllocationOrderQuery; +import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 分账订单服务 + * @author xxm + * @since 2024/4/7 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class AllocationOrderService { + private final AllocationOrderManager allocationOrderManager; + private final AllocationOrderDetailManager allocationOrderDetailManager; + + /** + * 分页查询分账订单 + */ + public void page(PageParam pageParam, AllocationOrderQuery param){ + + } + + /** + * 生成分账订单 + */ + @Transactional(rollbackFor = Exception.class) + public OrderAndDetail create(AllocationStartParam param, PayOrder payOrder, int orderAmount, List receiversByGroups){ + long orderId = IdUtil.getSnowflakeNextId(); + + // 请求号不存在使用订单ID + String allocationNo = param.getAllocationNo(); + if (StrUtil.isBlank(allocationNo)){ + allocationNo = String.valueOf(orderId); + } + + // 订单明细 + List details = receiversByGroups.stream() + .map(o -> { + // 计算分账金额, 小数不分直接舍弃, 防止分账金额超过上限 + Integer rate = o.getRate(); + Integer amount = orderAmount * rate / 10000; + AllocationOrderDetail detail = new AllocationOrderDetail(); + detail.setOrderId(orderId) + .setReceiverId(o.getId()) + .setStatus(AllocationStatusEnum.WAITING.getCode()) + .setAmount(amount) + .setRate(rate) + .setReceiverType(o.getReceiverType()) + .setReceiverName(o.getReceiverName()) + .setReceiverAccount(o.getReceiverAccount()); + return detail; + }) + .collect(Collectors.toList()); + // 求分账的总额 + Integer sumAmount = details.stream() + .map(AllocationOrderDetail::getAmount) + .reduce(0, Integer::sum); + // 分账订单 + AllocationOrder allocationOrder = new AllocationOrder() + .setPaymentId(payOrder.getId()) + .setAllocationNo(allocationNo) + .setChannel(payOrder.getAsyncChannel()) + .setGatewayPayOrderNo(payOrder.getGatewayOrderNo()) + .setOutReqNo(String.valueOf(orderId)) + .setDescription(param.getDescription()) + .setStatus(AllocationStatusEnum.WAITING.getCode()) + .setAmount(sumAmount); + allocationOrder.setId(orderId); + // 保存 + allocationOrderDetailManager.saveAll(details); + allocationOrderManager.save(allocationOrder); + + return new OrderAndDetail().setOrder(allocationOrder).setDetails(details); + } + +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationGroupManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationGroupManager.java index 0a57fb3cf..62e401d48 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationGroupManager.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/dao/AllocationGroupManager.java @@ -12,6 +12,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; +import java.util.Optional; + /** * * @author xxm @@ -27,4 +29,21 @@ public class AllocationGroupManager extends BaseManager generator = QueryGenerator.generator(query); return page(mpPage,generator); } + + /** + * 清除默认分账组 + */ + public void clearDefault(String channel) { + lambdaUpdate() + .set(AllocationGroup::isDefaultGroup,false) + .eq(AllocationGroup::getChannel,channel) + .update(); + } + + /** + * 获取默认分账组 + */ + public Optional findDefaultGroup(String asyncChannel) { + return findByField(AllocationGroup::getChannel,asyncChannel); + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationGroup.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationGroup.java index 3fa429621..8bf28163e 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationGroup.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/entity/AllocationGroup.java @@ -33,6 +33,9 @@ public class AllocationGroup extends MpBaseEntity implements EntityBaseFunction< @TableField(updateStrategy = FieldStrategy.NEVER) private String channel; + @DbColumn(comment = "默认分账组") + private boolean defaultGroup; + @DbColumn(comment = "总分账比例(万分之多少)") private Integer totalRate; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/factory/AllocationFactory.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/factory/AllocationFactory.java new file mode 100644 index 000000000..b487cf46e --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/factory/AllocationFactory.java @@ -0,0 +1,37 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.factory; + +import cn.bootx.platform.daxpay.code.PayChannelEnum; +import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException; +import cn.bootx.platform.daxpay.service.func.AbsAllocationStrategy; +import cn.hutool.extra.spring.SpringUtil; +import lombok.experimental.UtilityClass; + +/** + * 分账策略工厂 + * @author xxm + * @since 2024/4/7 + */ +@UtilityClass +public class AllocationFactory { + + /** + * 根据传入的支付通道创建策略 + * @return 支付策略 + */ + public static AbsAllocationStrategy create(String channel) { + PayChannelEnum channelEnum = PayChannelEnum.findByCode(channel); + + AbsAllocationStrategy strategy; + switch (channelEnum) { + case ALI: + strategy = SpringUtil.getBean(AbsAllocationStrategy.class); + break; + case WECHAT: + strategy = SpringUtil.getBean(AbsAllocationStrategy.class); + break; + default: + throw new PayUnsupportedMethodException(); + } + return strategy; + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationGroupService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationGroupService.java index b7f3ae02a..b36f1c905 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationGroupService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationGroupService.java @@ -100,6 +100,19 @@ public class AllocationGroupService { groupManager.save(group); } + /** + * 设置默认分账组 + */ + @Transactional(rollbackFor = Exception.class) + public void setDefault(Long id){ + // 分账组 + AllocationGroup group = groupManager.findById(id) + .orElseThrow(() -> new DataNotExistException("未找到分账组")); + groupManager.clearDefault(group.getChannel()); + group.setDefaultGroup(true); + groupManager.updateById(group); + } + /** * 更新分账组 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationOrderSyncService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationOrderSyncService.java new file mode 100644 index 000000000..941f2b179 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationOrderSyncService.java @@ -0,0 +1,16 @@ +package cn.bootx.platform.daxpay.service.core.payment.allocation.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 分账订单同步服务 + * @author xxm + * @since 2024/4/7 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class AllocationOrderSyncService { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationService.java index a5c769a20..adb66b9e4 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/service/AllocationService.java @@ -1,16 +1,28 @@ package cn.bootx.platform.daxpay.service.core.payment.allocation.service; import cn.bootx.platform.common.core.exception.DataNotExistException; -import cn.bootx.platform.daxpay.param.pay.AllocationParam; +import cn.bootx.platform.daxpay.exception.pay.PayFailureException; +import cn.bootx.platform.daxpay.param.pay.allocation.AllocationFinishParam; +import cn.bootx.platform.daxpay.param.pay.allocation.AllocationStartParam; +import cn.bootx.platform.daxpay.result.allocation.AllocationResult; +import cn.bootx.platform.daxpay.service.code.AllocationStatusEnum; +import cn.bootx.platform.daxpay.service.core.order.allocation.dao.AllocationOrderManager; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrder; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrderDetail; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.OrderAndDetail; +import cn.bootx.platform.daxpay.service.core.order.allocation.service.AllocationOrderService; +import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager; 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.payment.allocation.dao.AllocationGroupManager; import cn.bootx.platform.daxpay.service.core.payment.allocation.entity.AllocationGroup; +import cn.bootx.platform.daxpay.service.core.payment.allocation.factory.AllocationFactory; import cn.bootx.platform.daxpay.service.dto.allocation.AllocationGroupReceiverResult; +import cn.bootx.platform.daxpay.service.func.AbsAllocationStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.Objects; @@ -27,15 +39,21 @@ public class AllocationService { private final PayOrderManager payOrderManager; + private final PayChannelOrderManager payChannelOrderManager; + private final AllocationGroupManager groupManager; + private final AllocationOrderManager allocationOrderManager; + private final AllocationGroupService allocationGroupService; + private final AllocationOrderService allocationOrderService; + + /** - * 开启分账 + * 开启分账, 使用分账组进行分账 */ - @Transactional(rollbackFor = Exception.class) - public void allocation(AllocationParam param) { + public AllocationResult allocation(AllocationStartParam param) { // 查询支付单 PayOrder payOrder = null; if (Objects.nonNull(param.getPaymentId())){ @@ -46,10 +64,84 @@ public class AllocationService { payOrder = payOrderManager.findByBusinessNo(param.getBusinessNo()) .orElseThrow(() -> new DataNotExistException("未查询到支付订单")); } - AllocationGroup allocationGroup = groupManager.findById(param.getAllocationGroupId()) - .orElseThrow(() -> new DataNotExistException("未查询到分账组")); - List receiversByGroups = allocationGroupService.findReceiversByGroups(param.getAllocationGroupId()); + // 判断订单是否可以分账 + if (!payOrder.isAllocation()){ + throw new PayFailureException("该订单不允许分账"); + } + // 查询待分账的通道支付订单 + PayChannelOrder channelOrder = payChannelOrderManager.findByAsyncChannel(payOrder.getId()) + .orElseThrow(() -> new DataNotExistException("未查询到支付通道订单")); + + // 查询分账组 未传输使用默认该通道默认分账组 + AllocationGroup allocationGroup; + if (Objects.nonNull(param.getAllocationGroupId())) { + allocationGroup = groupManager.findById(param.getAllocationGroupId()).orElseThrow(() -> new DataNotExistException("未查询到分账组")); + } else { + allocationGroup = groupManager.findDefaultGroup(payOrder.getAsyncChannel()).orElseThrow(() -> new DataNotExistException("未查询到默认分账组")); + } + List receiversByGroups = allocationGroupService.findReceiversByGroups(allocationGroup.getId()); + + // 创建分账单和明细并保存, 使用事务 + OrderAndDetail orderAndDetail = allocationOrderService.create(param ,payOrder, channelOrder.getAmount(), receiversByGroups); + + // 创建分账策略并初始化 + AbsAllocationStrategy allocationStrategy = AllocationFactory.create(payOrder.getAsyncChannel()); + AllocationOrder order = orderAndDetail.getOrder(); + List details = orderAndDetail.getDetails(); + allocationStrategy.initParam(order, details); + + // 分账预处理 + allocationStrategy.doBeforeHandler(); + try { + // 分账处理 + allocationStrategy.allocation(); + // 执行中 + order.setStatus(AllocationStatusEnum.PARTIAL_PROCESSING.getCode()) + .setErrorMsg(null); + } catch (Exception e) { + // 失败 + order.setStatus(AllocationStatusEnum.PARTIAL_FAILED.getCode()) + .setErrorMsg(e.getMessage()); + } + allocationOrderManager.updateById(order); + + return new AllocationResult().setOrderId(order.getId()) + .setAllocationNo(order.getAllocationNo()) + .setStatus(order.getStatus()); } + /** + * 分账完结 + */ + public void finish(AllocationFinishParam param) { + AllocationOrder allocationOrder; + if (Objects.nonNull(param.getOrderId())){ + allocationOrder = allocationOrderManager.findById(param.getOrderId()) + .orElseThrow(() -> new DataNotExistException("未查询到分账单信息")); + } else { + allocationOrder = allocationOrderManager.findByAllocationNo(param.getAllocationNo()) + .orElseThrow(() -> new DataNotExistException("未查询到分账单信息")); + } + + // 创建分账策略并初始化 + AbsAllocationStrategy allocationStrategy = AllocationFactory.create(allocationOrder.getChannel()); + allocationStrategy.initParam(allocationOrder, null); + + // 分账完结预处理 + allocationStrategy.doBeforeHandler(); + try { + // 分账处理 + allocationStrategy.allocation(); + // 执行中 + allocationOrder.setStatus(AllocationStatusEnum.FINISH_PROCESSING.getCode()) + .setErrorMsg(null); + } catch (Exception e) { + // 失败 + allocationOrder.setStatus(AllocationStatusEnum.FINISH_FAILED.getCode()) + .setErrorMsg(e.getMessage()); + } + + allocationOrderManager.updateById(allocationOrder); + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/strategy/allocation/AliPayAllocationStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/strategy/allocation/AliPayAllocationStrategy.java index 0a2a08db2..168590210 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/strategy/allocation/AliPayAllocationStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/strategy/allocation/AliPayAllocationStrategy.java @@ -1,10 +1,18 @@ package cn.bootx.platform.daxpay.service.core.payment.allocation.strategy.allocation; +import cn.bootx.platform.daxpay.code.PayChannelEnum; +import cn.bootx.platform.daxpay.exception.pay.PayFailureException; +import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig; +import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayAllocationService; +import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayConfigService; +import cn.bootx.platform.daxpay.service.func.AbsAllocationStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import java.util.Objects; + import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; /** @@ -16,5 +24,50 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT @Service @Scope(SCOPE_PROTOTYPE) @RequiredArgsConstructor -public class AliPayAllocationStrategy { +public class AliPayAllocationStrategy extends AbsAllocationStrategy { + + private final AliPayAllocationService aliPayAllocationService; + + private final AliPayConfigService aliPayConfigService; + + private AliPayConfig aliPayConfig;; + + + /** + * 策略标识 + */ + @Override + public PayChannelEnum getChannel() { + return PayChannelEnum.ALI; + } + + /** + * 操作前处理, 校验和初始化支付配置 + */ + @Override + public void doBeforeHandler() { + this.aliPayConfig = aliPayConfigService.getConfig(); + // 判断是否支持分账 + if (Objects.equals(aliPayConfig.getAllocation(),false)){ + throw new PayFailureException("微信支付配置不支持分账"); + } + aliPayConfigService.initConfig(this.aliPayConfig); + } + + /** + * 分账操作 + */ + @Override + public void allocation() { + aliPayAllocationService.allocation(this.getAllocationOrder(), this.getAllocationOrderDetails()); + } + + /** + * 分账完结 + */ + @Override + public void finish() { + aliPayAllocationService.finish(this.getAllocationOrder()); + } + } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/strategy/allocation/WeChatPayAllocationStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/strategy/allocation/WeChatPayAllocationStrategy.java index 9dd708734..645843308 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/strategy/allocation/WeChatPayAllocationStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/allocation/strategy/allocation/WeChatPayAllocationStrategy.java @@ -1,10 +1,18 @@ package cn.bootx.platform.daxpay.service.core.payment.allocation.strategy.allocation; +import cn.bootx.platform.daxpay.code.PayChannelEnum; +import cn.bootx.platform.daxpay.exception.pay.PayFailureException; +import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig; +import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayAllocationService; +import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayConfigService; +import cn.bootx.platform.daxpay.service.func.AbsAllocationStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import java.util.Objects; + import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; /** @@ -16,5 +24,48 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT @Service @Scope(SCOPE_PROTOTYPE) @RequiredArgsConstructor -public class WeChatPayAllocationStrategy { +public class WeChatPayAllocationStrategy extends AbsAllocationStrategy { + + private final WeChatPayAllocationService weChatPayAllocationService; + + private final WeChatPayConfigService weChatPayConfigService; + + private WeChatPayConfig weChatPayConfig; + + /** + * 策略标识 + */ + @Override + public PayChannelEnum getChannel() { + return PayChannelEnum.WECHAT; + } + + /** + * 操作前处理, 校验和初始化支付配置 + */ + @Override + public void doBeforeHandler() { + weChatPayConfig = weChatPayConfigService.getAndCheckConfig(); + // 判断是否支持分账 + if (Objects.equals(weChatPayConfig.getAllocation(),false)){ + throw new PayFailureException("微信支付配置不支持分账"); + } + } + + /** + * 分账操作 + */ + @Override + public void allocation() { + weChatPayAllocationService.allocation(getAllocationOrder(), getAllocationOrderDetails(), weChatPayConfig); + } + + /** + * 分账完结 + */ + @Override + public void finish() { + weChatPayAllocationService.finish(getAllocationOrder(), weChatPayConfig); + } + } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/allocation/AllocationGroupDto.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/allocation/AllocationGroupDto.java index b33fce0fa..422764558 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/allocation/AllocationGroupDto.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/allocation/AllocationGroupDto.java @@ -1,6 +1,7 @@ package cn.bootx.platform.daxpay.service.dto.allocation; import cn.bootx.platform.common.core.rest.dto.BaseDto; +import cn.bootx.table.modify.annotation.DbColumn; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -23,6 +24,9 @@ public class AllocationGroupDto extends BaseDto { @Schema(description = "通道") private String channel; + @DbColumn(comment = "默认分账组") + private Boolean defaultGroup; + @Schema(description = "总分账比例(万分之多少)") private Integer totalRate; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/allocation/AllocationOrderDetailDto.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/allocation/AllocationOrderDetailDto.java new file mode 100644 index 000000000..1574ab731 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/allocation/AllocationOrderDetailDto.java @@ -0,0 +1,19 @@ +package cn.bootx.platform.daxpay.service.dto.order.allocation; + +import cn.bootx.platform.common.core.rest.dto.BaseDto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 分账订单详情 + * @author xxm + * @since 2024/4/7 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "") +public class AllocationOrderDetailDto extends BaseDto { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/allocation/AllocationOrderDto.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/allocation/AllocationOrderDto.java new file mode 100644 index 000000000..fdde56813 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/allocation/AllocationOrderDto.java @@ -0,0 +1,21 @@ +package cn.bootx.platform.daxpay.service.dto.order.allocation; + +import cn.bootx.platform.common.core.rest.dto.BaseDto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 分账订单 + * @author xxm + * @since 2024/4/7 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "分账订单") +public class AllocationOrderDto extends BaseDto { + + +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsAllocationReceiverStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsAllocationReceiverStrategy.java index 94ee4260b..463f51a35 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsAllocationReceiverStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsAllocationReceiverStrategy.java @@ -6,7 +6,7 @@ import lombok.Setter; import lombok.extern.slf4j.Slf4j; /** - * 分账接收方管理抽象策略 + * 分账抽象策略 * @author xxm * @since 2024/4/1 */ @@ -17,10 +17,13 @@ public abstract class AbsAllocationReceiverStrategy implements PayStrategy{ private AllocationReceiver allocationReceiver; + /** + * 操作前校验 + */ public abstract boolean validation(); /** - * 支付前处理, 校验和初始化支付配置 + * 操作前处理, 校验和初始化支付配置 */ public abstract void doBeforeHandler(); diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsAllocationStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsAllocationStrategy.java new file mode 100644 index 000000000..911e459d4 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsAllocationStrategy.java @@ -0,0 +1,47 @@ +package cn.bootx.platform.daxpay.service.func; + +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrder; +import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrderDetail; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * 分账接收方管理抽象策略 + * @author xxm + * @since 2024/4/1 + */ +@Slf4j +@Getter +@Setter +public abstract class AbsAllocationStrategy implements PayStrategy{ + + private AllocationOrder allocationOrder; + + private List allocationOrderDetails; + + /** + * 初始化参数 + */ + public void initParam(AllocationOrder allocationOrder, List allocationOrderDetails) { + this.allocationOrder = allocationOrder; + this.allocationOrderDetails = allocationOrderDetails; + } + + /** + * 操作前处理, 校验和初始化支付配置 + */ + public abstract void doBeforeHandler(); + + /** + * 分账操作 + */ + public abstract void allocation(); + + /** + * 分账完结 + */ + public abstract void finish(); +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsRefundRepairStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsRefundRepairStrategy.java index bfddf2794..4e02ee533 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsRefundRepairStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsRefundRepairStrategy.java @@ -11,7 +11,7 @@ import lombok.Getter; import java.util.Objects; /** - * 支付退款修复策略, 只要异步支付订单的退款才会有修复选项 + * 支付退款修复策略, 只有异步支付订单的退款才有修复选项 * @author xxm * @since 2024/1/25 */ 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 d2592be7f..210d357b4 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 @@ -14,7 +14,7 @@ import lombok.Setter; import java.time.LocalDateTime; /** - * 抽象支付退款策略基类 + * 抽象支付退款策略 * * @author xxm * @since 2020/12/11 diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/order/AllocationOrderQuery.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/order/AllocationOrderQuery.java new file mode 100644 index 000000000..60dfd8d3f --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/order/AllocationOrderQuery.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.param.order; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 分账订单查询参数 + * @author xxm + * @since 2024/4/7 + */ +@Data +@Accessors(chain = true) +@Schema(title = "分账订单查询参数") +public class AllocationOrderQuery { + + +}