mirror of
https://gitee.com/dromara/dax-pay
synced 2026-08-10 23:01:58 +08:00
ref 签名注解和上下文初始化注解改造, 初步实现分账通知功能
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
- [ ] DEMO增加获取微信OpenID和支付宝OpenId功能
|
||||
- [ ] 分账回调处理
|
||||
- [ ] 分账通知发送功能
|
||||
- [ ] 保存分账同步记录
|
||||
- [x] 分账支持手动和自动分账两种
|
||||
- [ ] 金额过小不进行分账, 增加新状态, 金额小于0.01元直接忽略
|
||||
- [ ] 增加收单收银台功能
|
||||
|
||||
@@ -5,9 +5,11 @@ import cn.bootx.platform.common.core.rest.Res;
|
||||
import cn.bootx.platform.common.core.rest.ResResult;
|
||||
import cn.bootx.platform.common.core.rest.dto.LabelValue;
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocStartParam;
|
||||
import cn.daxpay.single.code.PaymentApiCode;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocationParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocSyncParam;
|
||||
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.dto.order.allocation.AllocationOrderDetailDto;
|
||||
@@ -69,6 +71,7 @@ public class AllocationOrderController {
|
||||
return Res.ok(allocationOrderService.findChannels());
|
||||
}
|
||||
|
||||
@PlatformInitContext(PaymentApiCode.SYNC_ALLOCATION)
|
||||
@Operation(summary = "同步分账结果")
|
||||
@PostMapping("/sync")
|
||||
public ResResult<Void> sync(String allocationNo){
|
||||
@@ -78,6 +81,7 @@ public class AllocationOrderController {
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@PlatformInitContext(PaymentApiCode.SYNC_REFUND)
|
||||
@Operation(summary = "分账完结")
|
||||
@PostMapping("/finish")
|
||||
public ResResult<Void> finish(String allocationNo){
|
||||
@@ -87,10 +91,11 @@ public class AllocationOrderController {
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@PlatformInitContext(PaymentApiCode.ALLOCATION)
|
||||
@Operation(summary = "重新发起分账")
|
||||
@PostMapping("/retry")
|
||||
public ResResult<Void> retryAllocation(String bizAllocationNo){
|
||||
AllocStartParam param = new AllocStartParam();
|
||||
AllocationParam param = new AllocationParam();
|
||||
param.setBizAllocationNo(bizAllocationNo);
|
||||
allocationService.allocation(param);
|
||||
return Res.ok();
|
||||
|
||||
@@ -5,7 +5,7 @@ import cn.bootx.platform.common.core.rest.PageResult;
|
||||
import cn.bootx.platform.common.core.rest.Res;
|
||||
import cn.bootx.platform.common.core.rest.ResResult;
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocStartParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocationParam;
|
||||
import cn.daxpay.single.param.payment.pay.PayCloseParam;
|
||||
import cn.daxpay.single.param.payment.pay.PaySyncParam;
|
||||
import cn.daxpay.single.result.pay.SyncResult;
|
||||
@@ -99,7 +99,7 @@ public class PayOrderController {
|
||||
@Operation(summary = "发起分账")
|
||||
@PostMapping("/allocation")
|
||||
public ResResult<Void> allocation(String orderNo){
|
||||
AllocStartParam param = new AllocStartParam();
|
||||
AllocationParam param = new AllocationParam();
|
||||
param.setOrderNo(orderNo);
|
||||
param.setBizAllocationNo(OrderNoGenerateUtil.allocation());
|
||||
allocationService.allocation(param);
|
||||
|
||||
@@ -4,8 +4,10 @@ import cn.bootx.platform.common.core.rest.PageResult;
|
||||
import cn.bootx.platform.common.core.rest.Res;
|
||||
import cn.bootx.platform.common.core.rest.ResResult;
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.daxpay.single.code.PaymentApiCode;
|
||||
import cn.daxpay.single.param.payment.refund.RefundSyncParam;
|
||||
import cn.daxpay.single.result.pay.SyncResult;
|
||||
import cn.daxpay.single.service.annotation.PlatformInitContext;
|
||||
import cn.daxpay.single.service.core.order.refund.service.RefundOrderQueryService;
|
||||
import cn.daxpay.single.service.core.order.refund.service.RefundOrderService;
|
||||
import cn.daxpay.single.service.core.payment.sync.service.RefundSyncService;
|
||||
@@ -63,6 +65,7 @@ public class RefundOrderController {
|
||||
return Res.ok(queryService.findExtraById(id));
|
||||
}
|
||||
|
||||
@PlatformInitContext(PaymentApiCode.REFUND)
|
||||
@Operation(summary = "手动发起退款")
|
||||
@PostMapping("/refund")
|
||||
public ResResult<Void> refund(@RequestBody PayOrderRefundParam param){
|
||||
@@ -70,6 +73,7 @@ public class RefundOrderController {
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@PlatformInitContext(PaymentApiCode.REFUND)
|
||||
@Operation(summary = "重新发起退款")
|
||||
@PostMapping("/resetRefund")
|
||||
public ResResult<Void> resetRefund(Long id){
|
||||
|
||||
@@ -4,7 +4,7 @@ import cn.bootx.platform.common.core.rest.PageResult;
|
||||
import cn.bootx.platform.common.core.rest.Res;
|
||||
import cn.bootx.platform.common.core.rest.ResResult;
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.daxpay.single.service.core.task.notice.service.ClientNoticeTaskService;
|
||||
import cn.daxpay.single.service.core.notice.service.ClientNoticeTaskService;
|
||||
import cn.daxpay.single.service.dto.record.notice.ClientNoticeRecordDto;
|
||||
import cn.daxpay.single.service.dto.record.notice.ClientNoticeTaskDto;
|
||||
import cn.daxpay.single.service.param.record.ClientNoticeRecordQuery;
|
||||
|
||||
@@ -15,8 +15,8 @@ import java.util.List;
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Schema(title = "开始分账请求参数")
|
||||
public class AllocStartParam extends PaymentCommonParam {
|
||||
@Schema(title = "分账请求参数")
|
||||
public class AllocationParam extends PaymentCommonParam {
|
||||
|
||||
/** 商户分账单号 */
|
||||
@Schema(description = "商户分账单号")
|
||||
@@ -45,4 +45,12 @@ public class AllocStartParam extends PaymentCommonParam {
|
||||
@Schema(description = "分账接收方列表")
|
||||
private List<AllocReceiverParam> receivers;
|
||||
|
||||
/** 回调通知地址 */
|
||||
@Schema(description = "回调通知地址")
|
||||
private String notifyUrl;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
@Schema(description = "商户扩展参数,回调时会原样返回")
|
||||
private String attach;
|
||||
|
||||
}
|
||||
@@ -26,31 +26,31 @@ public class AllocOrderResult extends PaymentCommonResult {
|
||||
/**
|
||||
* 分账单号
|
||||
*/
|
||||
@Schema(description = "分账单号")
|
||||
@Schema(description = "分账单号")
|
||||
private String allocationNo;
|
||||
|
||||
/**
|
||||
* 商户分账单号
|
||||
*/
|
||||
@Schema(description = "商户分账单号")
|
||||
@Schema(description = "商户分账单号")
|
||||
private String bizAllocationNo;
|
||||
|
||||
/**
|
||||
* 通道分账号
|
||||
*/
|
||||
@Schema(description = "通道分账号")
|
||||
@Schema(description = "通道分账号")
|
||||
private String outAllocationNo;
|
||||
|
||||
/**
|
||||
* 支付订单号
|
||||
*/
|
||||
@Schema(description = "支付订单号")
|
||||
@Schema(description = "支付订单号")
|
||||
private String orderNo;
|
||||
|
||||
/**
|
||||
* 商户支付订单号
|
||||
*/
|
||||
@Schema(description = "商户支付订单号")
|
||||
@Schema(description = "商户支付订单号")
|
||||
private String bizOrderNo;
|
||||
|
||||
|
||||
@@ -64,53 +64,58 @@ public class AllocOrderResult extends PaymentCommonResult {
|
||||
* 所属通道
|
||||
* @see PayChannelEnum
|
||||
*/
|
||||
@Schema(description = "所属通道")
|
||||
@Schema(description = "所属通道")
|
||||
private String channel;
|
||||
|
||||
/**
|
||||
* 总分账金额
|
||||
*/
|
||||
@Schema(description = "总分账金额")
|
||||
@Schema(description = "总分账金额")
|
||||
private Integer amount;
|
||||
|
||||
/**
|
||||
* 分账描述
|
||||
*/
|
||||
@Schema(description = "分账描述")
|
||||
@Schema(description = "分账描述")
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
* @see AllocOrderStatusEnum
|
||||
*/
|
||||
@Schema(description = "状态")
|
||||
@Schema(description = "状态")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 处理结果
|
||||
* @see AllocOrderResultEnum
|
||||
*/
|
||||
@Schema(description = "处理结果")
|
||||
@Schema(description = "处理结果")
|
||||
private String result;
|
||||
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
@Schema(description = "错误码")
|
||||
@Schema(description = "错误码")
|
||||
private String errorCode;
|
||||
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
@Schema(description = "错误原因")
|
||||
@Schema(description = "错误原因")
|
||||
private String errorMsg;
|
||||
|
||||
/** 分账订单完成时间 */
|
||||
@Schema(description = "分账订单完成时间")
|
||||
@Schema(description = "分账订单完成时间")
|
||||
private LocalDateTime finishTime;
|
||||
|
||||
/** 分账明细 */
|
||||
@Schema(description = "分账明细")
|
||||
private List<AllocOrderDetailResult> details;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
@Schema(description = "商户扩展参数,回调时会原样返回")
|
||||
private String attach;
|
||||
|
||||
/** 分账明细 */
|
||||
@Schema(description = "分账明细")
|
||||
private List<AllocOrderDetailResult> details;
|
||||
|
||||
}
|
||||
|
||||
@@ -3,8 +3,12 @@ package cn.daxpay.single.gateway.controller;
|
||||
import cn.daxpay.single.code.PaymentApiCode;
|
||||
import cn.daxpay.single.param.payment.allocation.*;
|
||||
import cn.daxpay.single.result.DaxResult;
|
||||
import cn.daxpay.single.result.allocation.*;
|
||||
import cn.daxpay.single.service.annotation.PaymentApi;
|
||||
import cn.daxpay.single.result.allocation.AllocReceiverAddResult;
|
||||
import cn.daxpay.single.result.allocation.AllocReceiverRemoveResult;
|
||||
import cn.daxpay.single.result.allocation.AllocationResult;
|
||||
import cn.daxpay.single.result.allocation.AllocationSyncResult;
|
||||
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.util.DaxRes;
|
||||
@@ -31,35 +35,40 @@ public class UniAllocationController {
|
||||
|
||||
private final AllocationReceiverService receiverService;
|
||||
|
||||
@PaymentApi(PaymentApiCode.ALLOCATION)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.ALLOCATION)
|
||||
@Operation(summary = "触发分账")
|
||||
@PostMapping("/open")
|
||||
public DaxResult<AllocationResult> open(@RequestBody AllocStartParam param){
|
||||
public DaxResult<AllocationResult> open(@RequestBody AllocationParam param){
|
||||
return DaxRes.ok(allocationService.allocation(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.ALLOCATION_FINISH)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.ALLOCATION_FINISH)
|
||||
@Operation(summary = "分账完结接口")
|
||||
@PostMapping("/finish")
|
||||
public DaxResult<AllocationResult> finish(@RequestBody AllocFinishParam param){
|
||||
return DaxRes.ok(allocationService.finish(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.SYNC_ALLOCATION)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.SYNC_ALLOCATION)
|
||||
@Operation(summary = "分账同步接口")
|
||||
@PostMapping("/sync")
|
||||
public DaxResult<AllocationSyncResult> sync(@RequestBody AllocSyncParam param){
|
||||
return DaxRes.ok(allocationService.sync(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.ALLOCATION_RECEIVER_ADD)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.ALLOCATION_RECEIVER_ADD)
|
||||
@Operation(summary = "添加分账接收方接口")
|
||||
@PostMapping("/receiver/add")
|
||||
public DaxResult<AllocReceiverAddResult> receiverAdd(@RequestBody AllocReceiverAddParam param){
|
||||
return DaxRes.ok(receiverService.addAndSync(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.ALLOCATION_RECEIVER_REMOVE)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.ALLOCATION_RECEIVER_REMOVE)
|
||||
@Operation(summary = "删除分账接收方接口")
|
||||
@PostMapping("/receiver/remove")
|
||||
public DaxResult<AllocReceiverRemoveResult> receiverRemove(@RequestBody AllocReceiverRemoveParam param){
|
||||
|
||||
@@ -9,7 +9,8 @@ import cn.daxpay.single.param.assist.WxAuthUrlParam;
|
||||
import cn.daxpay.single.result.DaxResult;
|
||||
import cn.daxpay.single.result.assist.WxAccessTokenResult;
|
||||
import cn.daxpay.single.result.assist.WxAuthUrlResult;
|
||||
import cn.daxpay.single.service.annotation.PaymentApi;
|
||||
import cn.daxpay.single.service.annotation.PlatformInitContext;
|
||||
import cn.daxpay.single.service.annotation.PaymentSign;
|
||||
import cn.daxpay.single.service.core.payment.assist.service.UniPayAssistService;
|
||||
import cn.daxpay.single.util.DaxRes;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
@@ -33,14 +34,16 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
public class UniPayAssistController {
|
||||
private final UniPayAssistService uniPayAssistService;
|
||||
|
||||
@PaymentApi(PaymentApiCode.GET_WX_AUTH_URL)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.GET_WX_AUTH_URL)
|
||||
@Operation(summary = "获取微信OAuth2授权链接")
|
||||
@PostMapping("/getWxAuthUrl")
|
||||
public DaxResult<WxAuthUrlResult> getWxAuthUrl(@RequestBody WxAuthUrlParam param){
|
||||
return DaxRes.ok(uniPayAssistService.getWxAuthUrl(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.GET_WX_ACCESS_TOKEN)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.GET_WX_ACCESS_TOKEN)
|
||||
@Operation(summary = "获取微信AccessToken")
|
||||
@PostMapping("/getWxAccessToken")
|
||||
public ResResult<WxAccessTokenResult> getWxAccessToken(@RequestBody WxAccessTokenParam param){
|
||||
|
||||
@@ -12,7 +12,8 @@ import cn.daxpay.single.result.pay.PayCloseResult;
|
||||
import cn.daxpay.single.result.pay.PayResult;
|
||||
import cn.daxpay.single.result.pay.RefundResult;
|
||||
import cn.daxpay.single.result.pay.SyncResult;
|
||||
import cn.daxpay.single.service.annotation.PaymentApi;
|
||||
import cn.daxpay.single.service.annotation.PlatformInitContext;
|
||||
import cn.daxpay.single.service.annotation.PaymentSign;
|
||||
import cn.daxpay.single.service.core.payment.close.service.PayCloseService;
|
||||
import cn.daxpay.single.service.core.payment.pay.service.PayService;
|
||||
import cn.daxpay.single.service.core.payment.refund.service.RefundService;
|
||||
@@ -44,36 +45,40 @@ public class UniPayController {
|
||||
private final PayCloseService payCloseService;
|
||||
private final RefundSyncService refundSyncService;
|
||||
|
||||
|
||||
@PaymentApi(PaymentApiCode.PAY)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.PAY)
|
||||
@Operation(summary = "统一支付接口")
|
||||
@PostMapping("/pay")
|
||||
public DaxResult<PayResult> pay(@RequestBody PayParam payParam){
|
||||
return DaxRes.ok(payService.pay(payParam));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.CLOSE)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.CLOSE)
|
||||
@Operation(summary = "支付关闭接口")
|
||||
@PostMapping("/close")
|
||||
public DaxResult<PayCloseResult> close(@RequestBody PayCloseParam param){
|
||||
return DaxRes.ok(payCloseService.close(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.REFUND)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.REFUND)
|
||||
@Operation(summary = "统一退款接口")
|
||||
@PostMapping("/refund")
|
||||
public DaxResult<RefundResult> refund(@RequestBody RefundParam param){
|
||||
return DaxRes.ok(refundService.refund(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.SYNC_PAY)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.SYNC_PAY)
|
||||
@Operation(summary = "支付同步接口")
|
||||
@PostMapping("/syncPay")
|
||||
public DaxResult<SyncResult> syncPay(@RequestBody PaySyncParam param){
|
||||
return DaxRes.ok(paySyncService.sync(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.SYNC_REFUND)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.SYNC_REFUND)
|
||||
@Operation(summary = "退款同步接口")
|
||||
@PostMapping("/syncRefund")
|
||||
public DaxResult<SyncResult> syncRefund(@RequestBody RefundSyncParam param){
|
||||
|
||||
@@ -11,7 +11,8 @@ import cn.daxpay.single.result.allocation.AllocOrderResult;
|
||||
import cn.daxpay.single.result.allocation.AllocReceiversResult;
|
||||
import cn.daxpay.single.result.order.PayOrderResult;
|
||||
import cn.daxpay.single.result.order.RefundOrderResult;
|
||||
import cn.daxpay.single.service.annotation.PaymentApi;
|
||||
import cn.daxpay.single.service.annotation.PlatformInitContext;
|
||||
import cn.daxpay.single.service.annotation.PaymentSign;
|
||||
import cn.daxpay.single.service.core.order.pay.service.PayOrderQueryService;
|
||||
import cn.daxpay.single.service.core.order.refund.service.RefundOrderQueryService;
|
||||
import cn.daxpay.single.service.core.payment.allocation.service.AllocationReceiverService;
|
||||
@@ -42,28 +43,32 @@ public class UniQueryController {
|
||||
private final AllocationReceiverService allocationReceiverService;
|
||||
private final AllocationService allocationService;
|
||||
|
||||
@PaymentApi(PaymentApiCode.QUERY_PAY_ORDER)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.QUERY_PAY_ORDER)
|
||||
@Operation(summary = "支付订单查询接口")
|
||||
@PostMapping("/payOrder")
|
||||
public DaxResult<PayOrderResult> queryPayOrder(@RequestBody QueryPayParam param){
|
||||
return DaxRes.ok(payOrderQueryService.queryPayOrder(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.QUERY_REFUND_ORDER)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.QUERY_REFUND_ORDER)
|
||||
@Operation(summary = "退款订单查询接口")
|
||||
@PostMapping("/refundOrder")
|
||||
public DaxResult<RefundOrderResult> queryRefundOrder(@RequestBody QueryRefundParam param){
|
||||
return DaxRes.ok(refundOrderQueryService.queryRefundOrder(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.QUERY_ALLOCATION_ORDER)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.QUERY_ALLOCATION_ORDER)
|
||||
@Operation(summary = "分账订单查询接口")
|
||||
@PostMapping("/allocationOrder")
|
||||
public DaxResult<AllocOrderResult> queryAllocationOrder(@RequestBody QueryAllocOrderParam param){
|
||||
return DaxRes.ok(allocationService.queryAllocationOrder(param));
|
||||
}
|
||||
|
||||
@PaymentApi(PaymentApiCode.QUERY_ALLOCATION_RECEIVER)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.QUERY_ALLOCATION_RECEIVER)
|
||||
@Operation(summary = "分账接收方查询接口")
|
||||
@PostMapping("/allocReceiver")
|
||||
public DaxResult<AllocReceiversResult> queryAllocReceive(@RequestBody QueryAllocReceiverParam param){
|
||||
|
||||
@@ -3,7 +3,8 @@ package cn.daxpay.single.gateway.controller;
|
||||
import cn.daxpay.single.code.PaymentApiCode;
|
||||
import cn.daxpay.single.param.payment.pay.PayParam;
|
||||
import cn.daxpay.single.result.DaxResult;
|
||||
import cn.daxpay.single.service.annotation.PaymentApi;
|
||||
import cn.daxpay.single.service.annotation.PlatformInitContext;
|
||||
import cn.daxpay.single.service.annotation.PaymentSign;
|
||||
import cn.daxpay.single.util.DaxRes;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@@ -24,7 +25,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RequiredArgsConstructor
|
||||
public class UniReconcileController {
|
||||
|
||||
@PaymentApi(PaymentApiCode.PAY)
|
||||
@PaymentSign
|
||||
@PlatformInitContext(PaymentApiCode.PAY)
|
||||
@Operation(summary = "下载指定日期的资金流水")
|
||||
@PostMapping("/pay")
|
||||
public DaxResult<?> down(@RequestBody PayParam payParam){
|
||||
|
||||
@@ -3,7 +3,7 @@ package cn.daxpay.single.service.annotation;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 支付接口标识,
|
||||
* 支付签名标识
|
||||
* 支付方法至少有一个参数,并且需要签名支付参数需要放在第一位
|
||||
* 返回对象必须为 ResResult<T extends PaymentCommonResult> 格式
|
||||
* @author xxm
|
||||
@@ -13,10 +13,5 @@ import java.lang.annotation.*;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface PaymentApi {
|
||||
|
||||
/**
|
||||
* 支付接口编码
|
||||
*/
|
||||
String value();
|
||||
public @interface PaymentSign {
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package cn.daxpay.single.service.annotation;
|
||||
|
||||
import cn.daxpay.single.code.PaymentApiCode;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 初始化平台信息和接口API相关的上下文信息
|
||||
* @author xxm
|
||||
* @since 2024/5/22
|
||||
*/
|
||||
@Target({ ElementType.METHOD })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface PlatformInitContext {
|
||||
|
||||
/**
|
||||
* 接口标识
|
||||
* @see PaymentApiCode
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.daxpay.single.service.core.task.notice.convert;
|
||||
package cn.daxpay.single.service.core.notice.convert;
|
||||
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.dto.record.notice.ClientNoticeRecordDto;
|
||||
import cn.daxpay.single.service.dto.record.notice.ClientNoticeTaskDto;
|
||||
import org.mapstruct.Mapper;
|
||||
@@ -1,10 +1,10 @@
|
||||
package cn.daxpay.single.service.core.task.notice.dao;
|
||||
package cn.daxpay.single.service.core.notice.dao;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.common.query.generator.QueryGenerator;
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.param.record.ClientNoticeRecordQuery;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.daxpay.single.service.core.task.notice.dao;
|
||||
package cn.daxpay.single.service.core.notice.dao;
|
||||
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeRecord;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package cn.daxpay.single.service.core.task.notice.dao;
|
||||
package cn.daxpay.single.service.core.notice.dao;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.common.query.generator.QueryGenerator;
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.param.record.ClientNoticeTaskQuery;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.daxpay.single.service.core.task.notice.dao;
|
||||
package cn.daxpay.single.service.core.notice.dao;
|
||||
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeTask;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package cn.daxpay.single.service.core.task.notice.entity;
|
||||
package cn.daxpay.single.service.core.notice.entity;
|
||||
|
||||
import cn.bootx.platform.common.core.function.EntityBaseFunction;
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
|
||||
import cn.daxpay.single.service.code.ClientNoticeSendTypeEnum;
|
||||
import cn.daxpay.single.service.core.task.notice.convert.ClientNoticeConvert;
|
||||
import cn.daxpay.single.service.core.notice.convert.ClientNoticeConvert;
|
||||
import cn.daxpay.single.service.dto.record.notice.ClientNoticeRecordDto;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
@@ -1,4 +1,4 @@
|
||||
package cn.daxpay.single.service.core.task.notice.entity;
|
||||
package cn.daxpay.single.service.core.notice.entity;
|
||||
|
||||
import cn.bootx.platform.common.core.function.EntityBaseFunction;
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
|
||||
@@ -8,10 +8,11 @@ import cn.bootx.table.modify.mysql.annotation.DbMySqlFieldType;
|
||||
import cn.bootx.table.modify.mysql.constants.MySqlFieldTypeEnum;
|
||||
import cn.daxpay.single.code.PayStatusEnum;
|
||||
import cn.daxpay.single.code.RefundStatusEnum;
|
||||
import cn.daxpay.single.result.allocation.AllocOrderResult;
|
||||
import cn.daxpay.single.service.code.ClientNoticeTypeEnum;
|
||||
import cn.daxpay.single.service.core.payment.notice.result.PayNoticeResult;
|
||||
import cn.daxpay.single.service.core.payment.notice.result.RefundNoticeResult;
|
||||
import cn.daxpay.single.service.core.task.notice.convert.ClientNoticeConvert;
|
||||
import cn.daxpay.single.service.core.notice.convert.ClientNoticeConvert;
|
||||
import cn.daxpay.single.service.dto.record.notice.ClientNoticeTaskDto;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
@@ -59,6 +60,7 @@ public class ClientNoticeTask extends MpBaseEntity implements EntityBaseFunction
|
||||
* 消息内容
|
||||
* @see PayNoticeResult
|
||||
* @see RefundNoticeResult
|
||||
* @see AllocOrderResult
|
||||
*/
|
||||
@DbColumn(comment = "消息内容")
|
||||
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
|
||||
@@ -1,7 +1,7 @@
|
||||
package cn.daxpay.single.service.core.task.notice.service;
|
||||
package cn.daxpay.single.service.core.notice.service;
|
||||
|
||||
import cn.daxpay.single.service.core.task.notice.dao.ClientNoticeRecordManager;
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.core.notice.dao.ClientNoticeRecordManager;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeRecord;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -1,14 +1,14 @@
|
||||
package cn.daxpay.single.service.core.task.notice.service;
|
||||
package cn.daxpay.single.service.core.notice.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.bootx.platform.common.core.rest.PageResult;
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.core.payment.notice.service.ClientNoticeService;
|
||||
import cn.daxpay.single.service.core.task.notice.dao.ClientNoticeRecordManager;
|
||||
import cn.daxpay.single.service.core.task.notice.dao.ClientNoticeTaskManager;
|
||||
import cn.daxpay.single.service.core.notice.dao.ClientNoticeRecordManager;
|
||||
import cn.daxpay.single.service.core.notice.dao.ClientNoticeTaskManager;
|
||||
import cn.daxpay.single.service.dto.record.notice.ClientNoticeRecordDto;
|
||||
import cn.daxpay.single.service.dto.record.notice.ClientNoticeTaskDto;
|
||||
import cn.daxpay.single.service.param.record.ClientNoticeRecordQuery;
|
||||
@@ -0,0 +1,18 @@
|
||||
package cn.daxpay.single.service.core.order.allocation.dao;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrderExtra;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 分账订单扩展
|
||||
* @author xxm
|
||||
* @since 2024/5/22
|
||||
*/
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class AllocationOrderExtraManager extends BaseManager<AllocationOrderExtraMapper, AllocationOrderExtra> {
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package cn.daxpay.single.service.core.order.allocation.dao;
|
||||
|
||||
import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrderExtra;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 分账订单扩展
|
||||
* @author xxm
|
||||
* @since 2024/5/22
|
||||
*/
|
||||
@Mapper
|
||||
public interface AllocationOrderExtraMapper extends BaseMapper<AllocationOrderExtra> {
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package cn.daxpay.single.service.core.order.allocation.entity;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import cn.daxpay.single.param.channel.AliPayParam;
|
||||
import cn.daxpay.single.param.channel.WalletPayParam;
|
||||
import cn.daxpay.single.param.channel.WeChatPayParam;
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 分账订单扩展
|
||||
* @author xxm
|
||||
* @since 2024/5/22
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@DbTable(comment = "分账订单扩展")
|
||||
@TableName("pay_allocation_order_extra")
|
||||
public class AllocationOrderExtra extends MpBaseEntity {
|
||||
|
||||
/** 异步通知地址 */
|
||||
@DbColumn(comment = "异步通知地址")
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String notifyUrl;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回, 以最后一次为准 */
|
||||
@DbColumn(comment = "商户扩展参数")
|
||||
private String attach;
|
||||
|
||||
/**
|
||||
* 附加参数 以最后一次为准
|
||||
* @see AliPayParam
|
||||
* @see WeChatPayParam
|
||||
* @see WalletPayParam
|
||||
*/
|
||||
@DbColumn(comment = "附加参数")
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String extraParam;
|
||||
|
||||
/** 请求时间,时间戳转时间 */
|
||||
@DbColumn(comment = "请求时间,传输时间戳")
|
||||
private LocalDateTime reqTime;
|
||||
|
||||
/** 终端ip */
|
||||
@DbColumn(comment = "支付终端ip")
|
||||
private String clientIp;
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import cn.daxpay.single.code.PayChannelEnum;
|
||||
import cn.daxpay.single.code.PayOrderAllocStatusEnum;
|
||||
import cn.daxpay.single.exception.pay.PayFailureException;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocReceiverParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocStartParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocationParam;
|
||||
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;
|
||||
@@ -102,7 +102,7 @@ public class AllocationOrderService {
|
||||
* 生成分账订单, 根据分账组创建
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public OrderAndDetail createAndUpdate(AllocStartParam param, PayOrder payOrder, List<AllocationGroupReceiverResult> receiversByGroups){
|
||||
public OrderAndDetail createAndUpdate(AllocationParam param, PayOrder payOrder, List<AllocationGroupReceiverResult> receiversByGroups){
|
||||
long orderId = IdUtil.getSnowflakeNextId();
|
||||
|
||||
// 订单明细
|
||||
@@ -153,7 +153,7 @@ public class AllocationOrderService {
|
||||
/**
|
||||
* 生成分账订单, 通过传入的分账方创建
|
||||
*/
|
||||
public OrderAndDetail createAndUpdate(AllocStartParam param, PayOrder payOrder) {
|
||||
public OrderAndDetail createAndUpdate(AllocationParam param, PayOrder payOrder) {
|
||||
List<String> receiverNos = param.getReceivers()
|
||||
.stream()
|
||||
.map(AllocReceiverParam::getReceiverNo)
|
||||
|
||||
@@ -2,7 +2,6 @@ package cn.daxpay.single.service.core.order.refund.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.bootx.platform.common.spring.util.WebServletUtil;
|
||||
import cn.daxpay.single.code.PaymentApiCode;
|
||||
import cn.daxpay.single.param.payment.refund.RefundParam;
|
||||
import cn.daxpay.single.service.core.order.refund.dao.RefundOrderExtraManager;
|
||||
import cn.daxpay.single.service.core.order.refund.dao.RefundOrderManager;
|
||||
@@ -10,9 +9,6 @@ import cn.daxpay.single.service.core.order.refund.entity.RefundOrder;
|
||||
import cn.daxpay.single.service.core.order.refund.entity.RefundOrderExtra;
|
||||
import cn.daxpay.single.service.core.payment.common.service.PaymentAssistService;
|
||||
import cn.daxpay.single.service.core.payment.refund.service.RefundService;
|
||||
import cn.daxpay.single.service.core.system.config.dao.PayApiConfigManager;
|
||||
import cn.daxpay.single.service.core.system.config.entity.PayApiConfig;
|
||||
import cn.daxpay.single.service.core.system.config.service.PayApiConfigService;
|
||||
import cn.daxpay.single.service.param.order.PayOrderRefundParam;
|
||||
import cn.daxpay.single.util.OrderNoGenerateUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
@@ -36,16 +32,12 @@ public class RefundOrderService {
|
||||
|
||||
private final RefundService refundService;
|
||||
|
||||
private final PayApiConfigService apiConfigService;
|
||||
|
||||
private final PaymentAssistService paymentAssistService;
|
||||
|
||||
private final RefundOrderExtraManager refundOrderExtraManager;
|
||||
|
||||
private final RefundOrderManager refundOrderManager;
|
||||
|
||||
private final PayApiConfigManager apiConfigManager;
|
||||
|
||||
/**
|
||||
* 手动发起退款
|
||||
* 退款涉及到回调通知, 索所以需要手动初始化一下上下文
|
||||
@@ -64,11 +56,7 @@ public class RefundOrderService {
|
||||
refundParam.setReqTime(LocalDateTime.now());
|
||||
refundParam.setClientIp(ip);
|
||||
// 手动初始化上下文
|
||||
paymentAssistService.initContext(refundParam);
|
||||
// 初始化接口信息为统一退款
|
||||
PayApiConfig api = apiConfigManager.findByCode(PaymentApiCode.REFUND).orElseThrow(() -> new DataNotExistException("未找到统一退款接口信息"));
|
||||
// 设置接口信息
|
||||
apiConfigService.initApiInfo(api);
|
||||
paymentAssistService.initRequest(refundParam);
|
||||
// 调用统一退款接口
|
||||
refundService.refund(refundParam);
|
||||
}
|
||||
@@ -98,13 +86,7 @@ public class RefundOrderService {
|
||||
refundParam.setReqTime(LocalDateTime.now());
|
||||
refundParam.setClientIp(ip);
|
||||
|
||||
// 手动初始化上下文
|
||||
paymentAssistService.initContext(refundParam);
|
||||
// 初始化接口信息为统一退款
|
||||
PayApiConfig api = apiConfigManager.findByCode(PaymentApiCode.REFUND).orElseThrow(() -> new DataNotExistException("未找到统一退款接口信息"));
|
||||
// 设置接口信息
|
||||
apiConfigService.initApiInfo(api);
|
||||
// 调用统一退款接口
|
||||
refundService.refund(refundParam);
|
||||
// 手动初始化请求上下文
|
||||
paymentAssistService.initRequest(refundParam);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import cn.daxpay.single.param.payment.allocation.AllocReceiverAddParam;
|
||||
import cn.daxpay.single.result.allocation.AllocReceiverResult;
|
||||
import cn.daxpay.single.service.core.payment.allocation.entity.AllocationReceiver;
|
||||
import cn.daxpay.single.service.dto.allocation.AllocationReceiverDto;
|
||||
import cn.daxpay.single.service.param.allocation.receiver.AllocationReceiverParam;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@@ -21,7 +20,5 @@ public interface AllocationReceiverConvert {
|
||||
|
||||
AllocReceiverResult toResult(AllocationReceiver in);
|
||||
|
||||
AllocationReceiver convert(AllocationReceiverParam in);
|
||||
|
||||
AllocationReceiver convert(AllocReceiverAddParam in);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package cn.daxpay.single.service.core.payment.allocation.service;
|
||||
|
||||
import cn.daxpay.single.param.payment.allocation.AllocationParam;
|
||||
import cn.daxpay.single.service.common.context.ApiInfoLocal;
|
||||
import cn.daxpay.single.service.common.context.NoticeLocal;
|
||||
import cn.daxpay.single.service.common.context.PlatformLocal;
|
||||
import cn.daxpay.single.service.common.local.PaymentContextLocal;
|
||||
import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderExtraManager;
|
||||
import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrderExtra;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 分账支撑方法
|
||||
* @author xxm
|
||||
* @since 2024/5/22
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AllocationAssistService {
|
||||
|
||||
|
||||
private final AllocationOrderExtraManager allocationOrderExtraManager;
|
||||
|
||||
/**
|
||||
* 初始化通知相关上下文
|
||||
* 1. 异步通知参数: 读取参数配置 -> 读取接口配置 -> 读取平台参数
|
||||
* 2. 同步跳转参数: 读取参数配置 -> 读取平台参数
|
||||
* 3. 中途退出地址: 读取参数配置
|
||||
*/
|
||||
public void initNotice(AllocationParam allocationParam) {
|
||||
NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo();
|
||||
ApiInfoLocal apiInfo = PaymentContextLocal.get().getApiInfo();
|
||||
PlatformLocal platform = PaymentContextLocal.get()
|
||||
.getPlatformInfo();
|
||||
// 异步回调为开启状态
|
||||
if (apiInfo.isNotice()) {
|
||||
// 首先读取请求参数
|
||||
noticeInfo.setNotifyUrl(allocationParam.getNotifyUrl());
|
||||
// 读取接口配置
|
||||
if (StrUtil.isBlank(noticeInfo.getNotifyUrl())) {
|
||||
noticeInfo.setNotifyUrl(apiInfo.getNoticeUrl());
|
||||
}
|
||||
// 读取平台配置
|
||||
if (StrUtil.isBlank(noticeInfo.getNotifyUrl())) {
|
||||
noticeInfo.setNotifyUrl(platform.getNotifyUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 根据新传入的分账订单更新订单和扩展信息
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateOrder(AllocationParam allocationParam, AllocationOrderExtra orderExtra) {
|
||||
// 扩展信息
|
||||
NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo();
|
||||
orderExtra.setClientIp(allocationParam.getClientIp())
|
||||
.setNotifyUrl(noticeInfo.getNotifyUrl())
|
||||
.setAttach(allocationParam.getAttach())
|
||||
.setClientIp(allocationParam.getClientIp())
|
||||
.setReqTime(allocationParam.getReqTime());
|
||||
|
||||
allocationOrderExtraManager.updateById(orderExtra);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -9,8 +9,8 @@ import cn.daxpay.single.code.AllocOrderStatusEnum;
|
||||
import cn.daxpay.single.code.PayOrderAllocStatusEnum;
|
||||
import cn.daxpay.single.exception.pay.PayFailureException;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocFinishParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocStartParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocSyncParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocationParam;
|
||||
import cn.daxpay.single.param.payment.allocation.QueryAllocOrderParam;
|
||||
import cn.daxpay.single.result.allocation.AllocOrderDetailResult;
|
||||
import cn.daxpay.single.result.allocation.AllocOrderResult;
|
||||
@@ -19,9 +19,11 @@ import cn.daxpay.single.result.allocation.AllocationSyncResult;
|
||||
import cn.daxpay.single.service.common.local.PaymentContextLocal;
|
||||
import cn.daxpay.single.service.core.order.allocation.convert.AllocationConvert;
|
||||
import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderDetailManager;
|
||||
import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderExtraManager;
|
||||
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.order.allocation.entity.AllocationOrderExtra;
|
||||
import cn.daxpay.single.service.core.order.allocation.entity.OrderAndDetail;
|
||||
import cn.daxpay.single.service.core.order.allocation.service.AllocationOrderService;
|
||||
import cn.daxpay.single.service.core.order.pay.entity.PayOrder;
|
||||
@@ -29,6 +31,7 @@ import cn.daxpay.single.service.core.order.pay.service.PayOrderQueryService;
|
||||
import cn.daxpay.single.service.core.payment.allocation.dao.AllocationGroupManager;
|
||||
import cn.daxpay.single.service.core.payment.allocation.entity.AllocationGroup;
|
||||
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.dto.allocation.AllocationGroupReceiverResult;
|
||||
import cn.daxpay.single.service.func.AbsAllocationStrategy;
|
||||
import com.baomidou.lock.LockInfo;
|
||||
@@ -64,22 +67,26 @@ public class AllocationService {
|
||||
|
||||
private final AllocationOrderDetailManager allocationOrderDetailManager;
|
||||
|
||||
private final AllocationAssistService allocationAssistService;
|
||||
|
||||
private final PayOrderQueryService payOrderQueryService;
|
||||
|
||||
private final LockTemplate lockTemplate;
|
||||
private final AllocationOrderExtraManager allocationOrderExtraManager;
|
||||
private final ClientNoticeService clientNoticeService;
|
||||
|
||||
|
||||
/**
|
||||
* 开启分账 多次请求只会分账一次
|
||||
* 优先级 分账接收方列表 > 分账组编号 > 默认分账组
|
||||
*/
|
||||
public AllocationResult allocation(AllocStartParam param) {
|
||||
public AllocationResult allocation(AllocationParam param) {
|
||||
// 判断是否已经有分账订单
|
||||
AllocationOrder allocationOrder = allocationOrderManager.findByBizAllocationNo(param.getBizAllocationNo())
|
||||
.orElse(null);
|
||||
if (Objects.nonNull(allocationOrder)){
|
||||
// 重复分账
|
||||
return this.retryAllocation(allocationOrder);
|
||||
return this.retryAllocation(param, allocationOrder);
|
||||
} else {
|
||||
// 首次分账
|
||||
PayOrder payOrder = this.getAndCheckPayOrder(param);
|
||||
@@ -90,7 +97,7 @@ public class AllocationService {
|
||||
/**
|
||||
* 开启分账 优先级 分账接收方列表 > 分账组编号 > 默认分账组
|
||||
*/
|
||||
public AllocationResult allocation(AllocStartParam param, PayOrder payOrder) {
|
||||
public AllocationResult allocation(AllocationParam param, PayOrder payOrder) {
|
||||
LockInfo lock = lockTemplate.lock("payment:allocation:" + payOrder.getId(),10000,200);
|
||||
if (Objects.isNull(lock)){
|
||||
throw new RepetitiveOperationException("分账发起处理中,请勿重复操作");
|
||||
@@ -130,6 +137,7 @@ public class AllocationService {
|
||||
// 失败
|
||||
order.setStatus(AllocOrderStatusEnum.ALLOCATION_FAILED.getCode())
|
||||
.setErrorMsg(e.getMessage());
|
||||
// TODO 返回异常处理
|
||||
}
|
||||
// 网关分账号
|
||||
String gatewayNo = PaymentContextLocal.get()
|
||||
@@ -148,7 +156,7 @@ public class AllocationService {
|
||||
/**
|
||||
* 重新分账
|
||||
*/
|
||||
private AllocationResult retryAllocation(AllocationOrder order){
|
||||
private AllocationResult retryAllocation(AllocationParam param, AllocationOrder order){
|
||||
LockInfo lock = lockTemplate.lock("payment:allocation:" + order.getOrderId(),10000,200);
|
||||
if (Objects.isNull(lock)){
|
||||
throw new RepetitiveOperationException("分账发起处理中,请勿重复操作");
|
||||
@@ -165,9 +173,13 @@ public class AllocationService {
|
||||
// 创建分账策略并初始化
|
||||
AbsAllocationStrategy allocationStrategy = AllocationFactory.create(order.getChannel());
|
||||
allocationStrategy.initParam(order, details);
|
||||
|
||||
// 分账预处理
|
||||
allocationStrategy.doBeforeHandler();
|
||||
// 查询扩展信息
|
||||
AllocationOrderExtra orderExtra = allocationOrderExtraManager.findById(order.getId())
|
||||
.orElseThrow(() -> new PayFailureException("未查询到分账单扩展信息"));
|
||||
// 更新分账单扩展信息
|
||||
allocationAssistService.updateOrder(param, orderExtra);
|
||||
try {
|
||||
// 重复分账处理
|
||||
allocationStrategy.allocation();
|
||||
@@ -176,7 +188,7 @@ public class AllocationService {
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("重新分账出现错误:", e);
|
||||
// 失败
|
||||
// TODO 失败
|
||||
order.setStatus(AllocOrderStatusEnum.ALLOCATION_FAILED.getCode())
|
||||
.setErrorMsg(e.getMessage());
|
||||
}
|
||||
@@ -273,10 +285,9 @@ public class AllocationService {
|
||||
allocationStrategy.doBeforeHandler();
|
||||
allocationStrategy.doSync();
|
||||
// TODO 保存分账同步记录
|
||||
|
||||
// 根据订单明细更新订单的状态和处理结果
|
||||
this.updateOrderStatus(allocationOrder, detailList);
|
||||
allocationOrderDetailManager.updateAllById(detailList);
|
||||
allocationOrderManager.updateById(allocationOrder);
|
||||
} finally {
|
||||
lockTemplate.releaseLock(lock);
|
||||
}
|
||||
@@ -284,49 +295,59 @@ public class AllocationService {
|
||||
|
||||
/**
|
||||
* 根据订单明细更新订单的状态和处理结果, 如果订单是分账结束或失败, 不更新状态
|
||||
* TODO 是否多次同步会产生多次变动, 注意处理多次推送通知的问题, 目前是
|
||||
*/
|
||||
private void updateOrderStatus(AllocationOrder allocationOrder, List<AllocationOrderDetail> details){
|
||||
// 如果是分账结束或失败, 不更新状态
|
||||
String status = allocationOrder.getStatus();
|
||||
// 判断明细状态. 获取成功和失败的
|
||||
long successCount = details.stream()
|
||||
.map(AllocationOrderDetail::getResult)
|
||||
.filter(AllocDetailResultEnum.SUCCESS.getCode()::equals)
|
||||
.count();
|
||||
long failCount = details.stream()
|
||||
.map(AllocationOrderDetail::getResult)
|
||||
.filter(AllocDetailResultEnum.FAIL.getCode()::equals)
|
||||
.count();
|
||||
|
||||
// 成功和失败都为0 进行中
|
||||
if (successCount == 0 && failCount == 0){
|
||||
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_PROCESSING.getCode())
|
||||
.setResult(AllocOrderResultEnum.ALL_PENDING.getCode());
|
||||
} else if (failCount == details.size()){
|
||||
// 全部失败
|
||||
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
|
||||
.setResult(AllocOrderResultEnum.ALL_FAILED.getCode());
|
||||
} else if (successCount == details.size()){
|
||||
// 全部成功
|
||||
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
|
||||
.setResult(AllocOrderResultEnum.ALL_SUCCESS.getCode());
|
||||
} else {
|
||||
// 部分成功
|
||||
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
|
||||
.setResult(AllocOrderResultEnum.PART_SUCCESS.getCode());
|
||||
}
|
||||
// 如果是分账结束或失败, 状态复原
|
||||
// 如果是分账结束或失败, 不进行对订单进行处理
|
||||
List<String> list = Arrays.asList(AllocOrderStatusEnum.FINISH.getCode(), AllocOrderStatusEnum.FINISH_FAILED.getCode());
|
||||
if (list.contains(status)){
|
||||
allocationOrder.setStatus(AllocOrderStatusEnum.FINISH.getCode())
|
||||
.setResult(AllocOrderResultEnum.ALL_SUCCESS.getCode());
|
||||
if (!list.contains(status)){
|
||||
// 判断明细状态. 获取成功和失败的
|
||||
long successCount = details.stream()
|
||||
.map(AllocationOrderDetail::getResult)
|
||||
.filter(AllocDetailResultEnum.SUCCESS.getCode()::equals)
|
||||
.count();
|
||||
long failCount = details.stream()
|
||||
.map(AllocationOrderDetail::getResult)
|
||||
.filter(AllocDetailResultEnum.FAIL.getCode()::equals)
|
||||
.count();
|
||||
|
||||
// 成功和失败都为0 表示进行中
|
||||
if (successCount == 0 && failCount == 0){
|
||||
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_PROCESSING.getCode())
|
||||
.setResult(AllocOrderResultEnum.ALL_PENDING.getCode());
|
||||
} else {
|
||||
if (failCount == details.size()){
|
||||
// 全部失败
|
||||
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
|
||||
.setResult(AllocOrderResultEnum.ALL_FAILED.getCode());
|
||||
} else if (successCount == details.size()){
|
||||
// 全部成功
|
||||
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
|
||||
.setResult(AllocOrderResultEnum.ALL_SUCCESS.getCode());
|
||||
} else {
|
||||
// 部分成功
|
||||
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
|
||||
.setResult(AllocOrderResultEnum.PART_SUCCESS.getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
allocationOrderDetailManager.updateAllById(details);
|
||||
allocationOrderManager.updateById(allocationOrder);
|
||||
|
||||
// 如果状态为完成, 发送通知
|
||||
if (Objects.equals(AllocOrderStatusEnum.ALLOCATION_END.getCode(), allocationOrder.getStatus())){
|
||||
// 发送通知
|
||||
clientNoticeService.registerAllocNotice(allocationOrder, null, details);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取并检查支付订单
|
||||
*/
|
||||
private PayOrder getAndCheckPayOrder(AllocStartParam param) {
|
||||
private PayOrder getAndCheckPayOrder(AllocationParam param) {
|
||||
// 查询支付单
|
||||
PayOrder payOrder = payOrderQueryService.findByBizOrOrderNo(param.getOrderNo(), param.getBizOrderNo())
|
||||
.orElseThrow(() -> new PayFailureException("支付单不存在"));
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package cn.daxpay.single.service.core.payment.common.aop;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.daxpay.single.exception.pay.PayFailureException;
|
||||
import cn.daxpay.single.service.annotation.PlatformInitContext;
|
||||
import cn.daxpay.single.service.core.system.config.dao.PayApiConfigManager;
|
||||
import cn.daxpay.single.service.core.system.config.entity.PayApiConfig;
|
||||
import cn.daxpay.single.service.core.system.config.service.PayApiConfigService;
|
||||
import cn.daxpay.single.service.core.system.config.service.PlatformConfigService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
*
|
||||
* 执行顺序: 过滤器 -> 拦截器 -> 切面 -> 方法
|
||||
* @author xxm
|
||||
* @since 2023/12/24
|
||||
*/
|
||||
@Aspect
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class InitPlatformInfoAop {
|
||||
|
||||
private final PayApiConfigService payApiConfigService;
|
||||
|
||||
private final PayApiConfigManager payApiConfigManager;
|
||||
|
||||
private final PlatformConfigService platformConfigService;
|
||||
|
||||
/**
|
||||
* 拦截注解
|
||||
*/
|
||||
@Around("@annotation(platformContext)")
|
||||
public Object beforeMethod(ProceedingJoinPoint pjp, PlatformInitContext platformContext) throws Throwable {
|
||||
String code = platformContext.value();
|
||||
// 接口信息
|
||||
PayApiConfig api = payApiConfigManager.findByCode(code)
|
||||
.orElseThrow(() -> new DataNotExistException("未找到接口信息"));
|
||||
if (!api.isEnable()){
|
||||
throw new PayFailureException("该接口权限未开放");
|
||||
}
|
||||
// 设置接口信息
|
||||
payApiConfigService.initApiInfo(api);
|
||||
// 初始化平台信息
|
||||
platformConfigService.initPlatform();
|
||||
return pjp.proceed();
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import cn.bootx.platform.common.core.util.ValidationUtil;
|
||||
import cn.daxpay.single.exception.pay.PayFailureException;
|
||||
import cn.daxpay.single.param.PaymentCommonParam;
|
||||
import cn.daxpay.single.result.PaymentCommonResult;
|
||||
import cn.daxpay.single.service.annotation.PaymentApi;
|
||||
import cn.daxpay.single.service.annotation.PaymentSign;
|
||||
import cn.daxpay.single.service.core.payment.common.service.PaymentSignService;
|
||||
import cn.daxpay.single.util.DaxRes;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -13,6 +13,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
@@ -24,12 +25,13 @@ import org.springframework.stereotype.Component;
|
||||
@Aspect
|
||||
@Slf4j
|
||||
@Component
|
||||
@Order()
|
||||
@RequiredArgsConstructor
|
||||
public class PaymentVerifySignAop {
|
||||
private final PaymentSignService paymentSignService;
|
||||
|
||||
@Around("@annotation(paymentApi)")
|
||||
public Object beforeMethod(ProceedingJoinPoint pjp, PaymentApi paymentApi) throws Throwable {
|
||||
@Around("@annotation(paymentSign)")
|
||||
public Object beforeMethod(ProceedingJoinPoint pjp, @SuppressWarnings("unused") PaymentSign paymentSign) throws Throwable {
|
||||
Object[] args = pjp.getArgs();
|
||||
if (args.length == 0){
|
||||
throw new PayFailureException("支付方法至少有一个参数,并且需要签名支付参数需要放在第一位");
|
||||
@@ -49,7 +51,7 @@ public class PaymentVerifySignAop {
|
||||
} catch (PayFailureException ex) {
|
||||
// 如果抛出支付异常, 包裹异常信息, 进行返回
|
||||
PaymentCommonResult commonResult = new PaymentCommonResult();
|
||||
// todo 后期错误码统一管理后, 进行更改
|
||||
// todo 后期错误码统一管理后进行更改
|
||||
commonResult.setCode(1);
|
||||
commonResult.setMsg(ex.getMessage());
|
||||
paymentSignService.sign(commonResult);
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package cn.daxpay.single.service.core.payment.common.service;
|
||||
|
||||
import cn.daxpay.single.param.PaymentCommonParam;
|
||||
import cn.daxpay.single.service.common.context.PlatformLocal;
|
||||
import cn.daxpay.single.service.common.context.RequestLocal;
|
||||
import cn.daxpay.single.service.common.local.PaymentContextLocal;
|
||||
import cn.daxpay.single.service.core.system.config.entity.PlatformConfig;
|
||||
import cn.daxpay.single.service.core.system.config.service.PlatformConfigService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -25,29 +23,13 @@ public class PaymentAssistService {
|
||||
* 初始化上下文
|
||||
*/
|
||||
public void initContext(PaymentCommonParam paymentCommonParam){
|
||||
this.initPlatform();
|
||||
platformConfigService.initPlatform();
|
||||
this.initRequest(paymentCommonParam);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化平台配置上下文
|
||||
*/
|
||||
public void initPlatform(){
|
||||
PlatformConfig config = platformConfigService.getConfig();
|
||||
PlatformLocal platform = PaymentContextLocal.get().getPlatformInfo();
|
||||
platform.setSignType(config.getSignType());
|
||||
platform.setSignSecret(config.getSignSecret());
|
||||
platform.setNotifyUrl(config.getNotifyUrl());
|
||||
platform.setOrderTimeout(config.getOrderTimeout());
|
||||
platform.setLimitAmount(config.getLimitAmount());
|
||||
platform.setWebsiteUrl(config.getWebsiteUrl());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化请求相关信息上下文
|
||||
*/
|
||||
private void initRequest(PaymentCommonParam paymentCommonParam){
|
||||
public void initRequest(PaymentCommonParam paymentCommonParam){
|
||||
RequestLocal request = PaymentContextLocal.get().getRequestInfo();
|
||||
request.setClientIp(paymentCommonParam.getClientIp())
|
||||
.setSign(paymentCommonParam.getSign())
|
||||
|
||||
@@ -7,7 +7,9 @@ import cn.daxpay.single.result.PaymentCommonResult;
|
||||
import cn.daxpay.single.service.common.context.ApiInfoLocal;
|
||||
import cn.daxpay.single.service.common.context.PlatformLocal;
|
||||
import cn.daxpay.single.service.common.local.PaymentContextLocal;
|
||||
import cn.daxpay.single.service.core.system.config.service.PlatformConfigService;
|
||||
import cn.daxpay.single.util.PaySignUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -24,7 +26,9 @@ import java.util.Objects;
|
||||
@RequiredArgsConstructor
|
||||
public class PaymentSignService {
|
||||
|
||||
private final PaymentAssistService paymentAssistService;;
|
||||
private final PaymentAssistService paymentAssistService;
|
||||
|
||||
private final PlatformConfigService platformConfigService;
|
||||
|
||||
/**
|
||||
* 入参签名校验
|
||||
@@ -61,6 +65,10 @@ public class PaymentSignService {
|
||||
*/
|
||||
public void sign(PaymentCommonResult result) {
|
||||
PlatformLocal platformInfo = PaymentContextLocal.get().getPlatformInfo();
|
||||
// 如果平台配置所有属性为空, 进行初始化
|
||||
if (BeanUtil.isEmpty(platformInfo)){
|
||||
platformConfigService.initPlatform();
|
||||
}
|
||||
String signType = platformInfo.getSignType();
|
||||
if (Objects.equals(PaySignTypeEnum.HMAC_SHA256.getCode(), signType)){
|
||||
result.setSign(PaySignUtil.hmacSha256Sign(result, platformInfo.getSignSecret()));
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
package cn.daxpay.single.service.core.payment.notice.service;
|
||||
|
||||
import cn.bootx.platform.common.jackson.util.JacksonUtil;
|
||||
import cn.daxpay.single.result.allocation.AllocOrderDetailResult;
|
||||
import cn.daxpay.single.result.allocation.AllocOrderResult;
|
||||
import cn.daxpay.single.service.code.ClientNoticeTypeEnum;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.core.order.allocation.convert.AllocationConvert;
|
||||
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.order.allocation.entity.AllocationOrderExtra;
|
||||
import cn.daxpay.single.service.core.order.pay.convert.PayOrderConvert;
|
||||
import cn.daxpay.single.service.core.order.pay.entity.PayOrder;
|
||||
import cn.daxpay.single.service.core.order.pay.entity.PayOrderExtra;
|
||||
import cn.daxpay.single.service.core.order.refund.convert.RefundOrderConvert;
|
||||
import cn.daxpay.single.service.core.order.refund.entity.RefundOrder;
|
||||
import cn.daxpay.single.service.core.order.refund.entity.RefundOrderExtra;
|
||||
import cn.daxpay.single.service.core.payment.common.service.PaymentAssistService;
|
||||
import cn.daxpay.single.service.core.payment.common.service.PaymentSignService;
|
||||
import cn.daxpay.single.service.core.payment.notice.result.PayNoticeResult;
|
||||
import cn.daxpay.single.service.core.payment.notice.result.RefundNoticeResult;
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 客户系统消息通知任务支撑服务
|
||||
* @author xxm
|
||||
@@ -29,14 +37,10 @@ public class ClientNoticeAssistService {
|
||||
|
||||
private final PaymentSignService paymentSignService;
|
||||
|
||||
private final PaymentAssistService paymentAssistService;
|
||||
|
||||
/**
|
||||
* 构建出支付通知任务对象
|
||||
*/
|
||||
public ClientNoticeTask buildPayTask(PayOrder order, PayOrderExtra orderExtra){
|
||||
// 获取系统签名
|
||||
paymentAssistService.initPlatform();
|
||||
PayNoticeResult payNoticeResult = PayOrderConvert.CONVERT.convertNotice(order);
|
||||
payNoticeResult.setAttach(orderExtra.getAttach());
|
||||
paymentSignService.sign(payNoticeResult);
|
||||
@@ -55,12 +59,9 @@ public class ClientNoticeAssistService {
|
||||
* 构建出退款通知任务对象
|
||||
*/
|
||||
public ClientNoticeTask buildRefundTask(RefundOrder order, RefundOrderExtra orderExtra){
|
||||
// 获取系统签名
|
||||
paymentAssistService.initPlatform();
|
||||
// 创建退款通知内容
|
||||
RefundNoticeResult refundNoticeResult = RefundOrderConvert.CONVERT.convertNotice(order);
|
||||
refundNoticeResult.setAttach(orderExtra.getAttach());
|
||||
|
||||
// 签名
|
||||
paymentSignService.sign(refundNoticeResult);
|
||||
return new ClientNoticeTask()
|
||||
@@ -77,8 +78,26 @@ public class ClientNoticeAssistService {
|
||||
/**
|
||||
* 构建分账通知
|
||||
*/
|
||||
public ClientNoticeTask buildDivideTask(String tradeNo, String tradeStatus){
|
||||
return null;
|
||||
public ClientNoticeTask buildAllocTask(AllocationOrder order, AllocationOrderExtra orderExtra, List<AllocationOrderDetail> list){
|
||||
// 分账
|
||||
AllocOrderResult allocOrderResult = AllocationConvert.CONVERT.toResult(order);
|
||||
// 分账详情
|
||||
List<AllocOrderDetailResult> details = list.stream()
|
||||
.map(AllocationConvert.CONVERT::toResult)
|
||||
.collect(Collectors.toList());
|
||||
// 分账扩展
|
||||
allocOrderResult.setAttach(orderExtra.getAttach());
|
||||
// 签名
|
||||
paymentSignService.sign(allocOrderResult);
|
||||
return new ClientNoticeTask()
|
||||
.setUrl(orderExtra.getNotifyUrl())
|
||||
// 时间序列化进行了重写
|
||||
.setContent(JacksonUtil.toJson(allocOrderResult))
|
||||
.setNoticeType(ClientNoticeTypeEnum.REFUND.getType())
|
||||
.setSendCount(0)
|
||||
.setTradeId(order.getId())
|
||||
.setTradeNo(order.getAllocationNo())
|
||||
.setTradeStatus(order.getStatus());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,16 +4,20 @@ import cn.bootx.platform.common.core.exception.RepetitiveOperationException;
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.common.redis.RedisClient;
|
||||
import cn.daxpay.single.service.code.ClientNoticeSendTypeEnum;
|
||||
import cn.daxpay.single.service.core.notice.dao.ClientNoticeTaskManager;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.core.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.core.notice.service.ClientNoticeRecordService;
|
||||
import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderExtraManager;
|
||||
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.order.allocation.entity.AllocationOrderExtra;
|
||||
import cn.daxpay.single.service.core.order.pay.dao.PayOrderExtraManager;
|
||||
import cn.daxpay.single.service.core.order.pay.entity.PayOrder;
|
||||
import cn.daxpay.single.service.core.order.pay.entity.PayOrderExtra;
|
||||
import cn.daxpay.single.service.core.order.refund.dao.RefundOrderExtraManager;
|
||||
import cn.daxpay.single.service.core.order.refund.entity.RefundOrder;
|
||||
import cn.daxpay.single.service.core.order.refund.entity.RefundOrderExtra;
|
||||
import cn.daxpay.single.service.core.task.notice.dao.ClientNoticeTaskManager;
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.daxpay.single.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import cn.daxpay.single.service.core.task.notice.service.ClientNoticeRecordService;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
@@ -49,6 +53,8 @@ public class ClientNoticeService {
|
||||
|
||||
private final ClientNoticeRecordService recordService;
|
||||
|
||||
private final AllocationOrderExtraManager allocationOrderExtraManager;
|
||||
|
||||
private final RedisClient redisClient;
|
||||
|
||||
private final LockTemplate lockTemplate;
|
||||
@@ -126,7 +132,7 @@ public class ClientNoticeService {
|
||||
if (Objects.isNull(orderExtra)){
|
||||
Optional<RefundOrderExtra> extraOpt = refundOrderExtraManager.findById(order.getId());
|
||||
if (!extraOpt.isPresent()){
|
||||
log.error("未找到支付扩展信息,数据错误,订单ID:{}",order.getId());
|
||||
log.error("未找到退款扩展信息,数据错误,订单ID:{}",order.getId());
|
||||
return;
|
||||
}
|
||||
orderExtra = extraOpt.get();
|
||||
@@ -154,8 +160,32 @@ public class ClientNoticeService {
|
||||
* 注册分账消息通知任务
|
||||
*/
|
||||
@Async("bigExecutor")
|
||||
public void registerAllocNotice() {
|
||||
public void registerAllocNotice(AllocationOrder order, AllocationOrderExtra orderExtra, List<AllocationOrderDetail> list) {
|
||||
// 创建通知任务并保存
|
||||
if (Objects.isNull(orderExtra)){
|
||||
Optional<AllocationOrderExtra> extraOpt = allocationOrderExtraManager.findById(order.getId());
|
||||
if (!extraOpt.isPresent()){
|
||||
log.error("未找到分账扩展信息,数据错误,订单ID:{}",order.getId());
|
||||
return;
|
||||
}
|
||||
orderExtra = extraOpt.get();
|
||||
}
|
||||
// 判断是否需要进行通知
|
||||
if (StrUtil.isBlank(orderExtra.getNotifyUrl())){
|
||||
log.info("分账订单无需通知,订单ID:{}",order.getId());
|
||||
return;
|
||||
}
|
||||
// 创建通知任务并保存
|
||||
ClientNoticeTask task = clientNoticeAssistService.buildAllocTask(order, orderExtra, list);
|
||||
try {
|
||||
taskManager.save(task);
|
||||
} catch (Exception e) {
|
||||
log.error("注册分账消息通知任务失败,数据错误,订单ID:{}",order.getId());
|
||||
log.error("错误内容",e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// 同时触发一次通知, 如果成功发送, 任务结束
|
||||
this.sendData(task, LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -151,8 +151,6 @@ public class PayAssistService {
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updatePayOrder(PayParam payParam,PayOrder order, PayOrderExtra payOrderExtra) {
|
||||
PayLocal payInfo = PaymentContextLocal.get()
|
||||
.getPayInfo();
|
||||
// 订单信息
|
||||
order.setAllocation(payParam.getAllocation())
|
||||
.setChannel(payParam.getChannel())
|
||||
|
||||
@@ -54,7 +54,7 @@ public class PayApiConfigService {
|
||||
* 初始化接口上下文信息
|
||||
*/
|
||||
public void initApiInfo(PayApiConfig api){
|
||||
// 记录支付接口信息
|
||||
// 接口信息
|
||||
ApiInfoLocal apiInfoLocal = PaymentContextLocal.get().getApiInfo();
|
||||
apiInfoLocal.setApiCode(api.getCode())
|
||||
.setReqSign(api.isReqSign())
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package cn.daxpay.single.service.core.system.config.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.daxpay.single.service.core.system.config.entity.PlatformConfig;
|
||||
import cn.daxpay.single.service.common.context.PlatformLocal;
|
||||
import cn.daxpay.single.service.common.local.PaymentContextLocal;
|
||||
import cn.daxpay.single.service.core.system.config.dao.PlatformConfigManager;
|
||||
import cn.daxpay.single.service.core.system.config.entity.PlatformConfig;
|
||||
import cn.daxpay.single.service.param.system.config.PlatformConfigParam;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -38,4 +40,18 @@ public class PlatformConfigService {
|
||||
BeanUtil.copyProperties(param,config);
|
||||
platformConfigManager.updateById(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化平台配置上下文
|
||||
*/
|
||||
public void initPlatform(){
|
||||
PlatformConfig config = this.getConfig();
|
||||
PlatformLocal platform = PaymentContextLocal.get().getPlatformInfo();
|
||||
platform.setSignType(config.getSignType());
|
||||
platform.setSignSecret(config.getSignSecret());
|
||||
platform.setNotifyUrl(config.getNotifyUrl());
|
||||
platform.setOrderTimeout(config.getOrderTimeout());
|
||||
platform.setLimitAmount(config.getLimitAmount());
|
||||
platform.setWebsiteUrl(config.getWebsiteUrl());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
package cn.daxpay.single.service.handler;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.daxpay.single.exception.pay.PayFailureException;
|
||||
import cn.daxpay.single.service.annotation.PaymentApi;
|
||||
import cn.daxpay.single.service.core.system.config.dao.PayApiConfigManager;
|
||||
import cn.daxpay.single.service.core.system.config.entity.PayApiConfig;
|
||||
import cn.daxpay.single.service.core.system.config.service.PayApiConfigService;
|
||||
import cn.bootx.platform.starter.auth.service.RouterCheck;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 支付接口请求检查器, 用于判断请求的支付接口是否允许被外部访问.
|
||||
* 同时如果检查的结果是放行, 同时初始化支付上下文线程对象
|
||||
* @author xxm
|
||||
* @since 2023/12/22
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class PayApiCheckHandler implements RouterCheck {
|
||||
private final PayApiConfigManager apiConfigManager;
|
||||
private final PayApiConfigService apiConfigService;
|
||||
|
||||
@Override
|
||||
public int sortNo() {
|
||||
return -1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(Object handler) {
|
||||
// 如果请求的接口未启用
|
||||
if (handler instanceof HandlerMethod) {
|
||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||
PaymentApi paymentApi = handlerMethod.getMethodAnnotation(PaymentApi.class);
|
||||
if (Objects.isNull(paymentApi)){
|
||||
return false;
|
||||
}
|
||||
String code = paymentApi.value();
|
||||
PayApiConfig api = apiConfigManager.findByCode(code)
|
||||
.orElseThrow(() -> new DataNotExistException("未找到接口信息"));
|
||||
if (!api.isEnable()){
|
||||
throw new PayFailureException("该接口权限未开放");
|
||||
}
|
||||
// 设置接口信息
|
||||
apiConfigService.initApiInfo(api);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package cn.daxpay.single.service.param.allocation.receiver;
|
||||
|
||||
import cn.daxpay.single.code.AllocReceiverTypeEnum;
|
||||
import cn.daxpay.single.code.AllocRelationTypeEnum;
|
||||
import cn.daxpay.single.code.PayChannelEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 分账接收方参数
|
||||
* @author xxm
|
||||
* @since 2024/3/28
|
||||
*/
|
||||
@Data
|
||||
@Deprecated
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "分账接收方参数")
|
||||
public class AllocationReceiverParam {
|
||||
|
||||
|
||||
@Schema(description = "主键")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "账号别名")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* @see PayChannelEnum
|
||||
*/
|
||||
@Schema(description = "所属通道")
|
||||
private String channel;
|
||||
|
||||
/**
|
||||
* 分账接收方类型 个人/商户
|
||||
* @see AllocReceiverTypeEnum
|
||||
*/
|
||||
@Schema(description = "分账接收方类型")
|
||||
private String receiverType;
|
||||
|
||||
|
||||
@Schema(description = "接收方账号")
|
||||
private String receiverAccount;
|
||||
|
||||
/** 接收方姓名 */
|
||||
@Schema(description = "接收方姓名")
|
||||
private String receiverName;
|
||||
|
||||
/**
|
||||
* 分账关系类型
|
||||
* @see AllocRelationTypeEnum
|
||||
*/
|
||||
@Schema(description = "分账关系类型")
|
||||
private String relationType;
|
||||
|
||||
@Schema(description = "关系名称")
|
||||
private String relationName;
|
||||
|
||||
@Schema(description = "是否已经同步到网关")
|
||||
private Boolean sync;
|
||||
|
||||
@Schema(description = "备注")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.daxpay.single.service.task;
|
||||
|
||||
import cn.daxpay.single.param.payment.allocation.AllocStartParam;
|
||||
import cn.daxpay.single.param.payment.allocation.AllocationParam;
|
||||
import cn.daxpay.single.service.core.order.pay.dao.PayOrderManager;
|
||||
import cn.daxpay.single.service.core.order.pay.entity.PayOrder;
|
||||
import cn.daxpay.single.service.core.payment.allocation.service.AllocationService;
|
||||
@@ -27,7 +27,7 @@ public class AllocationAutoStartTask implements Job {
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
for (PayOrder payOrder : payOrderManager.findAutoAllocation()) {
|
||||
AllocStartParam param = new AllocStartParam();
|
||||
AllocationParam param = new AllocationParam();
|
||||
param.setBizAllocationNo(OrderNoGenerateUtil.allocation());
|
||||
try {
|
||||
allocationService.allocation(param, payOrder);
|
||||
|
||||
@@ -27,7 +27,7 @@ public class RefundSyncTask implements Job {
|
||||
private final RefundOrderManager refundOrderManager;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||
public void execute(JobExecutionContext context) {
|
||||
// 查询退款中的退款订单
|
||||
List<RefundOrder> list = refundOrderManager.findAllByProgress();
|
||||
for (RefundOrder refundOrder : list) {
|
||||
|
||||
Reference in New Issue
Block a user