mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-09-01 18:27:02 +00:00
feat 支付流程改为先落库, 后支付
This commit is contained in:
@@ -4,6 +4,7 @@ import cn.bootx.platform.common.core.annotation.IgnoreAuth;
|
||||
import cn.bootx.platform.common.core.exception.BizException;
|
||||
import cn.bootx.platform.common.core.rest.Res;
|
||||
import cn.bootx.platform.common.core.rest.ResResult;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayTransferService;
|
||||
import cn.hutool.core.thread.ThreadUtil;
|
||||
import com.baomidou.lock.LockInfo;
|
||||
import com.baomidou.lock.LockTemplate;
|
||||
@@ -27,6 +28,7 @@ import java.util.Objects;
|
||||
@RequiredArgsConstructor
|
||||
public class TestController {
|
||||
private final LockTemplate lockTemplate;
|
||||
private final AliPayTransferService aliPayTransferService;
|
||||
|
||||
@Operation(summary = "锁测试1")
|
||||
@GetMapping("/lock1")
|
||||
@@ -54,7 +56,15 @@ public class TestController {
|
||||
@Operation(summary = "微信回调测试")
|
||||
@GetMapping(value = {"/wxcs/","wxcs"})
|
||||
public String wxcs(){
|
||||
return "ok";
|
||||
}
|
||||
|
||||
@IgnoreAuth
|
||||
@Operation(summary = "支付宝回调测试")
|
||||
@GetMapping("/queryAmount")
|
||||
public String alipay(){
|
||||
|
||||
aliPayTransferService.queryAccountAmount();
|
||||
return "ok";
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,40 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.alipay.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig;
|
||||
import com.alipay.api.domain.AlipayFundAccountQueryModel;
|
||||
import com.alipay.api.response.AlipayFundAccountQueryResponse;
|
||||
import com.ijpay.alipay.AliPayApi;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AliPayTransferService {
|
||||
|
||||
private final AliPayConfigService payConfigService;
|
||||
/**
|
||||
* 余额查询接口
|
||||
*/
|
||||
@SneakyThrows
|
||||
public void queryAccountAmount() {
|
||||
|
||||
AliPayConfig config = payConfigService.getAndCheckConfig();
|
||||
payConfigService.initConfig(config);
|
||||
AlipayFundAccountQueryModel model = new AlipayFundAccountQueryModel();
|
||||
model.setAccountType("ACCTRANS_ACCOUNT");
|
||||
model.setAlipayUserId(config.getAppId());
|
||||
AlipayFundAccountQueryResponse response = AliPayApi.accountQueryToResponse(model, null);
|
||||
System.out.println(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转账接口
|
||||
*/
|
||||
@SneakyThrows
|
||||
public void transfer() {
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package cn.bootx.platform.daxpay.service.core.order.transfer.convert;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@Mapper
|
||||
public interface TransferOrderConvert {
|
||||
TransferOrderConvert CONVERT = Mappers.getMapper(TransferOrderConvert.class);
|
||||
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
package cn.bootx.platform.daxpay.service.core.order.transfer.dao;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.transfer.entity.TransferOrder;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class TransferOrderManager extends BaseManager<TransferOrderMapper, TransferOrder> {
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package cn.bootx.platform.daxpay.service.core.order.transfer.dao;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.order.transfer.entity.TransferOrder;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@Mapper
|
||||
public interface TransferOrderMapper extends BaseMapper<TransferOrder> {
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package cn.bootx.platform.daxpay.service.core.order.transfer.entity;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 转账订单
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@DbTable(comment = "转账订单")
|
||||
@TableName("pay_transfer_order")
|
||||
public class TransferOrder extends MpBaseEntity {
|
||||
|
||||
/** 业务号 */
|
||||
private String outTradeNo;
|
||||
|
||||
/**
|
||||
* 支付通道
|
||||
* @see PayChannelEnum
|
||||
*/
|
||||
private String channel;
|
||||
|
||||
/** 金额 */
|
||||
private Integer amount;
|
||||
|
||||
/** 状态 */
|
||||
private String status;
|
||||
|
||||
/** 付款方 */
|
||||
private String payer;
|
||||
|
||||
/** 收款方 */
|
||||
private String payee;
|
||||
|
||||
/** 成功时间 */
|
||||
private LocalDateTime successTime;
|
||||
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package cn.bootx.platform.daxpay.service.core.order.transfer.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 转正订单服务
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TransferOrderService {
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.pay.result;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 策略和订单
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class StrategyAndOrder {
|
||||
|
||||
/** 支付订单 */
|
||||
private final PayOrder order;
|
||||
|
||||
/** 支付策略集合 */
|
||||
private final List<AbsPayStrategy> strategies;
|
||||
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.pay.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.RepetitiveOperationException;
|
||||
import cn.bootx.platform.common.core.function.CollectorsFunction;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayParam;
|
||||
@@ -9,6 +10,8 @@ import cn.bootx.platform.daxpay.result.pay.PayResult;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.builder.PayBuilder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
|
||||
@@ -19,20 +22,24 @@ import cn.bootx.platform.daxpay.util.PayUtil;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.baomidou.lock.LockInfo;
|
||||
import com.baomidou.lock.LockTemplate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PayStatusEnum.*;
|
||||
import static cn.bootx.platform.daxpay.code.PayStatusEnum.SUCCESS;
|
||||
|
||||
|
||||
/**
|
||||
@@ -50,6 +57,8 @@ public class PayService {
|
||||
|
||||
private final PayAssistService payAssistService;
|
||||
|
||||
private final PayChannelOrderManager channelOrderManager;
|
||||
|
||||
private final ClientNoticeService clientNoticeService;
|
||||
|
||||
private final LockTemplate lockTemplate;
|
||||
@@ -62,6 +71,8 @@ public class PayService {
|
||||
* 注意:
|
||||
* 组合支付在非第一次支付的时候,只对新传入的异步支付通道进行处理,该通道的价格使用第一次发起的价格,旧的同步支付如果传入后也不做处理,
|
||||
* 支付单中支付通道列表将会为 旧有的同步支付+新传入的异步支付方式(在具体支付实现中处理)
|
||||
*
|
||||
* 订单数据会先进行入库, 才会进行发起支付, 在调用各通道支付之前发生错误, 数据不会入库
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public PayResult pay(PayParam payParam) {
|
||||
@@ -81,18 +92,38 @@ public class PayService {
|
||||
// 初始化上下文
|
||||
payAssistService.initPayContext(payOrder, payParam);
|
||||
|
||||
// 异步支付且非第一次支付
|
||||
if (Objects.nonNull(payOrder) && payOrder.isAsyncPay()) {
|
||||
return this.paySyncNotFirst(payParam, payOrder);
|
||||
// 订单为空, 创建支付订单和通道支付订单
|
||||
if (Objects.isNull(payOrder)){
|
||||
// 预支付处理, 无论请求成功还是失败, 各种订单对象都会保存
|
||||
List<AbsPayStrategy> strategies = SpringUtil.getBean(this.getClass()).prePay(payParam);
|
||||
// 执行首次支付逻辑
|
||||
return this.onePay(strategies);
|
||||
} else {
|
||||
// 第一次发起支付或同步支付
|
||||
return this.firstPay(payParam, payOrder);
|
||||
// 分为同步通道全部支付成功和所有支付都是支付中状态(上次支付失败)
|
||||
return this.towPay(payParam, payOrder);
|
||||
}
|
||||
} finally {
|
||||
lockTemplate.releaseLock(lock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 组合支付分为同步通道全部支付成功和所有支付都是支付中状态(上次支付失败)
|
||||
* 单通道支付不需要区分上次支付发起是否成功
|
||||
*/
|
||||
private PayResult towPay(PayParam payParam, PayOrder payOrder) {
|
||||
// 判断是否组合支付且同时包含异步支付
|
||||
if (payOrder.isCombinationPay()&&payOrder.isAsyncPay()) {
|
||||
// 同步支付通道全部支付成功, 单独走异步支付支付流程
|
||||
this.onlyAsyncPay(payParam, payOrder);
|
||||
// 通道订单全部支付中, 相当于上次支付异常, 重新走支付流程
|
||||
return this.allPay(payParam, payOrder);
|
||||
} else {
|
||||
// 单通道支付走标准支付流程
|
||||
return this.allPay(payParam, payOrder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单下单, 可以视为不支持组合支付的下单接口
|
||||
*/
|
||||
@@ -111,14 +142,46 @@ public class PayService {
|
||||
return this.pay(payParam);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 预支付处理, 无论请求成功还是失败, 各种订单对象都会保存
|
||||
* 1. 校验参数
|
||||
* 2. 创建支付订单/通道支付订单/扩展信息
|
||||
* 3, 返回数据
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
|
||||
public List<AbsPayStrategy> prePay(PayParam payParam){
|
||||
|
||||
// 价格检测
|
||||
PayUtil.validationAmount(payParam.getPayChannels());
|
||||
|
||||
// 创建支付订单和扩展记录并返回支付订单对象
|
||||
PayOrder payOrder = payAssistService.createPayOrder(payParam);
|
||||
|
||||
// 获取支付方式,通过工厂生成对应的策略组
|
||||
List<AbsPayStrategy> strategies = PayStrategyFactory.createAsyncLast(payParam.getPayChannels());
|
||||
if (CollectionUtil.isEmpty(strategies)) {
|
||||
throw new PayUnsupportedMethodException();
|
||||
}
|
||||
// 初始化支付的参数
|
||||
for (AbsPayStrategy strategy : strategies) {
|
||||
strategy.initPayParam(payOrder, payParam);
|
||||
}
|
||||
|
||||
// 执行支付前处理动作
|
||||
strategies.forEach(AbsPayStrategy::doBeforePayHandler);
|
||||
// 执行通道支付通道订单的生成
|
||||
strategies.forEach(AbsPayStrategy::generateChannelOrder);
|
||||
|
||||
// 保存通道支付订单
|
||||
payAssistService.savePayChannelOrder(strategies);
|
||||
return strategies;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起的第一次支付请求(同步/异步)
|
||||
*/
|
||||
private PayResult firstPay(PayParam payParam, PayOrder payOrder) {
|
||||
// 1. 已经发起过支付情况直接返回支付结果
|
||||
if (Objects.nonNull(payOrder)) {
|
||||
return PayBuilder.buildPayResultByPayOrder(payOrder);
|
||||
}
|
||||
|
||||
// 2. 价格检测
|
||||
PayUtil.validationAmount(payParam.getPayChannels());
|
||||
@@ -127,48 +190,40 @@ public class PayService {
|
||||
payOrder = payAssistService.createPayOrder(payParam);
|
||||
|
||||
// 4. 调用支付方法进行发起支付
|
||||
this.firstPayHandler(payParam, payOrder);
|
||||
this.allPay(payParam, payOrder);
|
||||
|
||||
// 5. 返回支付结果
|
||||
return PayBuilder.buildPayResultByPayOrder(payOrder);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行第一次发起支付的方法
|
||||
* 执行首次支付操作
|
||||
*/
|
||||
private void firstPayHandler(PayParam payParam, PayOrder payOrder) {
|
||||
|
||||
// 1.获取支付方式,通过工厂生成对应的策略组
|
||||
List<AbsPayStrategy> strategies = PayStrategyFactory.createAsyncLast(payParam.getPayChannels());
|
||||
if (CollectionUtil.isEmpty(strategies)) {
|
||||
throw new PayUnsupportedMethodException();
|
||||
public PayResult onePay(List<AbsPayStrategy> strategies){
|
||||
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
|
||||
// 支付操作
|
||||
try {
|
||||
strategies.forEach(AbsPayStrategy::doPayHandler);
|
||||
} catch (Exception e) {
|
||||
// 记录错误原因
|
||||
PayOrderExtra payOrderExtra = payInfo.getPayOrderExtra();
|
||||
payOrderExtra.setErrorMsg(e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
PayOrder payOrder = payInfo.getPayOrder();
|
||||
|
||||
// 2.初始化支付的参数
|
||||
for (AbsPayStrategy strategy : strategies) {
|
||||
strategy.initPayParam(payOrder, payParam);
|
||||
}
|
||||
|
||||
// 3.1 执行支付前处理动作
|
||||
strategies.forEach(AbsPayStrategy::doBeforePayHandler);
|
||||
// 3.2 执行通道支付单的生成动作
|
||||
strategies.forEach(AbsPayStrategy::generateChannelOrder);
|
||||
|
||||
// 4.1 支付操作
|
||||
strategies.forEach(AbsPayStrategy::doPayHandler);
|
||||
// 4.2 支付调用成功操作, 进行扣款、创建记录类类似的操作
|
||||
// 支付调用成功操作, 进行扣款、创建记录类类似的操作
|
||||
strategies.forEach(AbsPayStrategy::doSuccessHandler);
|
||||
// 4.3 保存通道支付订单
|
||||
payAssistService.savePayChannelOrder(strategies);
|
||||
|
||||
// 5.1 如果没有异步支付, 直接进行订单完成处理
|
||||
if (PayUtil.isNotSync(payParam.getPayChannels())) {
|
||||
// 如果没有异步支付, 直接进行订单完成处理
|
||||
if (!payOrder.isAsyncPay()) {
|
||||
// 修改支付订单状态为成功
|
||||
payOrder.setStatus(SUCCESS.getCode())
|
||||
.setPayTime(LocalDateTime.now());
|
||||
payOrderService.updateById(payOrder);
|
||||
}
|
||||
// 5.2 如果异步支付完成, 进行订单完成处理, 同时发送回调消息
|
||||
// 如果异步支付完成, 进行订单完成处理, 同时发送回调消息
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
if (asyncPayInfo.isPayComplete()) {
|
||||
payOrder.setGatewayOrderNo(asyncPayInfo.getGatewayOrderNo())
|
||||
@@ -179,22 +234,78 @@ public class PayService {
|
||||
|
||||
// 如果支付完成 发送通知
|
||||
if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){
|
||||
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
|
||||
clientNoticeService.registerPayNotice(payOrder, payInfo.getPayOrderExtra(), payInfo.getPayChannelOrders());
|
||||
}
|
||||
// 组装返回参数
|
||||
return PayBuilder.buildPayResultByPayOrder(payOrder);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 执行所有的支付方法
|
||||
*/
|
||||
private PayResult allPay(PayParam payParam, PayOrder payOrder) {
|
||||
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
|
||||
|
||||
// 获取支付方式,通过工厂生成对应的策略组
|
||||
List<AbsPayStrategy> strategies = PayStrategyFactory.createAsyncLast(payParam.getPayChannels());
|
||||
if (CollectionUtil.isEmpty(strategies)) {
|
||||
throw new PayUnsupportedMethodException();
|
||||
}
|
||||
// 查询通道支付订单
|
||||
List<PayChannelOrder> orders = channelOrderManager.findAllByPaymentId(payOrder.getId());
|
||||
Map<String, PayChannelOrder> channelOrderMap = orders.stream()
|
||||
.collect(Collectors.toMap(PayChannelOrder::getChannel, Function.identity(), CollectorsFunction::retainFirst));
|
||||
|
||||
// 初始化支付参数
|
||||
for (AbsPayStrategy strategy : strategies) {
|
||||
strategy.initPayParam(payOrder, payParam);
|
||||
strategy.setChannelOrder(channelOrderMap.get(strategy.getChannel().getCode()));
|
||||
}
|
||||
|
||||
// 执行支付前处理动作
|
||||
strategies.forEach(AbsPayStrategy::doBeforePayHandler);
|
||||
// 支付操作
|
||||
|
||||
try {
|
||||
strategies.forEach(AbsPayStrategy::doPayHandler);
|
||||
} catch (Exception e) {
|
||||
// 记录错误原因
|
||||
PayOrderExtra payOrderExtra = payInfo.getPayOrderExtra();
|
||||
payOrderExtra.setErrorMsg(e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
|
||||
// 支付调用成功操作, 进行扣款、创建记录类类似的操作
|
||||
strategies.forEach(AbsPayStrategy::doSuccessHandler);
|
||||
|
||||
// 如果没有异步支付, 直接进行订单完成处理
|
||||
if (PayUtil.isNotSync(payParam.getPayChannels())) {
|
||||
// 修改支付订单状态为成功
|
||||
payOrder.setStatus(SUCCESS.getCode())
|
||||
.setPayTime(LocalDateTime.now());
|
||||
payOrderService.updateById(payOrder);
|
||||
}
|
||||
// 如果异步支付完成, 进行订单完成处理, 同时发送回调消息
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
if (asyncPayInfo.isPayComplete()) {
|
||||
payOrder.setGatewayOrderNo(asyncPayInfo.getGatewayOrderNo())
|
||||
.setStatus(SUCCESS.getCode())
|
||||
.setPayTime(LocalDateTime.now());
|
||||
payOrderService.updateById(payOrder);
|
||||
}
|
||||
|
||||
// 如果支付完成 发送通知
|
||||
if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){
|
||||
clientNoticeService.registerPayNotice(payOrder, payInfo.getPayOrderExtra(), payInfo.getPayChannelOrders());
|
||||
}
|
||||
return PayBuilder.buildPayResultByPayOrder(payOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步支付执行(非第一次请求), 只执行异步支付策略, 因为同步支付已经支付成功. 报错不影响继续发起支付
|
||||
*/
|
||||
private PayResult paySyncNotFirst(PayParam payParam, PayOrder payOrder) {
|
||||
|
||||
// 1. 处理支付结束情况(完成/退款/关闭/错误)
|
||||
List<String> trades = Arrays.asList(SUCCESS.getCode(), CLOSE.getCode(), PARTIAL_REFUND.getCode(),
|
||||
REFUNDED.getCode(), REFUNDING.getCode(), FAIL.getCode());
|
||||
if (trades.contains(payOrder.getStatus())) {
|
||||
return PayBuilder.buildPayResultByPayOrder(payOrder);
|
||||
}
|
||||
private PayResult onlyAsyncPay(PayParam payParam, PayOrder payOrder) {
|
||||
|
||||
// 2.获取 异步支付通道,通过工厂生成对应的策略组(只包含异步支付的策略, 同步支付已经成功不再继续执行)
|
||||
PayChannelParam payChannelParam = payAssistService.getAsyncPayParam(payParam, payOrder);
|
||||
|
@@ -95,6 +95,7 @@ public class AliPayStrategy extends AbsPayStrategy {
|
||||
*/
|
||||
@Override
|
||||
public void generateChannelOrder() {
|
||||
super.generateChannelOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -98,6 +98,7 @@ public class UnionPayStrategy extends AbsPayStrategy {
|
||||
*/
|
||||
@Override
|
||||
public void generateChannelOrder() {
|
||||
super.generateChannelOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -104,7 +104,9 @@ public class WeChatPayStrategy extends AbsPayStrategy {
|
||||
* 不使用默认的生成通道支付单方法, 异步支付通道的支付订单自己管理
|
||||
*/
|
||||
@Override
|
||||
public void generateChannelOrder() {}
|
||||
public void generateChannelOrder() {
|
||||
super.generateChannelOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化微信支付
|
||||
|
@@ -0,0 +1,12 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.transfer.factory;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
/**
|
||||
* 转账工具类
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@UtilityClass
|
||||
public class TransferFactory {
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.transfer.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 转账服务
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TransferService {
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.transfer.strategy;
|
||||
|
||||
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.AliPayConfigService;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayTransferService;
|
||||
import cn.bootx.platform.daxpay.service.func.AbsTransferStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
|
||||
|
||||
/**
|
||||
* 支付宝转账测策略
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Scope(SCOPE_PROTOTYPE)
|
||||
@RequiredArgsConstructor
|
||||
public class AliPayTransferStrategy extends AbsTransferStrategy {
|
||||
|
||||
private final AliPayConfigService payConfigService;
|
||||
|
||||
private final AliPayTransferService aliPayTransferService;
|
||||
|
||||
private AliPayConfig config;
|
||||
|
||||
/**
|
||||
* 策略标识
|
||||
*/
|
||||
@Override
|
||||
public PayChannelEnum getChannel() {
|
||||
return PayChannelEnum.ALI;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转账前操作
|
||||
*/
|
||||
@Override
|
||||
public void doBeforeHandler() {
|
||||
this.config = payConfigService.getAndCheckConfig();
|
||||
payConfigService.initConfig(this.config);
|
||||
}
|
||||
|
||||
}
|
@@ -58,8 +58,7 @@ public abstract class AbsPayStrategy implements PayStrategy{
|
||||
* 支付调起成功的处理方式
|
||||
*/
|
||||
public void doSuccessHandler() {
|
||||
this.channelOrder.setStatus(PayStatusEnum.SUCCESS.getCode())
|
||||
.setPayTime(LocalDateTime.now());
|
||||
this.channelOrder.setStatus(PayStatusEnum.SUCCESS.getCode()).setPayTime(LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -0,0 +1,23 @@
|
||||
package cn.bootx.platform.daxpay.service.func;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.order.transfer.entity.TransferOrder;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* 转账抽象策略
|
||||
* @author xxm
|
||||
* @since 2024/3/21
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public abstract class AbsTransferStrategy implements PayStrategy{
|
||||
/** 转账订单 */
|
||||
private TransferOrder transferOrder;
|
||||
|
||||
/**
|
||||
* 转账前操作
|
||||
*/
|
||||
public void doBeforeHandler(){}
|
||||
|
||||
}
|
@@ -40,6 +40,12 @@
|
||||
<artifactId>daxpay-single-demo</artifactId>
|
||||
<version>${daxpay.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.afterturn</groupId>
|
||||
<artifactId>easypoi-spring-boot-starter</artifactId>
|
||||
<version>4.4.0</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
<build>
|
||||
|
Reference in New Issue
Block a user