feat 分账前后端调试

This commit is contained in:
xxm1995
2024-04-16 20:47:24 +08:00
parent 22d1dd5bf3
commit b3594d08fb
35 changed files with 519 additions and 336 deletions

View File

@@ -14,10 +14,11 @@
- [x] 分账完结
- [x] 分账处理
- [x] 发起分账
- [ ] 分账同步
- [x] 分账同步
- [x] 修复创建支付订单报错时, 订单保存数据不完整
- [x] 收银台演示支持传输分账标识
2.0.6: 分账完善和去除组合支付
2.0.6: 去除组合支付, 一系列代码优化
- [ ] 去除组合支付和场景,降低逻辑的的复杂度
- [ ] 退款场景
- [ ] 关闭支付订单
@@ -26,17 +27,20 @@
- [ ] 支付和退款回调
- [ ] 去除现金支付和储值卡支付方式
- [ ] 三方支付外部订单号规则优化: 支付P、退款R、分账A根据环境加前缀DEV_、DEMO_、PRE_
- [ ] 资金流水优化
- [ ] 资金流水优化(去除)
- [ ] 金额显示统一使用元
2.0.7: 分账完善
- [ ] 支持分账组分账和自己传接收方进行分账
- [ ] DEMO增加获取微信OpenID和支付宝OpenId功能
- [ ] 分账接收方管理提供接口调用
- [ ] 分账情况查询, 分账结果/剩余可分账金额
- [ ] 分账回调处理
- [ ] 分账组管理提供接口调用
- [ ] 对账回退及退款
- [ ] 分账通知
2.0.x 版本内容
- [ ] 对账回退及退款
- [ ] 统计报表功能
- [ ] 微信新增V3版本接口
- [ ] 付款码支付自动路由到V2接口

View File

