feat 调整通道支付单相关关系

This commit is contained in:
bootx
2024-01-23 23:35:21 +08:00
parent b64b481945
commit a5c0de1ca1
31 changed files with 205 additions and 241 deletions

View File

@@ -26,7 +26,7 @@ public class AsyncPayLocal {
* 1. 如付款码支付直接成功时会出现
* 2. 回调或者支付同步时也会有这个值
*/
private String tradeNo;
private String gatewayOrderNo;
/** 支付参数体(通常用于发起支付的参数) */

View File

@@ -14,6 +14,7 @@ import java.util.Optional;
* @author xxm
* @since 2021/2/26
*/
@Deprecated
@Repository
@RequiredArgsConstructor
public class AliPayOrderManager extends BaseManager<AliPayOrderMapper, AliPayOrder> {

View File

@@ -10,6 +10,7 @@ import org.apache.ibatis.annotations.Mapper;
* @author xxm
* @since 2021/2/26
*/
@Deprecated
@Mapper
public interface AliPayOrderMapper extends BaseMapper<AliPayOrder> {

View File

@@ -19,6 +19,7 @@ import lombok.experimental.Accessors;
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Deprecated
@Accessors(chain = true)
@DbTable(comment = "支付宝支付记录")
@TableName("pay_alipay_order")

View File

@@ -104,7 +104,7 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
public void initContext() {
Map<String, String> callbackParam = PaymentContextLocal.get().getCallbackParam();
// 订单号
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(callbackParam.get(TRADE_NO));
PaymentContextLocal.get().getAsyncPayInfo().setGatewayOrderNo(callbackParam.get(TRADE_NO));
// 支付时间
String gmpTime = callbackParam.get(GMT_PAYMENT);
if (StrUtil.isNotBlank(gmpTime)) {

View File

@@ -42,7 +42,7 @@ public class AliPayOrderService {
public void updatePaySuccess(PayOrder payOrder, PayChannelParam payChannelParam) {
// 更新支付宝异步支付类型信息
payOrder.setAsyncPay(true).setAsyncChannel(PayChannelEnum.ALI.getCode());
payChannelOrderService.updateChannel(payChannelParam,payOrder);
payChannelOrderService.updateAsyncChannelOrder(payOrder,payChannelParam);
// 更新支付宝可退款类型信息
List<RefundableInfo> refundableInfos = payOrder.getRefundableInfos();
@@ -61,6 +61,7 @@ public class AliPayOrderService {
/**
* 更新异步支付记录成功状态, 并创建支付宝支付记录
*/
@Deprecated
public void updateAsyncSuccess(PayOrder payOrder, Integer amount) {
// 创建支付宝支付订单
this.createAliPayOrder(payOrder,amount);
@@ -69,10 +70,11 @@ public class AliPayOrderService {
/**
* 创建支付宝支付订单(支付成功后才会创建)
*/
@Deprecated
private void createAliPayOrder(PayOrder payOrder, Integer amount) {
String tradeNo = PaymentContextLocal.get()
.getAsyncPayInfo()
.getTradeNo();
.getGatewayOrderNo();
AliPayOrder aliPayOrder = new AliPayOrder();
aliPayOrder.setTradeNo(tradeNo)

View File

@@ -88,7 +88,7 @@ public class AliPayService {
// 付款码支付
else if (Objects.equals(payChannelParam.getWay(), PayWayEnum.BARCODE.getCode())) {
String tradeNo = this.barCode(amount, payOrder, aliPayParam, alipayConfig);
asyncPayInfo.setTradeNo(tradeNo);
asyncPayInfo.setGatewayOrderNo(tradeNo);
}
// 通常是发起支付的参数
asyncPayInfo.setPayBody(payBody);

View File

@@ -51,7 +51,7 @@ public class AliPaySyncService {
syncResult.setSyncPayInfo(JSONUtil.toJsonStr(response));
// 支付完成 TODO 部分退款也在这个地方, 但无法进行区分, 需要借助对账进行处理
if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_SUCCESS) || Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_FINISHED)) {
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(response.getTradeNo());
PaymentContextLocal.get().getAsyncPayInfo().setGatewayOrderNo(response.getTradeNo());
// 支付完成时间
LocalDateTime payTime = LocalDateTimeUtil.of(response.getSendPayDate());
PaymentContextLocal.get().getAsyncPayInfo().setPayTime(payTime);

View File

@@ -106,7 +106,7 @@ public class WeChatPayCallbackService extends AbsPayCallbackStrategy {
public void initContext() {
Map<String, String> callbackParam = PaymentContextLocal.get().getCallbackParam();
// 订单号
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(callbackParam.get(WeChatPayCode.TRANSACTION_ID));
PaymentContextLocal.get().getAsyncPayInfo().setGatewayOrderNo(callbackParam.get(WeChatPayCode.TRANSACTION_ID));
// 支付时间
String timeEnd = callbackParam.get(TIME_END);
if (StrUtil.isNotBlank(timeEnd)) {

View File

@@ -2,20 +2,17 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.service;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.entity.RefundableInfo;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.channel.wechat.dao.WeChatPayOrderManager;
import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -30,8 +27,6 @@ import java.util.Optional;
@RequiredArgsConstructor
public class WeChatPayOrderService {
private final PayOrderService payOrderService;
private final PayChannelOrderService payChannelOrderService;
private final WeChatPayOrderManager weChatPayOrderManager;
@@ -40,19 +35,10 @@ public class WeChatPayOrderService {
* 支付调起成功 更新payment中异步支付类型信息, 如果支付完成, 创建微信支付单
*/
public void updatePaySuccess(PayOrder payOrder, PayChannelParam payChannelParam) {
payOrder.setAsyncPay(true).setAsyncChannel(PayChannelEnum.WECHAT.getCode());
payOrder.setAsyncPay(true)
.setAsyncChannel(PayChannelEnum.WECHAT.getCode());
payChannelOrderService.updateAsyncChannelOrder(payOrder,payChannelParam);
payChannelOrderService.updateChannel(payChannelParam,payOrder);
// 更新微信可退款类型信息
List<RefundableInfo> refundableInfos = payOrder.getRefundableInfos();
refundableInfos.removeIf(payTypeInfo -> PayChannelEnum.ASYNC_TYPE_CODE.contains(payTypeInfo.getChannel()));
refundableInfos.add(new RefundableInfo()
.setChannel(PayChannelEnum.WECHAT.getCode())
.setAmount(payChannelParam.getAmount())
);
payOrder.setRefundableInfos(refundableInfos);
// 如果支付完成(付款码情况) 调用 updateSyncSuccess 创建微信支付记录
if (Objects.equals(payOrder.getStatus(), PayStatusEnum.SUCCESS.getCode())) {
this.createWeChatOrder(payOrder, payChannelParam.getAmount());
}
@@ -71,7 +57,7 @@ public class WeChatPayOrderService {
private void createWeChatOrder(PayOrder payOrder, int amount) {
String tradeNo = PaymentContextLocal.get()
.getAsyncPayInfo()
.getTradeNo();
.getGatewayOrderNo();
// 创建微信支付记录
WeChatPayOrder wechatPayOrder = new WeChatPayOrder();
wechatPayOrder.setTradeNo(tradeNo)

View File

@@ -105,7 +105,7 @@ public class WeChatPayService {
// 付款码支付
else if (payWayEnum == PayWayEnum.BARCODE) {
String tradeNo = this.barCode(totalFee, payOrder, weChatPayParam.getAuthCode(), weChatPayConfig);
asyncPayInfo.setTradeNo(tradeNo);
asyncPayInfo.setGatewayOrderNo(tradeNo);
}
asyncPayInfo.setPayBody(payBody);
}

View File

@@ -31,10 +31,10 @@ import java.util.stream.Collectors;
* @since 2021/2/25
*/
@UtilityClass
public class PaymentBuilder {
public class PayBuilder {
/**
* 构建payment记录
* 构建支付订单
*/
public PayOrder buildPayOrder(PayParam payParam) {
// 订单超时时间
@@ -42,6 +42,7 @@ public class PaymentBuilder {
.getAsyncPayInfo()
.getExpiredTime();
// 可退款信息
@Deprecated
List<RefundableInfo> refundableInfos = buildRefundableInfo(payParam.getPayChannels());
// 计算总价
int sumAmount = payParam.getPayChannels().stream()
@@ -93,22 +94,20 @@ public class PaymentBuilder {
/**
* 构建订单关联通道信息
*/
public List<PayChannelOrder> buildPayChannel(List<PayChannelParam> payChannelParams) {
if (CollectionUtil.isEmpty(payChannelParams)) {
return Collections.emptyList();
}
return payChannelParams.stream()
.map(o-> new PayChannelOrder()
.setChannel(o.getChannel())
.setPayWay(o.getWay())
.setAmount(o.getAmount())
.setChannelExtra(o.getChannelExtra()))
.collect(Collectors.toList());
public PayChannelOrder buildPayChannelOrder(PayChannelParam channelParam) {
return new PayChannelOrder()
.setAsync(PayChannelEnum.ASYNC_TYPE_CODE.contains(channelParam.getChannel()))
.setChannel(channelParam.getChannel())
.setPayWay(channelParam.getWay())
.setAmount(channelParam.getAmount())
.setRefundableBalance(channelParam.getAmount())
.setChannelExtra(channelParam.getChannelExtra());
}
/**
* 构建支付订单的可退款信息列表
*/
@Deprecated
private List<RefundableInfo> buildRefundableInfo(List<PayChannelParam> payChannelParamList) {
if (CollectionUtil.isEmpty(payChannelParamList)) {
return Collections.emptyList();
@@ -141,18 +140,4 @@ public class PaymentBuilder {
}
return paymentResult;
}
/**
* 根据新的新传入的支付参数和支付订单构建出当前需要支付参数
* 主要是针对其中的异步支付参数进行处理
*
* @param newPayParam 新传入的参数
* @param payOrder 支付订单
* @return PayParam 支付参数
*/
public PayParam buildPayParam(PayParam newPayParam, PayOrder payOrder) {
return null;
}
}

View File

@@ -4,7 +4,7 @@ import cn.bootx.platform.daxpay.result.order.PayOrderChannelResult;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayChanneOrderlDto;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayChannelOrderDto;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderExtraDto;
import org.mapstruct.Mapper;
@@ -23,7 +23,7 @@ public interface PayOrderConvert {
PayOrderDto convert(PayOrder in);
PayChanneOrderlDto convert(PayChannelOrder in);
PayChannelOrderDto convert(PayChannelOrder in);
PayOrderChannelResult convertResult(PayChannelOrder in);
}

View File

@@ -7,7 +7,7 @@ import cn.bootx.platform.daxpay.param.channel.VoucherPayParam;
import cn.bootx.platform.daxpay.param.channel.WalletPayParam;
import cn.bootx.platform.daxpay.param.channel.WeChatPayParam;
import cn.bootx.platform.daxpay.service.core.order.pay.convert.PayOrderConvert;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayChanneOrderlDto;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayChannelOrderDto;
import cn.bootx.table.modify.annotation.DbColumn;
import cn.bootx.table.modify.annotation.DbTable;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -24,8 +24,8 @@ import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@DbTable(comment = "支付订单关联支付时通道信息")
@TableName("pay_order_channel")
public class PayChannelOrder extends MpCreateEntity implements EntityBaseFunction<PayChanneOrderlDto> {
@TableName("pay_channel_order")
public class PayChannelOrder extends MpCreateEntity implements EntityBaseFunction<PayChannelOrderDto> {
@DbColumn(comment = "支付id")
private Long paymentId;
@@ -33,15 +33,24 @@ public class PayChannelOrder extends MpCreateEntity implements EntityBaseFunctio
@DbColumn(comment = "通道")
private String channel;
@DbColumn(comment = "金额")
private Integer amount;
@DbColumn(comment = "可退款余额")
private Integer refundableBalance;
/**
* 异步支付通道发给网关的退款号, 用与将记录关联起来
*/
@DbColumn(comment = "关联网关支付号")
private String gatewayOrderNo;
@DbColumn(comment = "支付方式")
private String payWay;
@DbColumn(comment = "异步支付方式")
private boolean async;
@DbColumn(comment = "金额")
private Integer amount;
/**
* @see AliPayParam
* @see WeChatPayParam
@@ -55,7 +64,7 @@ public class PayChannelOrder extends MpCreateEntity implements EntityBaseFunctio
* 转换
*/
@Override
public PayChanneOrderlDto toDto() {
public PayChannelOrderDto toDto() {
return PayOrderConvert.CONVERT.convert(this);
}
}

View File

@@ -76,6 +76,7 @@ public class PayOrder extends MpBaseEntity implements EntityBaseFunction<PayOrde
@BigField
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
@DbColumn(comment = "退款信息列表")
@Deprecated
private List<RefundableInfo> refundableInfos;
/**

View File

@@ -4,9 +4,9 @@ import cn.bootx.platform.common.core.util.ResultConvertUtil;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayChanneOrderlDto;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.dto.order.pay.PayChannelOrderDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -29,15 +29,15 @@ public class PayChannelOrderService {
/**
* 根据支付ID查询列表
*/
public List<PayChanneOrderlDto> findAllByPaymentId(Long paymentId){
public List<PayChannelOrderDto> findAllByPaymentId(Long paymentId){
return ResultConvertUtil.dtoListConvert(payChannelOrderManager.findAllByPaymentId(paymentId));
}
/**
* 更新支付订单的通道信息
* 更新支付订单的异步通道信息
*/
@Transactional(rollbackFor = Exception.class)
public void updateChannel(PayChannelParam payChannelParam, PayOrder payOrder){
public void updateAsyncChannelOrder(PayOrder payOrder, PayChannelParam payChannelParam){
Optional<PayChannelOrder> payOrderChannelOpt = payChannelOrderManager.findByPaymentIdAndChannel(payOrder.getId(), PayChannelEnum.WECHAT.getCode());
if (!payOrderChannelOpt.isPresent()){
payChannelOrderManager.deleteByPaymentIdAndAsync(payOrder.getId());
@@ -45,6 +45,7 @@ public class PayChannelOrderService {
.setPaymentId(payOrder.getId())
.setChannel(PayChannelEnum.ALI.getCode())
.setAmount(payChannelParam.getAmount())
.setRefundableBalance(payChannelParam.getAmount())
.setPayWay(payChannelParam.getWay())
.setChannelExtra(payChannelParam.getChannelExtra())
.setAsync(true)
@@ -56,4 +57,14 @@ public class PayChannelOrderService {
payChannelOrderManager.updateById(payOrderChannelOpt.get());
}
}
/**
* 支付调起成功 更新payment中异步支付类型信息, 如果支付完成, 创建支付宝支付单
*/
@Transactional(rollbackFor = Exception.class)
public void updatePaySuccess(PayOrder payOrder, PayChannelParam payChannelParam) {
// 更新支付宝异步支付类型信息
this.updateAsyncChannelOrder(payOrder, payChannelParam);
}
}

View File

@@ -33,7 +33,7 @@ public class PayRefundChannelOrder extends MpBaseEntity implements EntityBaseFun
* 异步支付通道发给网关的退款号, 用与将记录关联起来
*/
@DbColumn(comment = "关联网关退款号")
private String gatewayRequestNo;
private String gatewayOrderNo;
@DbColumn(comment = "通道")
private String channel;

View File

@@ -5,21 +5,21 @@ import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.pay.PayParam;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.param.pay.PayParam;
import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
import cn.bootx.platform.daxpay.service.common.context.NoticeLocal;
import cn.bootx.platform.daxpay.service.common.context.PlatformLocal;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
import cn.bootx.platform.daxpay.service.core.payment.sync.service.PaySyncService;
import cn.bootx.platform.daxpay.service.core.order.pay.builder.PaymentBuilder;
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.dao.PayOrderExtraManager;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
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.PayOrderQueryService;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
import cn.bootx.platform.daxpay.service.core.payment.sync.service.PaySyncService;
import cn.bootx.platform.daxpay.util.PayUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
@@ -30,7 +30,6 @@ import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 支付支持服务
@@ -138,17 +137,11 @@ public class PayAssistService {
*/
public PayOrder createPayOrder(PayParam payParam) {
// 构建支付订单并保存
PayOrder payOrder = PaymentBuilder.buildPayOrder(payParam);
PayOrder payOrder = PayBuilder.buildPayOrder(payParam);
payOrderService.save(payOrder);
// 构建支付订单扩展表并保存
PayOrderExtra payOrderExtra = PaymentBuilder.buildPayOrderExtra(payParam, payOrder.getId());
PayOrderExtra payOrderExtra = PayBuilder.buildPayOrderExtra(payParam, payOrder.getId());
payOrderExtraManager.save(payOrderExtra);
// 构建支付通道表并保存
List<PayChannelOrder> payChannelOrders = PaymentBuilder.buildPayChannel(payParam.getPayChannels())
.stream()
.peek(o -> o.setPaymentId(payOrder.getId()).setAsync(payOrder.isAsyncPay()))
.collect(Collectors.toList());
payChannelOrderManager.saveAll(payChannelOrders);
return payOrder;
}

View File

@@ -7,8 +7,10 @@ import cn.bootx.platform.daxpay.param.pay.PayParam;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.param.pay.SimplePayParam;
import cn.bootx.platform.daxpay.result.pay.PayResult;
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.payment.pay.factory.PayStrategyFactory;
import cn.bootx.platform.daxpay.service.core.order.pay.builder.PaymentBuilder;
import cn.bootx.platform.daxpay.service.core.order.pay.builder.PayBuilder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
@@ -27,6 +29,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
@@ -44,6 +47,8 @@ public class PayService {
private final PayAssistService payAssistService;
private final PayChannelOrderManager payChannelOrderManager;
private final LockTemplate lockTemplate;
/**
@@ -109,20 +114,20 @@ public class PayService {
private PayResult firstPay(PayParam payParam, PayOrder payOrder) {
// 1. 已经发起过支付情况直接返回支付结果
if (Objects.nonNull(payOrder)) {
return PaymentBuilder.buildPayResultByPayOrder(payOrder);
return PayBuilder.buildPayResultByPayOrder(payOrder);
}
// 2. 价格检测
PayUtil.validationAmount(payParam.getPayChannels());
// 3. 创建支付相关的记录并返回支付订单对象
// 3. 创建支付订单和扩展记录并返回支付订单对象
payOrder = payAssistService.createPayOrder(payParam);
// 4. 调用支付方法进行发起支付
this.firstPayHandler(payParam, payOrder);
// 5. 返回支付结果
return PaymentBuilder.buildPayResultByPayOrder(payOrder);
return PayBuilder.buildPayResultByPayOrder(payOrder);
}
/**
@@ -131,31 +136,36 @@ public class PayService {
private void firstPayHandler(PayParam payParam, PayOrder payOrder) {
// 1.获取支付方式,通过工厂生成对应的策略组
List<AbsPayStrategy> paymentStrategyList = PayStrategyFactory.createAsyncLast(payParam.getPayChannels());
if (CollectionUtil.isEmpty(paymentStrategyList)) {
List<AbsPayStrategy> payStrategyList = PayStrategyFactory.createAsyncLast(payParam.getPayChannels());
if (CollectionUtil.isEmpty(payStrategyList)) {
throw new PayUnsupportedMethodException();
}
// 2.初始化支付的参数
for (AbsPayStrategy paymentStrategy : paymentStrategyList) {
for (AbsPayStrategy paymentStrategy : payStrategyList) {
paymentStrategy.initPayParam(payOrder, payParam);
}
// 3.支付前准备, 执行支付前处理
this.doHandler(payOrder, paymentStrategyList, AbsPayStrategy::doBeforePayHandler, null);
// 3.执行支付前处理动作
payStrategyList.forEach(AbsPayStrategy::doBeforePayHandler);
// 4.支付操作
this.doHandler(payOrder, paymentStrategyList, AbsPayStrategy::doPayHandler, (strategies, payOrderObj) -> {
// 发起支付成功进行的执行方法
strategies.forEach(AbsPayStrategy::doSuccessHandler);
// 所有支付方式都是同步时, 对支付订单进行处理
if (PayUtil.isNotSync(payParam.getPayChannels())) {
// 修改支付订单状态为成功
payOrderObj.setStatus(PayStatusEnum.SUCCESS.getCode());
payOrderObj.setPayTime(LocalDateTime.now());
}
payOrderService.updateById(payOrderObj);
});
// 4.1 支付操作
payStrategyList.forEach(AbsPayStrategy::doPayHandler);
// 4.2 支付调用成功操作, 进行扣款、创建记录类类似的操作
payStrategyList.forEach(AbsPayStrategy::doSuccessHandler);
// 4.3 获取通道支付订单进行保存
List<PayChannelOrder> channelOrders = payStrategyList.stream()
.map(AbsPayStrategy::generateChannelOrder)
.collect(Collectors.toList());
payChannelOrderManager.saveAll(channelOrders);
// 5. 如果没有异步支付, 直接进行成功处理
if (PayUtil.isNotSync(payParam.getPayChannels())) {
// 修改支付订单状态为成功
payOrder.setStatus(PayStatusEnum.SUCCESS.getCode());
payOrder.setPayTime(LocalDateTime.now());
payOrderService.updateById(payOrder);
}
}
/**
@@ -167,35 +177,31 @@ public class PayService {
List<String> trades = Arrays.asList(PayStatusEnum.SUCCESS.getCode(), PayStatusEnum.CLOSE.getCode(),
PayStatusEnum.PARTIAL_REFUND.getCode(), PayStatusEnum.REFUNDED.getCode());
if (trades.contains(payOrder.getStatus())) {
return PaymentBuilder.buildPayResultByPayOrder(payOrder);
return PayBuilder.buildPayResultByPayOrder(payOrder);
}
// 2.获取 异步支付通道,通过工厂生成对应的策略组(只包含异步支付的策略, 同步支付相关逻辑不再进行执行)
PayChannelParam payChannelParam = payAssistService.getAsyncPayParam(payParam, payOrder);
List<AbsPayStrategy> asyncStrategyList = PayStrategyFactory.createAsyncLast(Collections.singletonList(payChannelParam));
List<AbsPayStrategy> payStrategyList = PayStrategyFactory.createAsyncLast(Collections.singletonList(payChannelParam));
// 3.初始化支付的参数
for (AbsPayStrategy paymentStrategy : asyncStrategyList) {
paymentStrategy.initPayParam(payOrder, payParam);
for (AbsPayStrategy payStrategy : payStrategyList) {
payStrategy.initPayParam(payOrder, payParam);
}
// 4.支付前准备
this.doHandler(payOrder, asyncStrategyList, AbsPayStrategy::doBeforePayHandler, null);
payStrategyList.forEach(AbsPayStrategy::doBeforePayHandler);
// 5. 发起支付
this.doHandler(payOrder, asyncStrategyList, AbsPayStrategy::doPayHandler, (strategyList, paymentObj) -> {
// 发起支付成功进行的执行方法
strategyList.forEach(AbsPayStrategy::doSuccessHandler);
payOrderService.updateById(paymentObj);
});
// 5.1发起支付
payStrategyList.forEach(AbsPayStrategy::doPayHandler);
// 5.2支付发起成功处理
payStrategyList.forEach(AbsPayStrategy::doSuccessHandler);
// 6. 更新支付订单扩展参数
// 6. 更新支付订单扩展参数
// payOrderService.updateById(payOrder);
payAssistService.updatePayOrderExtra(payParam,payOrder.getId());
// 7. 更新订单过期时间
// 8. 组装返回参数
return PaymentBuilder.buildPayResultByPayOrder(payOrder);
// 7. 组装返回参数
return PayBuilder.buildPayResultByPayOrder(payOrder);
}
/**

View File

@@ -1,17 +1,17 @@
package cn.bootx.platform.daxpay.service.core.payment.pay.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.service.common.exception.ExceptionInfo;
import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayCloseService;
import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayConfigService;
import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayOrderService;
import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayService;
import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
import cn.bootx.platform.daxpay.param.channel.AliPayParam;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
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.AliPayService;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService;
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONUtil;
@@ -32,14 +32,12 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@RequiredArgsConstructor
public class AliPayStrategy extends AbsPayStrategy {
private final AliPayOrderService aliPaymentService;
private final PayChannelOrderService channelOrderService;
private final AliPayService aliPayService;
private final AliPayConfigService alipayConfigService;
private final AliPayCloseService aliPayCancelService;
private AliPayConfig alipayConfig;
private AliPayParam aliPayParam;
@@ -82,7 +80,7 @@ public class AliPayStrategy extends AbsPayStrategy {
*/
@Override
public void doPayHandler() {
aliPayService.pay( this.getOrder(), this.getPayChannelParam(), this.aliPayParam, this.alipayConfig);
aliPayService.pay(this.getOrder(), this.getPayChannelParam(), this.aliPayParam, this.alipayConfig);
}
/**
@@ -90,25 +88,20 @@ public class AliPayStrategy extends AbsPayStrategy {
*/
@Override
public void doSuccessHandler() {
aliPaymentService.updatePaySuccess(this.getOrder(), this.getPayChannelParam());
channelOrderService.updateAsyncChannelOrder(this.getOrder(), this.getPayChannelParam());
}
/**
* 发起支付失败
* 生成通道支付单
*/
@Override
public void doErrorHandler(ExceptionInfo exceptionInfo) {
this.doCloseHandler();
}
/**
* 关闭支付记录
*/
@Override
public void doCloseHandler() {
// 关闭支付
aliPayCancelService.close(this.getOrder());
aliPaymentService.updateClose(this.getOrder().getId());
public PayChannelOrder generateChannelOrder() {
String gatewayOrderNo = PaymentContextLocal.get()
.getAsyncPayInfo()
.getGatewayOrderNo();
PayChannelOrder payChannelOrder = super.generateChannelOrder();
payChannelOrder.setGatewayOrderNo(gatewayOrderNo);
return payChannelOrder;
}

View File

@@ -1,11 +1,10 @@
package cn.bootx.platform.daxpay.service.core.payment.pay.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.service.core.channel.cash.service.CashService;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException;
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.service.core.channel.cash.service.CashService;
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
@@ -27,8 +26,6 @@ public class CashPayStrategy extends AbsPayStrategy {
private final CashService cashService;
private final PayOrderService payOrderService;
/**
* 现金支付
*/
@@ -57,12 +54,4 @@ public class CashPayStrategy extends AbsPayStrategy {
cashService.pay(this.getPayChannelParam(), this.getOrder(), this.getPayParam());
}
/**
* 关闭本地支付记录
*/
@Override
public void doCloseHandler() {
cashService.close(this.getOrder().getId());
}
}

View File

@@ -1,7 +1,6 @@
package cn.bootx.platform.daxpay.service.core.payment.pay.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.service.common.exception.ExceptionInfo;
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -32,11 +31,6 @@ public class UnionPayStrategy extends AbsPayStrategy {
}
@Override
public void doErrorHandler(ExceptionInfo exceptionInfo) {
}
@Override
public void doCloseHandler() {

View File

@@ -4,12 +4,12 @@ import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.service.common.exception.ExceptionInfo;
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig;
import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayCloseService;
import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayConfigService;
import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayOrderService;
import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayService;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayChannelOrderService;
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
import cn.bootx.platform.daxpay.service.param.channel.wechat.WeChatPayParam;
import cn.hutool.core.util.StrUtil;
@@ -32,14 +32,12 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@RequiredArgsConstructor
public class WeChatPayStrategy extends AbsPayStrategy {
private final PayChannelOrderService channelOrderService;
private final WeChatPayConfigService weChatPayConfigService;
private final WeChatPayService weChatPayService;
private final WeChatPayOrderService weChatPayOrderService;
private final WeChatPayCloseService weChatPayCloseService;
private WeChatPayConfig weChatPayConfig;
private WeChatPayParam weChatPayParam;
@@ -57,7 +55,6 @@ public class WeChatPayStrategy extends AbsPayStrategy {
*/
@Override
public void doBeforePayHandler() {
this.initWeChatPayConfig();
try {
// 微信参数验证
String extraParamsJson = this.getPayChannelParam().getChannelExtra();
@@ -96,24 +93,21 @@ public class WeChatPayStrategy extends AbsPayStrategy {
*/
@Override
public void doSuccessHandler() {
weChatPayOrderService.updatePaySuccess(this.getOrder(), this.getPayChannelParam());
channelOrderService.updateAsyncChannelOrder(this.getOrder(), this.getPayChannelParam());
}
/**
* 错误处理
* 生成通道支付单
*/
@Override
public void doErrorHandler(ExceptionInfo exceptionInfo) {
this.doCloseHandler();
}
/**
* 关闭本地支付记录
*/
@Override
public void doCloseHandler() {
weChatPayCloseService.close(this.getOrder(), weChatPayConfig);
weChatPayOrderService.updateClose(this.getOrder().getId());
public PayChannelOrder generateChannelOrder() {
String gatewayOrderNo = PaymentContextLocal.get()
.getAsyncPayInfo()
.getGatewayOrderNo();
PayChannelOrder payChannelOrder = super.generateChannelOrder();
payChannelOrder.setGatewayOrderNo(gatewayOrderNo);
return payChannelOrder;
}
/**

View File

@@ -118,54 +118,48 @@ public class PayRefundService {
* 分支付通道进行退款
*/
public RefundResult refundByChannel(RefundParam refundParam, PayOrder payOrder){
// 0.基础数据准备
List<RefundChannelParam> refundChannels = refundParam.getRefundChannels();
Map<String, PayChannelOrder> orderChannelMap = payChannelOrderManager.findAllByPaymentId(payOrder.getId())
.stream()
.collect(Collectors.toMap(PayChannelOrder::getChannel, Function.identity(), CollectorsFunction::retainLatest));
// 比对通道支付单是否与可退款记录数量一致
if (orderChannelMap.size() != refundChannels.size()){
throw new PayFailureException("通道支付单是否与可退款记录数量不一致");
}
// 1.获取退款参数方式,通过工厂生成对应的策略组
List<AbsPayRefundStrategy> payRefundStrategies = PayRefundStrategyFactory.createAsyncLast(refundChannels);
if (CollectionUtil.isEmpty(payRefundStrategies)) {
throw new PayUnsupportedMethodException();
}
// 2.初始化退款策略的参数
for (AbsPayRefundStrategy refundStrategy : payRefundStrategies) {
refundStrategy.initRefundParam(payOrder, refundParam, orderChannelMap.get(refundStrategy.getType().getCode()));
}
try {
// 0.基础数据准备
List<RefundChannelParam> refundChannels = refundParam.getRefundChannels();
Map<String, PayChannelOrder> orderChannelMap = payChannelOrderManager.findAllByPaymentId(payOrder.getId())
.stream()
.collect(Collectors.toMap(PayChannelOrder::getChannel, Function.identity(), CollectorsFunction::retainLatest));
// 比对通道支付单是否与可退款记录数量一致
if (orderChannelMap.size() != refundChannels.size()){
throw new PayFailureException("通道支付单是否与可退款记录数量不一致");
}
// 1.获取退款参数方式,通过工厂生成对应的策略组
List<AbsPayRefundStrategy> payRefundStrategies = PayRefundStrategyFactory.createAsyncLast(refundChannels);
if (CollectionUtil.isEmpty(payRefundStrategies)) {
throw new PayUnsupportedMethodException();
}
// 2.初始化退款策略的参数
for (AbsPayRefundStrategy refundStrategy : payRefundStrategies) {
refundStrategy.initRefundParam(payOrder, refundParam, orderChannelMap.get(refundStrategy.getType().getCode()));
}
// 3.退款前准备操作
payRefundStrategies.forEach(AbsPayRefundStrategy::doBeforeRefundHandler);
// 4.执行退款策略
payRefundStrategies.forEach(AbsPayRefundStrategy::doRefundHandler);
// 5 生成退款相关订单并保存
List<PayRefundChannelOrder> refundChannelOrders = payRefundStrategies.stream()
.map(AbsPayRefundStrategy::generateChannelOrder)
.collect(Collectors.toList());
PayRefundOrder refundOrder = payRefundAssistService.generateRefundOrder(refundParam, payOrder);
payRefundAssistService.saveOrderAndChannels(refundOrder,refundChannelOrders);
// 6.退款成功后支付单处理
this.successHandler(refundParam, payOrder);
// 7. 返回结果
return new RefundResult()
.setRefundId(refundOrder.getId())
.setRefundNo(refundParam.getRefundNo());
}
catch (Exception e) {
// 5失败处理
// 失败处理
this.errorHandler(refundParam, payOrder, e);
throw e;
}
// 5 生成退款相关订单并保存
List<PayRefundChannelOrder> refundChannelOrders = payRefundStrategies.stream()
.map(AbsPayRefundStrategy::generateChannelOrder)
.collect(Collectors.toList());
PayRefundOrder refundOrder = payRefundAssistService.generateRefundOrder(refundParam, payOrder);
payRefundAssistService.saveOrderAndChannels(refundOrder,refundChannelOrders);
// 6.退款成功后支付单处理
this.successHandler(refundParam, payOrder);
// 返回结果
return new RefundResult()
.setRefundId(refundOrder.getId())
.setRefundNo(refundParam.getRefundNo());
}
/**

View File

@@ -70,6 +70,6 @@ public class AliPayRefundStrategy extends AbsPayRefundStrategy {
String refundRequestNo = PaymentContextLocal.get()
.getRefundInfo()
.getGatewayRequestNo();
return payRefundChannelOrder.setGatewayRequestNo(refundRequestNo);
return payRefundChannelOrder.setGatewayOrderNo(refundRequestNo);
}
}

View File

@@ -71,7 +71,7 @@ public class WeChatPayRefundStrategy extends AbsPayRefundStrategy {
String refundRequestNo = PaymentContextLocal.get()
.getRefundInfo()
.getGatewayRequestNo();
return payRefundChannelOrder.setGatewayRequestNo(refundRequestNo);
return payRefundChannelOrder.setGatewayOrderNo(refundRequestNo);
}
}

View File

@@ -15,7 +15,7 @@ import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@Schema(title = "支付订单关联通道信息")
public class PayChanneOrderlDto extends BaseDto {
public class PayChannelOrderDto extends BaseDto {
@Schema(description = "支付id")
private Long paymentId;

View File

@@ -1,10 +1,11 @@
package cn.bootx.platform.daxpay.service.func;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.service.common.exception.ExceptionInfo;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.param.pay.PayParam;
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
import cn.bootx.platform.daxpay.param.pay.PayParam;
import cn.bootx.platform.daxpay.service.core.order.pay.builder.PayBuilder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
import lombok.Getter;
import lombok.Setter;
@@ -61,15 +62,14 @@ public abstract class AbsPayStrategy implements PayStrategy{
}
/**
* 支付失败的处理方式 TODO 后期考虑如何进行错误处理
* 生成通道支付单
*/
public void doErrorHandler(ExceptionInfo exceptionInfo) {
public PayChannelOrder generateChannelOrder() {
PayChannelOrder payChannelOrder = PayBuilder.buildPayChannelOrder(this.getPayChannelParam());
payChannelOrder.setId(this.getOrder().getId());
return payChannelOrder;
}
/**
* 关闭支付. 支付交易返回失败或支付系统超时调通该接口关闭支付
*/
public abstract void doCloseHandler();
}