diff --git a/_doc/Task.md b/_doc/Task.md index 542a0162a..f9a8521de 100644 --- a/_doc/Task.md +++ b/_doc/Task.md @@ -16,23 +16,24 @@ - [x] 分账同步 - [ ] 保存分账同步记录 - [ ] SDK支持分账相关接口 -- [ ] DEMO增加获取微信OpenID和支付宝OpenId功能 - [ ] 分账回调处理 -- [ ] 分账通知发送功能 +- [x] 分账通知发送功能 - [x] 分账支持手动和自动分账两种 - [ ] 金额过小不进行分账, 增加新状态, 金额小于0.01元直接忽略 -- [ ] 增加收单收银台功能 - [x] 优化签名注解和上下文初始化注解切面 - [x] 对账差异单, 数据不一致处理异常, 本地待对账订单类型记录错误 - [x] 订单超时任务注册任务错误,id改为订单号 - [x] 系统中金额分转元精度异常问题 2.0.7: 对账完善和系统优化 +- [ ] DEMO增加获取微信OpenID和支付宝OpenId功能 - [ ] 对账提供外部接口调用 - [ ] 下载系统账单 +- [ ] 增加收单收银台功能 - [ ] 增加资金对账单功能 - [ ] 支付通道两个独立的配置进行合并为一个 - [ ] 撤销接口 +- [ ] 支付和退款达到终态不可以再回退回之前的状态, 只能添加差错单进行处理 2.1.x 版本内容 - [ ] 差错单据处理 diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/daxpay/single/admin/controller/allocation/AllocationOrderController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/daxpay/single/admin/controller/allocation/AllocationOrderController.java index e6c95633f..262473697 100644 --- a/daxpay-single/daxpay-single-admin/src/main/java/cn/daxpay/single/admin/controller/allocation/AllocationOrderController.java +++ b/daxpay-single/daxpay-single-admin/src/main/java/cn/daxpay/single/admin/controller/allocation/AllocationOrderController.java @@ -12,6 +12,7 @@ import cn.daxpay.single.param.payment.allocation.AllocFinishParam; import cn.daxpay.single.service.annotation.PlatformInitContext; import cn.daxpay.single.service.core.order.allocation.service.AllocationOrderService; import cn.daxpay.single.service.core.payment.allocation.service.AllocationService; +import cn.daxpay.single.service.core.payment.allocation.service.AllocationSyncService; import cn.daxpay.single.service.dto.order.allocation.AllocationOrderDetailDto; import cn.daxpay.single.service.dto.order.allocation.AllocationOrderDto; import cn.daxpay.single.service.param.order.AllocationOrderQuery; @@ -40,6 +41,8 @@ public class AllocationOrderController { private final AllocationService allocationService; + private final AllocationSyncService allocationSyncService; + @Operation(summary = "分页") @GetMapping("/page") public ResResult> page(PageParam pageParam, AllocationOrderQuery param){ @@ -77,7 +80,7 @@ public class AllocationOrderController { public ResResult sync(String allocationNo){ AllocSyncParam param = new AllocSyncParam(); param.setAllocationNo(allocationNo); - allocationService.sync(param); + allocationSyncService.sync(param); return Res.ok(); } diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/daxpay/single/result/allocation/AllocationSyncResult.java b/daxpay-single/daxpay-single-core/src/main/java/cn/daxpay/single/result/allocation/AllocationSyncResult.java index 621ca9bc8..7d587581c 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/daxpay/single/result/allocation/AllocationSyncResult.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/daxpay/single/result/allocation/AllocationSyncResult.java @@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; /** - * 分账同步接口 + * 分账同步接口返回类 * @author xxm * @since 2024/5/20 */ diff --git a/daxpay-single/daxpay-single-gateway/src/main/java/cn/daxpay/single/gateway/controller/UniAllocationController.java b/daxpay-single/daxpay-single-gateway/src/main/java/cn/daxpay/single/gateway/controller/UniAllocationController.java index f7bcf15ac..36484dcf2 100644 --- a/daxpay-single/daxpay-single-gateway/src/main/java/cn/daxpay/single/gateway/controller/UniAllocationController.java +++ b/daxpay-single/daxpay-single-gateway/src/main/java/cn/daxpay/single/gateway/controller/UniAllocationController.java @@ -11,6 +11,7 @@ import cn.daxpay.single.service.annotation.PaymentSign; import cn.daxpay.single.service.annotation.PlatformInitContext; import cn.daxpay.single.service.core.payment.allocation.service.AllocationReceiverService; import cn.daxpay.single.service.core.payment.allocation.service.AllocationService; +import cn.daxpay.single.service.core.payment.allocation.service.AllocationSyncService; import cn.daxpay.single.util.DaxRes; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -33,6 +34,8 @@ public class UniAllocationController { private final AllocationService allocationService; + private final AllocationSyncService allocationSyncService; + private final AllocationReceiverService receiverService; @PaymentSign @@ -56,7 +59,7 @@ public class UniAllocationController { @Operation(summary = "分账同步接口") @PostMapping("/sync") public DaxResult sync(@RequestBody AllocSyncParam param){ - return DaxRes.ok(allocationService.sync(param)); + return DaxRes.ok(allocationSyncService.sync(param)); } @PaymentSign diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/channel/alipay/service/AliPayAllocationService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/channel/alipay/service/AliPayAllocationService.java index a6316f8fa..f3806fbf1 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/channel/alipay/service/AliPayAllocationService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/channel/alipay/service/AliPayAllocationService.java @@ -8,9 +8,11 @@ import cn.daxpay.single.service.code.AliPayCode; import cn.daxpay.single.service.common.local.PaymentContextLocal; import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrder; import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrderDetail; +import cn.daxpay.single.service.core.payment.sync.result.AllocSyncResult; import cn.daxpay.single.util.PayUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; import com.alipay.api.AlipayResponse; import com.alipay.api.domain.*; import com.alipay.api.request.AlipayTradeOrderSettleQueryRequest; @@ -104,7 +106,7 @@ public class AliPayAllocationService { * 分账状态同步 */ @SneakyThrows - public void sync(AllocationOrder allocationOrder, List allocationOrderDetails){ + public AllocSyncResult sync(AllocationOrder allocationOrder, List allocationOrderDetails){ AlipayTradeOrderSettleQueryModel model = new AlipayTradeOrderSettleQueryModel(); model.setTradeNo(allocationOrder.getOutOrderNo()); model.setOutRequestNo(allocationOrder.getOrderNo()); @@ -132,6 +134,7 @@ public class AliPayAllocationService { } } } + return new AllocSyncResult().setSyncInfo(JSONUtil.toJsonStr(response)); } /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/channel/wechat/service/WeChatPayAllocationService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/channel/wechat/service/WeChatPayAllocationService.java index 0a28cc36a..1b20da60a 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/channel/wechat/service/WeChatPayAllocationService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/channel/wechat/service/WeChatPayAllocationService.java @@ -9,6 +9,7 @@ import cn.daxpay.single.service.code.WeChatPayCode; import cn.daxpay.single.service.core.channel.wechat.entity.WeChatPayConfig; import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrder; import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrderDetail; +import cn.daxpay.single.service.core.payment.sync.result.AllocSyncResult; import cn.daxpay.single.service.dto.channel.wechat.WeChatPayAllocationReceiver; import cn.hutool.core.codec.Base64; import cn.hutool.core.date.DatePattern; @@ -108,7 +109,7 @@ public class WeChatPayAllocationService { /** * 同步分账状态 */ - public void sync(AllocationOrder allocationOrder, List allocationOrderDetails, WeChatPayConfig config){ + public AllocSyncResult sync(AllocationOrder allocationOrder, List allocationOrderDetails, WeChatPayConfig config){ // 不要传输AppId参数, 否则会失败 Map params = ProfitSharingModel.builder() .mch_id(config.getWxMchId()) @@ -137,6 +138,7 @@ public class WeChatPayAllocationService { } } } + return new AllocSyncResult().setSyncInfo(JSONUtil.toJsonStr(receivers)); } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/service/AllocationService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/service/AllocationService.java index b5ef14fd3..0ad21538a 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/service/AllocationService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/service/AllocationService.java @@ -133,10 +133,10 @@ public class AllocationService { // TODO 返回异常处理 } // 网关分账号 - String gatewayNo = PaymentContextLocal.get() + String outAllocationNo = PaymentContextLocal.get() .getAllocationInfo() .getOutAllocationNo(); - order.setOutAllocationNo(gatewayNo); + order.setOutAllocationNo(outAllocationNo); allocationOrderManager.updateById(order); return new AllocationResult() .setAllocationNo(order.getAllocationNo()) diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/service/AllocationSyncService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/service/AllocationSyncService.java index 285eb6ea2..d4cca51fa 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/service/AllocationSyncService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/service/AllocationSyncService.java @@ -7,12 +7,17 @@ import cn.daxpay.single.code.AllocOrderResultEnum; import cn.daxpay.single.code.AllocOrderStatusEnum; import cn.daxpay.single.param.payment.allocation.AllocSyncParam; import cn.daxpay.single.result.allocation.AllocationSyncResult; +import cn.daxpay.single.service.code.PaymentTypeEnum; +import cn.daxpay.single.service.common.local.PaymentContextLocal; import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderDetailManager; import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderManager; import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrder; import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrderDetail; import cn.daxpay.single.service.core.payment.allocation.factory.AllocationFactory; import cn.daxpay.single.service.core.payment.notice.service.ClientNoticeService; +import cn.daxpay.single.service.core.payment.sync.result.AllocSyncResult; +import cn.daxpay.single.service.core.record.sync.entity.PaySyncRecord; +import cn.daxpay.single.service.core.record.sync.service.PaySyncRecordService; import cn.daxpay.single.service.func.AbsAllocationStrategy; import com.baomidou.lock.LockInfo; import com.baomidou.lock.LockTemplate; @@ -37,11 +42,14 @@ import java.util.Objects; public class AllocationSyncService { private final ClientNoticeService clientNoticeService; + private final AllocationOrderManager allocationOrderManager; - private final LockTemplate lockTemplate; private final AllocationOrderDetailManager allocationOrderDetailManager; + private final PaySyncRecordService paySyncRecordService; + + private final LockTemplate lockTemplate; /** * 分账同步, 开启一个新的事务, 不受外部抛出异常的影响 @@ -77,9 +85,9 @@ public class AllocationSyncService { allocationStrategy.initParam(allocationOrder, detailList); // 分账完结预处理 allocationStrategy.doBeforeHandler(); - allocationStrategy.doSync(); - // TODO 保存分账同步记录 - + AllocSyncResult allocSyncResult = allocationStrategy.doSync(); + // 保存分账同步记录 + this.saveRecord(allocationOrder, allocSyncResult,null,null); // 根据订单明细更新订单的状态和处理结果 this.updateOrderStatus(allocationOrder, detailList); } finally { @@ -138,4 +146,21 @@ public class AllocationSyncService { } } + + /** + * 保存同步记录 + */ + private void saveRecord(AllocationOrder order, AllocSyncResult syncResult, String errorCode, String errorMsg){ + PaySyncRecord paySyncRecord = new PaySyncRecord() + .setBizTradeNo(order.getBizAllocationNo()) + .setTradeNo(order.getAllocationNo()) + .setOutTradeNo(order.getOutAllocationNo()) + .setSyncType(PaymentTypeEnum.ALLOCATION.getCode()) + .setChannel(order.getChannel()) + .setSyncInfo(syncResult.getSyncInfo()) + .setErrorCode(errorCode) + .setErrorMsg(errorMsg) + .setClientIp(PaymentContextLocal.get().getRequestInfo().getClientIp()); + paySyncRecordService.saveRecord(paySyncRecord); + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/strategy/allocation/AliPayAllocationStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/strategy/allocation/AliPayAllocationStrategy.java index b22d5c883..a5b78bb5d 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/strategy/allocation/AliPayAllocationStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/strategy/allocation/AliPayAllocationStrategy.java @@ -5,6 +5,7 @@ import cn.daxpay.single.exception.pay.PayFailureException; import cn.daxpay.single.service.core.channel.alipay.entity.AliPayConfig; import cn.daxpay.single.service.core.channel.alipay.service.AliPayAllocationService; import cn.daxpay.single.service.core.channel.alipay.service.AliPayConfigService; +import cn.daxpay.single.service.core.payment.sync.result.AllocSyncResult; import cn.daxpay.single.service.func.AbsAllocationStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -74,8 +75,8 @@ public class AliPayAllocationStrategy extends AbsAllocationStrategy { * 同步状态 */ @Override - public void doSync() { - aliPayAllocationService.sync(this.getAllocationOrder(), this.getAllocationOrderDetails()); + public AllocSyncResult doSync() { + return aliPayAllocationService.sync(this.getAllocationOrder(), this.getAllocationOrderDetails()); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/strategy/allocation/WeChatPayAllocationStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/strategy/allocation/WeChatPayAllocationStrategy.java index 37baed79c..0416a8634 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/strategy/allocation/WeChatPayAllocationStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/allocation/strategy/allocation/WeChatPayAllocationStrategy.java @@ -5,6 +5,7 @@ import cn.daxpay.single.exception.pay.PayFailureException; import cn.daxpay.single.service.core.channel.wechat.entity.WeChatPayConfig; import cn.daxpay.single.service.core.channel.wechat.service.WeChatPayAllocationService; import cn.daxpay.single.service.core.channel.wechat.service.WeChatPayConfigService; +import cn.daxpay.single.service.core.payment.sync.result.AllocSyncResult; import cn.daxpay.single.service.func.AbsAllocationStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -72,8 +73,8 @@ public class WeChatPayAllocationStrategy extends AbsAllocationStrategy { * 同步状态 */ @Override - public void doSync() { - weChatPayAllocationService.sync(this.getAllocationOrder(),this.getAllocationOrderDetails(),weChatPayConfig); + public AllocSyncResult doSync() { + return weChatPayAllocationService.sync(this.getAllocationOrder(),this.getAllocationOrderDetails(),weChatPayConfig); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/sync/result/AllocSyncResult.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/sync/result/AllocSyncResult.java new file mode 100644 index 000000000..8e7da4cfb --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/payment/sync/result/AllocSyncResult.java @@ -0,0 +1,16 @@ +package cn.daxpay.single.service.core.payment.sync.result; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 分账同步结果 + * @author xxm + * @since 2024/5/23 + */ +@Data +@Accessors(chain = true) +public class AllocSyncResult { + /** 同步时网关返回的对象, 序列化为json字符串 */ + private String syncInfo; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/record/sync/entity/PaySyncRecord.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/record/sync/entity/PaySyncRecord.java index 504947b61..67acaf266 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/record/sync/entity/PaySyncRecord.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/record/sync/entity/PaySyncRecord.java @@ -47,7 +47,6 @@ public class PaySyncRecord extends MpCreateEntity implements EntityBaseFunction< * 三方支付返回状态 * @see PaySyncStatusEnum * @see RefundSyncStatusEnum - * @see AllocOrderStatusEnum */ @DbColumn(comment = "网关返回状态") private String outTradeStatus; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/record/sync/service/PaySyncRecordService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/record/sync/service/PaySyncRecordService.java index 5333d7c2b..907119bb3 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/record/sync/service/PaySyncRecordService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/core/record/sync/service/PaySyncRecordService.java @@ -16,7 +16,7 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; /** - * 支付同步记录 + * 支付同步记录, 包括支付/退款/分账 * @author xxm * @since 2023/7/14 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/func/AbsAllocationStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/func/AbsAllocationStrategy.java index ccbf34f41..66a6d1286 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/func/AbsAllocationStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/daxpay/single/service/func/AbsAllocationStrategy.java @@ -2,6 +2,7 @@ package cn.daxpay.single.service.func; import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrder; import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrderDetail; +import cn.daxpay.single.service.core.payment.sync.result.AllocSyncResult; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -48,5 +49,5 @@ public abstract class AbsAllocationStrategy implements PayStrategy{ /** * 同步状态 */ - public abstract void doSync(); + public abstract AllocSyncResult doSync(); }