@@ -10,7 +10,6 @@ import cn.bootx.platform.daxpay.param.pay.allocation.AllocationFinishParam;
import cn.bootx.platform.daxpay.param.pay.allocation.AllocationResetParam;
import cn.bootx.platform.daxpay.service.core.order.allocation.service.AllocationOrderService;
import cn.bootx.platform.daxpay.service.core.payment.allocation.service.AllocationService;
import cn.bootx.platform.daxpay.service.core.payment.allocation.service.AllocationSyncService;
import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDetailDto;
import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDto;
import cn.bootx.platform.daxpay.service.param.order.AllocationOrderQuery;
@@ -37,7 +36,6 @@ public class AllocationOrderController {
private final AllocationOrderService allocationOrderService;
private final AllocationSyncService allocationSyncService;
private final AllocationService allocationService;
@Operation(summary = "分页")
@@ -76,7 +74,7 @@ public class AllocationOrderController {
public ResResult<Void> sync(Long id){
AllocationSyncParam param = new AllocationSyncParam();
param.setAllocationId(id);
allocationSyncService.sync(param);
allocationService.sync(param);
return Res.ok();
}

View File

@@ -0,0 +1,22 @@
package cn.bootx.platform.daxpay.code;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 支付分账明细处理结果
* @author xxm
* @since 2024/4/16
*/
@Getter
@AllArgsConstructor
public enum AllocationDetailResultEnum {
PENDING("pending", "待分账"),
SUCCESS("success", "分账成功"),
FAIL("fail", "分账失败"),
;
private final String code;
private final String name;
}

View File

@@ -0,0 +1,23 @@
package cn.bootx.platform.daxpay.code;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 支付分账订单处理结果
* @author xxm
* @since 2024/4/16
*/
@Getter
@AllArgsConstructor
public enum AllocationOrderResultEnum {
ALL_PENDING("all_pending", "全部成功"),
ALL_SUCCESS("all_success", "全部成功"),
PART_SUCCESS("part_success", "部分成功"),
ALL_FAILED("all_failed", "全部失败"),
;
private final String code;
private final String name;
}

View File

@@ -0,0 +1,25 @@
package cn.bootx.platform.daxpay.code;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 分账状态枚举
* @author xxm
* @since 2024/4/7
*/
@Getter
@AllArgsConstructor
public enum AllocationOrderStatusEnum {
ALLOCATION_PROCESSING("allocation_processing", "分账处理中"),
ALLOCATION_END("allocation_end", "分账完成"),
ALLOCATION_FAILED("allocation_failed", "分账失败"),
FINISH("finish", "完结"),
FINISH_FAILED("finish_failed", "完结失败"),
;
final String code;
final String name;
}

View File

@@ -1,29 +0,0 @@
package cn.bootx.platform.daxpay.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;
}

View File

@@ -0,0 +1,20 @@
package cn.bootx.platform.daxpay.code;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 支付订单分账状态
* @author xxm
* @since 2024/4/16
*/
@Getter
@AllArgsConstructor
public enum PayOrderAllocationStatusEnum {
WAITING("waiting", "待分账"),
ALLOCATION("allocation", "已分账"),
;
final String code;
final String name;
}

View File

@@ -1,6 +1,6 @@
package cn.bootx.platform.daxpay.result.pay;
import cn.bootx.platform.daxpay.code.AllocationStatusEnum;
import cn.bootx.platform.daxpay.code.AllocationOrderStatusEnum;
import cn.bootx.platform.daxpay.code.RefundSyncStatusEnum;
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
import cn.bootx.platform.daxpay.result.CommonResult;
@@ -26,7 +26,7 @@ public class SyncResult extends CommonResult {
* 支付网关同步状态
* @see PaySyncStatusEnum
* @see RefundSyncStatusEnum
* @see AllocationStatusEnum
* @see AllocationOrderStatusEnum
*/
@Schema(description = "支付网关同步状态")
private String gatewayStatus = FAIL.getCode();

View File

@@ -0,0 +1,38 @@
package cn.bootx.platform.daxpay.gateway.controller;
import cn.bootx.platform.common.core.annotation.IgnoreAuth;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 网关消息通知
* @author xxm
* @since 2024/4/16
*/
@IgnoreAuth
@Tag(name = "三方支付网关消息通知")
@RestController
@RequestMapping("/gateway/notice")
@RequiredArgsConstructor
public class PayGatewayNoticeController {
@Operation(summary = "支付宝消息通知")
@PostMapping("/alipay")
public String aliPayNotice() {
return "success";
}
@Operation(summary = "微信消息通知")
@PostMapping("/wechat")
public Map<String, Objects> wechatPayNotice() {
return new HashMap<>();
}
}

View File

@@ -105,4 +105,15 @@ public interface AliPayCode {
/** 分账金额超过最大可分账金额 */
String ALLOC_AMOUNT_VALIDATE_ERROR = "ACQ.ALLOC_AMOUNT_VALIDATE_ERROR";
/** 分账 进行中 */
String ALLOC_PROCESSING = "PROCESSING";
/** 分账 成功 */
String ALLOC_SUCCESS = "SUCCESS";
/** 分账 失败 */
String ALLOC_FAIL = "FAIL";
/** 异步分账 */
String ALLOC_ASYNC = "ASYNC";
/** 同步分账 */
String ALLOC_SYNC = "SYNC";
}

View File

@@ -146,4 +146,7 @@ public interface WeChatPayCode {
/** 个人openid */
String PERSONAL_OPENID = "PERSONAL_OPENID";
/** 获取分账订单明细 */
String ALLOC_RECEIVERS = "receivers";
}

View File

@@ -1,10 +1,14 @@
package cn.bootx.platform.daxpay.service.core.channel.alipay.service;
import cn.bootx.platform.common.core.function.CollectorsFunction;
import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
import cn.bootx.platform.daxpay.code.AllocationDetailResultEnum;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.service.code.AliPayCode;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
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.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayResponse;
import com.alipay.api.domain.*;
@@ -17,8 +21,12 @@ import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -40,9 +48,10 @@ public class AliPayAllocationService {
AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel();
model.setOutRequestNo(String.valueOf(allocationOrder.getOrderNo()));
model.setTradeNo(allocationOrder.getGatewayPayOrderNo());
model.setRoyaltyMode("async");
model.setRoyaltyMode(AliPayCode.ALLOC_ASYNC);
// 分账子参数
// 分账子参数 根据Id排序
orderDetails.sort(Comparator.comparing(MpIdEntity::getId));
List<OpenApiRoyaltyDetailInfoPojo> royaltyParameters = orderDetails.stream()
.map(o -> {
OpenApiRoyaltyDetailInfoPojo infoPojo = new OpenApiRoyaltyDetailInfoPojo();
@@ -69,13 +78,14 @@ public class AliPayAllocationService {
AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel();
model.setOutRequestNo(String.valueOf(allocationOrder.getOrderNo()));
model.setTradeNo(allocationOrder.getGatewayPayOrderNo());
model.setRoyaltyMode("async");
model.setRoyaltyMode(AliPayCode.ALLOC_ASYNC);
// 分账完结参数
SettleExtendParams extendParams = new SettleExtendParams();
extendParams.setRoyaltyFinish("true");
model.setExtendParams(extendParams);
// 分账子参数
// 分账子参数 根据Id排序
orderDetails.sort(Comparator.comparing(MpIdEntity::getId));
List<OpenApiRoyaltyDetailInfoPojo> royaltyParameters = orderDetails.stream()
.map(o -> {
OpenApiRoyaltyDetailInfoPojo infoPojo = new OpenApiRoyaltyDetailInfoPojo();
@@ -90,10 +100,10 @@ public class AliPayAllocationService {
}
/**
* 分账状态查询
* 分账状态同步
*/
@SneakyThrows
public void queryStatus(AllocationOrder allocationOrder){
public void sync(AllocationOrder allocationOrder, List<AllocationOrderDetail> allocationOrderDetails){
AlipayTradeOrderSettleQueryModel model = new AlipayTradeOrderSettleQueryModel();
model.setTradeNo(allocationOrder.getGatewayPayOrderNo());
model.setOutRequestNo(allocationOrder.getOrderNo());
@@ -102,22 +112,23 @@ public class AliPayAllocationService {
AlipayTradeOrderSettleQueryResponse response = AliPayApi.execute(request);
// 验证
this.verifyErrorMsg(response);
Map<String, AllocationOrderDetail> detailMap = allocationOrderDetails.stream()
.collect(Collectors.toMap(AllocationOrderDetail::getReceiverAccount, Function.identity(), CollectorsFunction::retainLatest));
List<RoyaltyDetail> royaltyDetailList = response.getRoyaltyDetailList();
// 转换成通用的明细详情
for (RoyaltyDetail royaltyDetail : royaltyDetailList) {
System.out.println(royaltyDetail);
System.out.println(royaltyDetail.getState());
System.out.println(royaltyDetail.getDetailId());
for (RoyaltyDetail receiver : royaltyDetailList) {
AllocationOrderDetail detail = detailMap.get(receiver.getTransIn());
if (Objects.nonNull(detail)) {
detail.setResult(this.getDetailResultEnum(receiver.getState()).getCode());
detail.setErrorCode(receiver.getErrorCode());
detail.setErrorMsg(receiver.getErrorDesc());
// 如果是完成, 更新时间
if (AllocationDetailResultEnum.SUCCESS.getCode().equals(detail.getResult())){
LocalDateTime finishTime = LocalDateTimeUtil.of(receiver.getExecuteDt());
detail.setFinishTime(finishTime);
}
}
}
/**
* 分账剩余金额查询
*/
public void queryAmount(AllocationOrder allocationOrder){
}
/**
@@ -129,8 +140,24 @@ public class AliPayAllocationService {
if (StrUtil.isBlank(errorMsg)) {
errorMsg = alipayResponse.getMsg();
}
log.error("分账接收方处理失败 {}", errorMsg);
log.error("分账处理失败 {}", errorMsg);
throw new PayFailureException(errorMsg);
}
}
/**
* 转换支付宝分账类型到系统中统一的
*/
private AllocationDetailResultEnum getDetailResultEnum (String result){
// 进行中
if(Objects.equals(AliPayCode.ALLOC_PROCESSING, result)){
return AllocationDetailResultEnum.PENDING;
}
// 成功
if(Objects.equals(AliPayCode.ALLOC_SUCCESS, result)){
return AllocationDetailResultEnum.SUCCESS;
}
// 失败
return AllocationDetailResultEnum.FAIL;
}
}

View File

@@ -38,7 +38,7 @@ public class WeChatPayAllocationReceiverService {
public boolean validation(AllocationReceiver allocationReceiver){
List<String> list = Arrays.asList(WX_MERCHANT.getCode(), WX_MERCHANT.getCode());
String receiverType = allocationReceiver.getReceiverType();
return !list.contains(receiverType);
return list.contains(receiverType);
}
/**

View File

@@ -1,12 +1,19 @@
package cn.bootx.platform.daxpay.service.core.channel.wechat.service;
import cn.bootx.platform.common.core.function.CollectorsFunction;
import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
import cn.bootx.platform.daxpay.code.AllocationDetailResultEnum;
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.bootx.platform.daxpay.service.dto.channel.wechat.WeChatPayAllocationReceiver;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
@@ -21,8 +28,12 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -45,6 +56,7 @@ public class WeChatPayAllocationService {
description = "分账";
}
String finalDescription = description;
orderDetails.sort(Comparator.comparing(MpIdEntity::getId));
List<ReceiverModel> list = orderDetails.stream().map(o->{
AllocationReceiverTypeEnum receiverTypeEnum = AllocationReceiverTypeEnum.findByCode(o.getReceiverType());
return ReceiverModel.builder()
@@ -75,7 +87,7 @@ public class WeChatPayAllocationService {
/**
* 完成分账
*/
public void finish(AllocationOrder allocationOrder, List<AllocationOrderDetail> allocationOrderDetails, WeChatPayConfig config){
public void finish(AllocationOrder allocationOrder, WeChatPayConfig config){
Map<String, String> params = ProfitSharingModel.builder()
.mch_id(config.getWxMchId())
.appid(config.getWxAppId())
@@ -94,9 +106,9 @@ public class WeChatPayAllocationService {
}
/**
* 查询分账状态
* 同步分账状态
*/
public void queryStatus(AllocationOrder allocationOrder, WeChatPayConfig config){
public void sync(AllocationOrder allocationOrder, List<AllocationOrderDetail> allocationOrderDetails, WeChatPayConfig config){
// 不要传输AppId参数, 否则会失败
Map<String, String> params = ProfitSharingModel.builder()
.mch_id(config.getWxMchId())
@@ -108,7 +120,23 @@ public class WeChatPayAllocationService {
String xmlResult = WxPayApi.profitSharingQuery(params);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
this.verifyErrorMsg(result);
JSONUtil.parse(result.get("receivers"));
String json = result.get(WeChatPayCode.ALLOC_RECEIVERS);
List<WeChatPayAllocationReceiver> receivers = JSONUtil.toBean(json, new TypeReference<List<WeChatPayAllocationReceiver>>() {}, false);
Map<String, AllocationOrderDetail> detailMap = allocationOrderDetails.stream()
.collect(Collectors.toMap(AllocationOrderDetail::getReceiverAccount, Function.identity(), CollectorsFunction::retainLatest));
// 根据明细更新订单明细内容
for (WeChatPayAllocationReceiver receiver : receivers) {
AllocationOrderDetail detail = detailMap.get(receiver.getAccount());
if (Objects.nonNull(detail)){
detail.setResult(this.getDetailResultEnum(receiver.getResult()).getCode());
detail.setErrorMsg(receiver.getFailReason());
// 如果是完成, 更新时间
if (AllocationDetailResultEnum.SUCCESS.getCode().equals(detail.getResult())){
LocalDateTime finishTime = LocalDateTimeUtil.parse(receiver.getFinishTime(), DatePattern.PURE_DATETIME_PATTERN);
detail.setFinishTime(finishTime);
}
}
}
}
@@ -127,4 +155,20 @@ public class WeChatPayAllocationService {
throw new PayFailureException(errorMsg);
}
}
/**
* 转换微信分账类型到系统中统一的
*/
private AllocationDetailResultEnum getDetailResultEnum (String result){
// 进行中
if(Objects.equals("PENDING", result)){
return AllocationDetailResultEnum.PENDING;
}
// 成功
if(Objects.equals("SUCCESS", result)){
return AllocationDetailResultEnum.SUCCESS;
}
// 失败
return AllocationDetailResultEnum.FAIL;
}
}

View File

@@ -2,7 +2,8 @@ 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.AllocationStatusEnum;
import cn.bootx.platform.daxpay.code.AllocationOrderResultEnum;
import cn.bootx.platform.daxpay.code.AllocationOrderStatusEnum;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.service.core.order.allocation.convert.AllocationConvert;
import cn.bootx.platform.daxpay.service.dto.order.allocation.AllocationOrderDto;
@@ -18,8 +19,6 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* 分账订单
* @author xxm
@@ -91,11 +90,18 @@ public class AllocationOrder extends MpBaseEntity implements EntityBaseFunction<
/**
* 状态
* @see AllocationStatusEnum
* @see AllocationOrderStatusEnum
*/
@DbColumn(comment = "状态")
private String status;
/**
* 分账处理结果
* @see AllocationOrderResultEnum
*/
@DbColumn(comment = "分账处理结果")
private String result;
/**
* 错误原因
*/
@@ -103,12 +109,6 @@ public class AllocationOrder extends MpBaseEntity implements EntityBaseFunction<
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private String errorMsg;
/**
* 完成时间
*/
@DbColumn(comment = "完成时间")
private LocalDateTime finishTime;
/**
* 转换
*/

View File

@@ -3,6 +3,7 @@ package cn.bootx.platform.daxpay.service.core.order.allocation.entity;
import cn.bootx.platform.common.core.annotation.EncryptionField;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.daxpay.code.AllocationDetailResultEnum;
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;
@@ -13,6 +14,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* 分账订单明细
* @author xxm
@@ -57,9 +60,12 @@ public class AllocationOrderDetail extends MpBaseEntity implements EntityBaseFun
@DbColumn(comment = "接收方姓名")
private String receiverName;
/** 状态 */
@DbColumn(comment = "状态")
private String status;
/**
* 分账结果
* @see AllocationDetailResultEnum
*/
@DbColumn(comment = "分账结果")
private String result;
/** 错误代码 */
@DbColumn(comment = "错误代码")
@@ -69,6 +75,10 @@ public class AllocationOrderDetail extends MpBaseEntity implements EntityBaseFun
@DbColumn(comment = "错误原因")
private String errorMsg;
/** 分账完成时间 */
@DbColumn(comment = "分账完成时间")
private LocalDateTime finishTime;
/**
* 转换
*/

View File

@@ -6,14 +6,17 @@ import cn.bootx.platform.common.core.rest.dto.LabelValue;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.core.util.ResultConvertUtil;
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
import cn.bootx.platform.daxpay.code.AllocationDetailResultEnum;
import cn.bootx.platform.daxpay.code.AllocationOrderStatusEnum;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayOrderAllocationStatusEnum;
import cn.bootx.platform.daxpay.param.pay.allocation.AllocationStartParam;
import cn.bootx.platform.daxpay.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.dao.PayOrderManager;
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.dto.order.allocation.AllocationOrderDetailDto;
@@ -43,6 +46,8 @@ public class AllocationOrderService {
private final AllocationOrderManager allocationOrderManager;
private final AllocationOrderDetailManager allocationOrderDetailManager;
private final PayOrderManager payOrderManager;
/**
* 获取可以分账的通道
@@ -106,8 +111,8 @@ public class AllocationOrderService {
AllocationOrderDetail detail = new AllocationOrderDetail();
detail.setAllocationId(orderId)
.setReceiverId(o.getId())
.setStatus(AllocationStatusEnum.WAITING.getCode())
.setAmount(amount)
.setResult(AllocationDetailResultEnum.PENDING.getCode())
.setRate(rate)
.setReceiverType(o.getReceiverType())
.setReceiverName(o.getReceiverName())
@@ -128,10 +133,12 @@ public class AllocationOrderService {
.setGatewayPayOrderNo(payOrder.getGatewayOrderNo())
.setOrderNo(String.valueOf(orderId))
.setDescription(param.getDescription())
.setStatus(AllocationStatusEnum.WAITING.getCode())
.setStatus(AllocationOrderStatusEnum.ALLOCATION_PROCESSING.getCode())
.setAmount(sumAmount);
allocationOrder.setId(orderId);
// 保存
// 更新支付订单分账状态
payOrder.setAllocationStatus(PayOrderAllocationStatusEnum.ALLOCATION.getCode());
payOrderManager.updateById(payOrder);
// 因为加密后字段值会发生变更, 所以在保存前备份一下
List<AllocationOrderDetail> detailsBack = details.stream()
.map(o -> {

View File

@@ -1,6 +1,7 @@
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.pay.PayChannelParam;
import cn.bootx.platform.daxpay.param.pay.PayParam;
@@ -52,7 +53,7 @@ public class PayBuilder {
.filter(PayChannelEnum.ASYNC_TYPE_CODE::contains)
.findFirst();
// 构建支付订单对象
return new PayOrder()
PayOrder payOrder = new PayOrder()
.setBusinessNo(payParam.getBusinessNo())
.setTitle(payParam.getTitle())
.setStatus(PayStatusEnum.PROGRESS.getCode())
@@ -62,6 +63,11 @@ public class PayBuilder {
.setCombinationPay(payParam.getPayChannels().size() > 1)
.setAsyncPay(asyncPay.isPresent())
.setRefundableBalance(sumAmount);
// 设置分账状态
if (payOrder.isAllocation()) {
payOrder.setAllocationStatus(PayOrderAllocationStatusEnum.WAITING.getCode());
}
return payOrder;
}
/**

View File

@@ -2,9 +2,9 @@ package cn.bootx.platform.daxpay.service.core.order.pay.entity;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.daxpay.code.PayOrderAllocationStatusEnum;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.AllocationStatusEnum;
import cn.bootx.platform.daxpay.service.core.order.pay.convert.PayOrderConvert;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto;
import cn.bootx.table.modify.annotation.DbColumn;
@@ -83,7 +83,7 @@ public class PayOrder extends MpBaseEntity implements EntityBaseFunction<PayOrde
/**
* 分账状态
* @see AllocationStatusEnum
* @see PayOrderAllocationStatusEnum
*/
@DbColumn(comment = "分账状态")
private String allocationStatus;

View File

@@ -1,39 +0,0 @@
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.core.payment.sync.strategy.allocation.AliPayAllocationSyncStrategy;
import cn.bootx.platform.daxpay.service.core.payment.sync.strategy.allocation.WechatPayAllocationSyncStrategy;
import cn.bootx.platform.daxpay.service.func.AbsAllocationSyncStrategy;
import cn.hutool.extra.spring.SpringUtil;
import lombok.experimental.UtilityClass;
/**
* 分账同步策略工厂
* @author xxm
* @since 2024/4/12
*/
@UtilityClass
public class AllocationSyncFactory {
/**
* 根据传入的支付通道创建策略
* @return 支付策略
*/
public static AbsAllocationSyncStrategy create(String channel) {
PayChannelEnum channelEnum = PayChannelEnum.findByCode(channel);
AbsAllocationSyncStrategy strategy;
switch (channelEnum) {
case ALI:
strategy = SpringUtil.getBean(AliPayAllocationSyncStrategy.class);
break;
case WECHAT:
strategy = SpringUtil.getBean(WechatPayAllocationSyncStrategy.class);
break;
default:
throw new PayUnsupportedMethodException();
}
return strategy;
}
}

View File

@@ -1,8 +1,12 @@
package cn.bootx.platform.daxpay.service.core.payment.allocation.service;
import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.daxpay.code.AllocationStatusEnum;
import cn.bootx.platform.daxpay.code.AllocationDetailResultEnum;
import cn.bootx.platform.daxpay.code.AllocationOrderResultEnum;
import cn.bootx.platform.daxpay.code.AllocationOrderStatusEnum;
import cn.bootx.platform.daxpay.code.PayOrderAllocationStatusEnum;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.pay.AllocationSyncParam;
import cn.bootx.platform.daxpay.param.pay.allocation.AllocationFinishParam;
import cn.bootx.platform.daxpay.param.pay.allocation.AllocationResetParam;
import cn.bootx.platform.daxpay.param.pay.allocation.AllocationStartParam;
@@ -27,7 +31,10 @@ import cn.hutool.core.util.StrUtil;
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.Arrays;
import java.util.List;
import java.util.Objects;
@@ -73,6 +80,7 @@ public class AllocationService {
} else {
allocationGroup = groupManager.findDefaultGroup(payOrder.getAsyncChannel()).orElseThrow(() -> new DataNotExistException("未查询到默认分账组"));
}
List<AllocationGroupReceiverResult> receiversByGroups = allocationGroupService.findReceiversByGroups(allocationGroup.getId());
// 创建分账单和明细并保存, 同时更新支付订单状态 使用事务
@@ -90,11 +98,11 @@ public class AllocationService {
// 分账处理
allocationStrategy.allocation();
// 执行中
order.setStatus(AllocationStatusEnum.PARTIAL_PROCESSING.getCode())
order.setStatus(AllocationOrderStatusEnum.ALLOCATION_PROCESSING.getCode())
.setErrorMsg(null);
} catch (Exception e) {
// 失败
order.setStatus(AllocationStatusEnum.PARTIAL_FAILED.getCode())
order.setStatus(AllocationOrderStatusEnum.ALLOCATION_FAILED.getCode())
.setErrorMsg(e.getMessage());
}
// 网关分账号
@@ -121,6 +129,14 @@ public class AllocationService {
allocationOrder = allocationOrderManager.findByAllocationNo(param.getAllocationNo())
.orElseThrow(() -> new DataNotExistException("未查询到分账单信息"));
}
// 需要是分账中分账中或者完成状态才能重新分账
List<String> list = Arrays.asList(AllocationOrderStatusEnum.ALLOCATION_END.getCode(),
AllocationOrderStatusEnum.ALLOCATION_FAILED.getCode(),
AllocationOrderStatusEnum.ALLOCATION_PROCESSING.getCode());
if (!list.contains(allocationOrder.getStatus())){
throw new PayFailureException("分账单状态错误");
}
List<AllocationOrderDetail> details = allocationOrderDetailManager.findAllByOrderId(allocationOrder.getId());
// 创建分账策略并初始化
@@ -132,9 +148,15 @@ public class AllocationService {
try {
// 重复分账处理
allocationStrategy.allocation();
allocationOrder.setStatus(AllocationOrderStatusEnum.ALLOCATION_PROCESSING.getCode())
.setErrorMsg(null);
} catch (Exception e) {
// 失败
allocationOrder.setStatus(AllocationOrderStatusEnum.ALLOCATION_FAILED.getCode())
.setErrorMsg(e.getMessage());
}
allocationOrderManager.updateById(allocationOrder);
}
/**
@@ -149,8 +171,12 @@ public class AllocationService {
allocationOrder = allocationOrderManager.findByAllocationNo(param.getAllocationNo())
.orElseThrow(() -> new DataNotExistException("未查询到分账单信息"));
}
List<AllocationOrderDetail> details = allocationOrderDetailManager.findAllByOrderId(allocationOrder.getId());
// 只有分账结束后才可以完结
if (!AllocationOrderStatusEnum.ALLOCATION_END.getCode().equals(allocationOrder.getStatus())){
throw new PayFailureException("分账单状态错误");
}
List<AllocationOrderDetail> details = allocationOrderDetailManager.findAllByOrderId(allocationOrder.getId());
// 创建分账策略并初始化
AbsAllocationStrategy allocationStrategy = AllocationFactory.create(allocationOrder.getChannel());
allocationStrategy.initParam(allocationOrder, details);
@@ -158,20 +184,90 @@ public class AllocationService {
// 分账完结预处理
allocationStrategy.doBeforeHandler();
try {
// 分账处理
// 完结处理
allocationStrategy.finish();
// 执行中
allocationOrder.setStatus(AllocationStatusEnum.FINISH_PROCESSING.getCode())
// 完结状态
allocationOrder.setStatus(AllocationOrderStatusEnum.FINISH.getCode())
.setErrorMsg(null);
} catch (Exception e) {
// 失败
allocationOrder.setStatus(AllocationStatusEnum.FINISH_FAILED.getCode())
allocationOrder.setStatus(AllocationOrderStatusEnum.FINISH_FAILED.getCode())
.setErrorMsg(e.getMessage());
}
allocationOrderManager.updateById(allocationOrder);
}
/**
* 分账同步, 开启一个新的事务, 不受外部抛出异常的影响
*/
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void sync(AllocationSyncParam param) {
// 获取分账订单
AllocationOrder allocationOrder = null;
if (Objects.nonNull(param.getAllocationId())){
allocationOrder = allocationOrderManager.findById(param.getAllocationId())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
if (Objects.isNull(allocationOrder)){
allocationOrder = allocationOrderManager.findByAllocationNo(param.getAllocationNo())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
List<AllocationOrderDetail> detailList = allocationOrderDetailManager.findAllByOrderId(allocationOrder.getId());
// 获取分账策略
AbsAllocationStrategy allocationStrategy = AllocationFactory.create(allocationOrder.getChannel());
allocationStrategy.initParam(allocationOrder, detailList);
// 分账完结预处理
allocationStrategy.doBeforeHandler();
allocationStrategy.doSync();
// 根据订单明细更新订单的状态和处理结果
this.updateOrderStatus(allocationOrder, detailList);
allocationOrderDetailManager.updateAllById(detailList);
allocationOrderManager.updateById(allocationOrder);
}
/**
* 根据订单明细更新订单的状态和处理结果, 如果订单是分账结束或失败, 不更新状态
*/
private void updateOrderStatus(AllocationOrder allocationOrder, List<AllocationOrderDetail> details){
// 如果是分账结束或失败, 不更新状态
String status = allocationOrder.getStatus();
// 判断明细状态. 获取成功和失败的
long successCount = details.stream()
.map(AllocationOrderDetail::getResult)
.filter(AllocationDetailResultEnum.SUCCESS.getCode()::equals)
.count();
long failCount = details.stream()
.map(AllocationOrderDetail::getResult)
.filter(AllocationDetailResultEnum.FAIL.getCode()::equals)
.count();
// 成功和失败都为0 进行中
if (successCount == 0 && failCount == 0){
allocationOrder.setStatus(AllocationOrderStatusEnum.ALLOCATION_PROCESSING.getCode())
.setResult(AllocationOrderResultEnum.ALL_PENDING.getCode());
} else if (failCount == details.size()){
// 全部失败
allocationOrder.setStatus(AllocationOrderStatusEnum.ALLOCATION_END.getCode())
.setResult(AllocationOrderResultEnum.ALL_FAILED.getCode());
} else if (successCount == details.size()){
// 全部成功
allocationOrder.setStatus(AllocationOrderStatusEnum.ALLOCATION_END.getCode())
.setResult(AllocationOrderResultEnum.ALL_SUCCESS.getCode());
} else {
// 部分成功
allocationOrder.setStatus(AllocationOrderStatusEnum.ALLOCATION_END.getCode())
.setResult(AllocationOrderResultEnum.PART_SUCCESS.getCode());
}
// 如果是分账结束或失败, 状态复原
List<String> list = Arrays.asList(AllocationOrderStatusEnum.FINISH.getCode(), AllocationOrderStatusEnum.FINISH_FAILED.getCode());
if (list.contains(status)){
allocationOrder.setStatus(AllocationOrderStatusEnum.FINISH.getCode())
.setResult(AllocationOrderResultEnum.ALL_SUCCESS.getCode());
}
}
/**
* 获取并检查支付订单
*/
@@ -191,11 +287,9 @@ public class AllocationService {
throw new PayFailureException("该订单不允许分账");
}
// 判断分账状态
if (Objects.equals(AllocationStatusEnum.FINISH_SUCCESS.getCode(), payOrder.getAllocationStatus())){
if (Objects.equals(PayOrderAllocationStatusEnum.ALLOCATION.getCode(), payOrder.getAllocationStatus())){
throw new PayFailureException("该订单已分账完成");
}
return payOrder;
}
}

View File

@@ -1,50 +0,0 @@
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.AllocationSyncParam;
import cn.bootx.platform.daxpay.result.pay.SyncResult;
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.payment.allocation.factory.AllocationSyncFactory;
import cn.bootx.platform.daxpay.service.func.AbsAllocationSyncStrategy;
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.Objects;
/**
* 分账状态同步
* @author xxm
* @since 2024/4/12
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AllocationSyncService {
private final AllocationOrderManager allocationOrderManager;
/**
* 支付同步, 开启一个新的事务, 不受外部抛出异常的影响
*/
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public SyncResult sync(AllocationSyncParam param) {
// 获取分账订单
AllocationOrder allocationOrder = null;
if (Objects.nonNull(param.getAllocationId())){
allocationOrder = allocationOrderManager.findById(param.getAllocationId())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
if (Objects.isNull(allocationOrder)){
allocationOrder = allocationOrderManager.findByAllocationNo(param.getAllocationNo())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
// 获取分账策略
AbsAllocationSyncStrategy allocationSyncStrategy = AllocationSyncFactory.create(allocationOrder.getChannel());
allocationSyncStrategy.initPayParam(allocationOrder);
allocationSyncStrategy.doSyncStatus();
return new SyncResult();
}
}

View File

@@ -70,4 +70,12 @@ public class AliPayAllocationStrategy extends AbsAllocationStrategy {
aliPayAllocationService.finish(this.getAllocationOrder(), this.getAllocationOrderDetails());
}
/**
* 同步状态
*/
@Override
public void doSync() {
aliPayAllocationService.sync(this.getAllocationOrder(), this.getAllocationOrderDetails());
}
}

View File

@@ -65,8 +65,15 @@ public class WeChatPayAllocationStrategy extends AbsAllocationStrategy {
*/
@Override
public void finish() {
weChatPayAllocationService.finish(getAllocationOrder(), this.getAllocationOrderDetails(), weChatPayConfig);
weChatPayAllocationService.finish(getAllocationOrder(), weChatPayConfig);
}
/**
* 同步状态
*/
@Override
public void doSync() {
weChatPayAllocationService.sync(this.getAllocationOrder(),this.getAllocationOrderDetails(),weChatPayConfig);
}
}

View File

@@ -7,7 +7,6 @@ import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.param.pay.PayParam;
import cn.bootx.platform.daxpay.param.pay.SimplePayParam;
import cn.bootx.platform.daxpay.result.pay.PayResult;
import cn.bootx.platform.daxpay.code.AllocationStatusEnum;
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;
@@ -271,10 +270,6 @@ public class PayService {
payOrderExtraManager.update(payOrderExtra);
// 如果支付完成 发送通知
if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){
// 如果是是允许分账的订单, 设置为待分装
if (payOrder.isAllocation()){
payOrder.setAllocationStatus(AllocationStatusEnum.WAITING.getCode());
}
clientNoticeService.registerPayNotice(payOrder, payOrderExtra, payInfo.getPayChannelOrders());
}
return PayBuilder.buildPayResultByPayOrder(payOrder);
@@ -373,10 +368,6 @@ public class PayService {
payOrderExtraManager.update(payOrderExtra);
// 如果支付完成 发送通知
if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){
// 如果是是允许分账的订单, 设置为待分装
if (payOrder.isAllocation()){
payOrder.setAllocationStatus(AllocationStatusEnum.WAITING.getCode());
}
clientNoticeService.registerPayNotice(payOrder, payOrderExtra, payInfo.getPayChannelOrders());
}
return PayBuilder.buildPayResultByPayOrder(payOrder);

View File

@@ -1,44 +0,0 @@
package cn.bootx.platform.daxpay.service.core.payment.sync.strategy.allocation;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
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.AbsAllocationSyncStrategy;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
* 支付宝分账状态同步策略
* @author xxm
* @since 2024/4/12
*/
@Scope(SCOPE_PROTOTYPE)
@Component
@RequiredArgsConstructor
public class AliPayAllocationSyncStrategy extends AbsAllocationSyncStrategy {
private final AliPayConfigService aliPayConfigService;
private final AliPayAllocationService aliPayAllocationService;
/**
* 策略标识
*/
@Override
public PayChannelEnum getChannel() {
return PayChannelEnum.ALI;
}
/**
* 同步状态
*/
@Override
public void doSyncStatus() {
AliPayConfig aliPayConfig = aliPayConfigService.getAndCheckConfig();
aliPayConfigService.initConfig(aliPayConfig);
aliPayAllocationService.queryStatus(this.getAllocationOrder());
}
}

View File

@@ -1,45 +0,0 @@
package cn.bootx.platform.daxpay.service.core.payment.sync.strategy.allocation;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
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.AbsAllocationSyncStrategy;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
* 微信分账状态同步策略
* @author xxm
* @since 2024/4/12
*/
@Scope(SCOPE_PROTOTYPE)
@Component
@RequiredArgsConstructor
public class WechatPayAllocationSyncStrategy extends AbsAllocationSyncStrategy {
private final WeChatPayAllocationService weChatPayAllocationService;
private final WeChatPayConfigService weChatPayConfigService;
/**
* 同步状态
*/
@Override
public void doSyncStatus() {
WeChatPayConfig wechatPayConfig = weChatPayConfigService.getAndCheckConfig();
weChatPayAllocationService.queryStatus(this.getAllocationOrder(),wechatPayConfig);
}
/**
* 策略标识
*/
@Override
public PayChannelEnum getChannel() {
return PayChannelEnum.WECHAT;
}
}

View File

@@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.service.dto.allocation;
import cn.bootx.platform.daxpay.code.AllocationReceiverTypeEnum;
import cn.bootx.platform.daxpay.code.AllocationRelationTypeEnum;
import cn.bootx.platform.starter.data.perm.sensitive.SensitiveInfo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -37,6 +38,7 @@ public class AllocationGroupReceiverResult {
@Schema(description = "接收方账号")
@SensitiveInfo
private String receiverAccount;
/** 接收方姓名 */

View File

@@ -0,0 +1,63 @@
package cn.bootx.platform.daxpay.service.dto.channel.wechat;
import cn.bootx.platform.daxpay.code.AllocationReceiverTypeEnum;
import cn.hutool.core.annotation.Alias;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 微信分账单状态
* @author xxm
* @since 2024/4/16
*/
@Data
@Accessors(chain = true)
public class WeChatPayAllocationReceiver {
/** 分账金额 */
private Integer amount;
/** 分账描述 */
private String description;
/**
* 分账接收方类型
* @see AllocationReceiverTypeEnum
*/
private String type;
/**
* 分账接收方账号
*/
private String account;
/**
* 分账结果
*/
private String result;
/**
* 分账完成时间 yyyyMMddHHmmss
*/
@Alias("finish_time")
@JsonProperty("finish_time")
private String finishTime;
/**
* 分账失败原因
*/
@Alias("fail_reason")
@JsonProperty("fail_reason")
private String failReason;
/**
* 分账明细单号
*/
@Alias("detail_id")
@JsonProperty("detail_id")
private String detailId;
}

View File

@@ -1,6 +1,7 @@
package cn.bootx.platform.daxpay.service.dto.order.allocation;
import cn.bootx.platform.common.core.rest.dto.BaseDto;
import cn.bootx.platform.daxpay.code.AllocationDetailResultEnum;
import cn.bootx.platform.daxpay.code.AllocationReceiverTypeEnum;
import cn.bootx.platform.starter.data.perm.sensitive.SensitiveInfo;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -8,6 +9,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* 分账订单详情
* @author xxm
@@ -52,7 +55,23 @@ public class AllocationOrderDetailDto extends BaseDto {
@Schema(description = "接收方姓名")
private String receiverName;
/** 状态 */
@Schema(description = "状态")
private String status;
/**
* 分账结果
* @see AllocationDetailResultEnum
*/
@Schema(description = "分账结果")
private String result;
/** 错误代码 */
@Schema(description = "错误代码")
private String errorCode;
/** 错误原因 */
@Schema(description = "错误原因")
private String errorMsg;
/** 分账完成时间 */
@Schema(description = "分账完成时间")
private LocalDateTime finishTime;
}

View File

@@ -1,16 +1,13 @@
package cn.bootx.platform.daxpay.service.dto.order.allocation;
import cn.bootx.platform.common.core.rest.dto.BaseDto;
import cn.bootx.platform.daxpay.code.AllocationStatusEnum;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;
import cn.bootx.platform.daxpay.code.AllocationOrderResultEnum;
import cn.bootx.platform.daxpay.code.AllocationOrderStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* 分账订单
* @author xxm
@@ -78,22 +75,21 @@ public class AllocationOrderDto extends BaseDto {
/**
* 状态
* @see AllocationStatusEnum
* @see AllocationOrderStatusEnum
*/
@Schema(description = "状态")
private String status;
/**
* 分账处理结果
* @see AllocationOrderResultEnum
*/
@Schema(description = "分账处理结果")
private String result;
/**
* 错误原因
*/
@Schema(description = "错误原因")
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private String errorMsg;
/**
* 完成时间
*/
@Schema(description = "完成时间")
private LocalDateTime finishTime;
}

View File

@@ -3,7 +3,7 @@ package cn.bootx.platform.daxpay.service.dto.order.pay;
import cn.bootx.platform.common.core.rest.dto.BaseDto;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.AllocationStatusEnum;
import cn.bootx.platform.daxpay.code.AllocationOrderStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -71,7 +71,7 @@ public class PayOrderDto extends BaseDto {
/**
* 分账状态
* @see AllocationStatusEnum
* @see AllocationOrderStatusEnum
*/
@Schema(description = "分账状态")
private String allocationStatus;

View File

@@ -44,4 +44,9 @@ public abstract class AbsAllocationStrategy implements PayStrategy{
* 分账完结
*/
public abstract void finish();
/**
* 同步状态
*/
public abstract void doSync();
}

View File

@@ -1,33 +0,0 @@
package cn.bootx.platform.daxpay.service.func;
import cn.bootx.platform.daxpay.service.core.order.allocation.entity.AllocationOrder;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
/**
* 抽象的分账状态同步策略
* @author xxm
* @since 2024/4/12
*/
@Slf4j
@Getter
@Setter
public abstract class AbsAllocationSyncStrategy implements PayStrategy{
private AllocationOrder allocationOrder;
/**
* 初始化参数
*/
public void initPayParam(AllocationOrder allocationOrder) {
this.allocationOrder = allocationOrder;
}
/**
* 同步状态
*/
public abstract void doSyncStatus();
}

View File

@@ -159,7 +159,7 @@ dax-pay:
# 服务地址
server-url: http://localhost:9000
# 前端h5地址
front-h5-url: http://localhost:5173/#
front-h5-url: http://pay1.bootx.cn/h5/#
# 前端web地址
front-web-url: http://localhost:9000/#
# 演示模块
@@ -167,7 +167,7 @@ dax-pay:
# 网关地址
server-url: http://localhost:9000
# 前端h5地址
front-h5-url: http://localhost:5173/#
front-h5-url: http://pay1.bootx.cn/h5/#
# 签名秘钥
sign-secret: 123456
# 签名方式