ref 支付修复逻辑, 各通道相关策略完善

This commit is contained in:
nws
2024-01-01 00:39:47 +08:00
parent 3a942198c5
commit ec22293a1c
60 changed files with 426 additions and 528 deletions

View File

@@ -6,12 +6,12 @@
- 支付超时取消支付单
- 支付单回调处理实现
- 支付同步相关逻辑
- 新增支付订单修复逻辑, 用于回调和支付同步后不一致的情况处理
- 新增支付单预警功能, 处理支付单与网关状态不一致且无法自动修复的情况
- 记录支付修复单的情况, 主要分为自动修复, 人工介入
- 2023-12-31:
- 支付关闭相关逻辑
- 各支付通道补充相关未实现的逻辑
- 支付订单修复逻辑, 用于回调和支付同步后不一致的情况处理
1.0.1
- x 钱包支持多商户和多应用

View File

@@ -3,9 +3,9 @@ package cn.bootx.platform.daxpay.admin.controller.channel;
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.daxpay.core.channel.alipay.service.AlipayConfigService;
import cn.bootx.platform.daxpay.dto.channel.alipay.AlipayConfigDto;
import cn.bootx.platform.daxpay.param.channel.alipay.AlipayConfigParam;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayConfigService;
import cn.bootx.platform.daxpay.dto.channel.alipay.AliPayConfigDto;
import cn.bootx.platform.daxpay.param.channel.alipay.AliPayConfigParam;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
@@ -26,18 +26,18 @@ import java.util.List;
@AllArgsConstructor
public class AlipayConfigController {
private final AlipayConfigService alipayConfigService;
private final AliPayConfigService alipayConfigService;
@Operation(summary = "更新")
@PostMapping("/update")
public ResResult<Void> update(@RequestBody AlipayConfigParam param) {
public ResResult<Void> update(@RequestBody AliPayConfigParam param) {
alipayConfigService.update(param);
return Res.ok();
}
@Operation(summary = "获取配置")
@GetMapping("/getConfig")
public ResResult<AlipayConfigDto> getConfig() {
public ResResult<AliPayConfigDto> getConfig() {
return Res.ok(alipayConfigService.getConfig().toDto());
}

View File

@@ -1,13 +1,9 @@
package cn.bootx.platform.daxpay.admin.controller.channel;
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.dto.LabelValue;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayConfigService;
import cn.bootx.platform.daxpay.dto.channel.alipay.AlipayConfigDto;
import cn.bootx.platform.daxpay.dto.channel.wechat.WeChatPayConfigDto;
import cn.bootx.platform.daxpay.param.channel.wechat.WeChatPayConfigParam;
import cn.hutool.core.codec.Base64;

View File

@@ -6,6 +6,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.NOT_SYNC;
/**
* 支付单同步结果
* @author xxm
@@ -17,15 +19,15 @@ import lombok.experimental.Accessors;
@Schema(title = "支付单同步结果")
public class PaySyncResult extends PayCommonResult{
/**
* 支付网关同步状态
* @see PaySyncStatusEnum#NOT_SYNC
*/
private String syncStatus = NOT_SYNC.getCode();
@Schema(description = "是否同步成功")
private boolean success;
@Schema(description = "是否进行了修复")
private boolean repair;
/**
* @see PaySyncStatusEnum
*/
@Schema(description = "支付单的同步状态")
private String status;
}

View File

@@ -3,6 +3,9 @@ package cn.bootx.platform.daxpay.common.context;
import lombok.Getter;
import lombok.experimental.Accessors;
import java.util.HashMap;
import java.util.Map;
/**
* 支付上下文
* @author xxm
@@ -27,6 +30,9 @@ public class PaymentContext {
/** 消息通知相关信息 */
private final NoticeLocal noticeInfo = new NoticeLocal();
/** 回调参数内容 */
private final Map<String, String> callbackParam = new HashMap<>();
/** 支付请求相关信息 */
private final RequestLocal request = new RequestLocal();

View File

@@ -1,8 +1,8 @@
package cn.bootx.platform.daxpay.core.channel.alipay.convert;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.dto.channel.alipay.AlipayConfigDto;
import cn.bootx.platform.daxpay.param.channel.alipay.AlipayConfigParam;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.dto.channel.alipay.AliPayConfigDto;
import cn.bootx.platform.daxpay.param.channel.alipay.AliPayConfigParam;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@@ -17,10 +17,10 @@ public interface AlipayConvert {
AlipayConvert CONVERT = Mappers.getMapper(AlipayConvert.class);
AlipayConfig convert(AlipayConfigDto in);
AliPayConfig convert(AliPayConfigDto in);
AlipayConfig convert(AlipayConfigParam in);
AliPayConfig convert(AliPayConfigParam in);
AlipayConfigDto convert(AlipayConfig in);
AliPayConfigDto convert(AliPayConfig in);
}

View File

@@ -1,7 +1,7 @@
package cn.bootx.platform.daxpay.core.channel.alipay.dao;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@@ -13,6 +13,6 @@ import org.springframework.stereotype.Repository;
*/
@Repository
@RequiredArgsConstructor
public class AlipayConfigManager extends BaseManager<AlipayConfigMapper, AlipayConfig> {
public class AliPayConfigManager extends BaseManager<AliPayConfigMapper, AliPayConfig> {
}

View File

@@ -1,6 +1,6 @@
package cn.bootx.platform.daxpay.core.channel.alipay.dao;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@@ -10,6 +10,6 @@ import org.apache.ibatis.annotations.Mapper;
* @since 2023/12/18
*/
@Mapper
public interface AlipayConfigMapper extends BaseMapper<AlipayConfig> {
public interface AliPayConfigMapper extends BaseMapper<AliPayConfig> {
}

View File

@@ -7,8 +7,8 @@ import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
import cn.bootx.platform.common.mybatisplus.handler.StringListTypeHandler;
import cn.bootx.platform.daxpay.code.AliPayCode;
import cn.bootx.platform.daxpay.core.channel.alipay.convert.AlipayConvert;
import cn.bootx.platform.daxpay.dto.channel.alipay.AlipayConfigDto;
import cn.bootx.platform.daxpay.param.channel.alipay.AlipayConfigParam;
import cn.bootx.platform.daxpay.dto.channel.alipay.AliPayConfigDto;
import cn.bootx.platform.daxpay.param.channel.alipay.AliPayConfigParam;
import cn.bootx.table.modify.annotation.DbColumn;
import cn.bootx.table.modify.annotation.DbTable;
import cn.bootx.table.modify.mysql.annotation.DbMySqlFieldType;
@@ -32,7 +32,7 @@ import java.util.List;
@Accessors(chain = true)
@DbTable(comment = "支付宝支付配置")
@TableName("pay_alipay_config")
public class AlipayConfig extends MpBaseEntity implements EntityBaseFunction<AlipayConfigDto> {
public class AliPayConfig extends MpBaseEntity implements EntityBaseFunction<AliPayConfigDto> {
/** 支付宝商户appId */
@DbColumn(comment = "支付宝商户appId")
@@ -109,11 +109,11 @@ public class AlipayConfig extends MpBaseEntity implements EntityBaseFunction<Ali
private String remark;
@Override
public AlipayConfigDto toDto() {
public AliPayConfigDto toDto() {
return AlipayConvert.CONVERT.convert(this);
}
public static AlipayConfig init(AlipayConfigParam in) {
public static AliPayConfig init(AliPayConfigParam in) {
return AlipayConvert.CONVERT.convert(in);
}

View File

@@ -5,8 +5,9 @@ import cn.bootx.platform.common.redis.RedisClient;
import cn.bootx.platform.daxpay.code.AliPayCode;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.callback.dao.CallbackNotifyManager;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.core.payment.callback.service.PayCallbackService;
import cn.bootx.platform.daxpay.func.AbsPayCallbackStrategy;
import cn.hutool.core.util.CharsetUtil;
@@ -32,10 +33,10 @@ import java.util.Objects;
@Service
public class AliPayCallbackService extends AbsPayCallbackStrategy {
private final AlipayConfigService aliasConfigService;
private final AliPayConfigService aliasConfigService;
public AliPayCallbackService(RedisClient redisClient, CallbackNotifyManager callbackNotifyManager,
PayCallbackService payCallbackService, AlipayConfigService aliasConfigService) {
PayCallbackService payCallbackService, AliPayConfigService aliasConfigService) {
super(redisClient, callbackNotifyManager, payCallbackService);
this.aliasConfigService = aliasConfigService;
}
@@ -47,7 +48,7 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
@Override
public String getTradeStatus() {
Map<String, String> params = PARAMS.get();
Map<String, String> params = PaymentContextLocal.get().getCallbackParam();
String tradeStatus = params.get(AliPayCode.TRADE_STATUS);
if (Objects.equals(tradeStatus, AliPayCode.NOTIFY_TRADE_SUCCESS)) {
return PayStatusEnum.SUCCESS.getCode();
@@ -61,14 +62,14 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
@SneakyThrows
@Override
public boolean verifyNotify() {
Map<String, String> params = PARAMS.get();
Map<String, String> params =PaymentContextLocal.get().getCallbackParam();
String callReq = JSONUtil.toJsonStr(params);
String appId = params.get(AliPayCode.APP_ID);
if (StrUtil.isBlank(appId)) {
log.error("支付宝回调报文 appId 为空 {}", callReq);
return false;
}
AlipayConfig alipayConfig = aliasConfigService.getConfig();
AliPayConfig alipayConfig = aliasConfigService.getConfig();
if (Objects.isNull(alipayConfig)) {
log.error("支付宝支付配置不存在: {}", callReq);
return false;
@@ -92,7 +93,7 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
@Override
public Long getPaymentId() {
Map<String, String> params = PARAMS.get();
Map<String, String> params = PaymentContextLocal.get().getCallbackParam();
return Long.valueOf(params.get(AliPayCode.OUT_TRADE_NO));
}

View File

@@ -27,23 +27,21 @@ import java.util.Objects;
public class AliPayCloseService {
/**
* 关闭支付 此处使用交易关闭接口
* 支付宝支持 交易关闭 和 交易撤销 两种关闭订单的方式,
* 关闭支付 此处使用交易关闭接口, 支付宝支持 交易关闭 和 交易撤销 两种关闭订单的方式, 区别如下
* 交易关闭: 只有订单在未支付的状态下才可以进行关闭, 商户不需要额外申请就有此接口的权限
* 交易撤销: 如果用户支付成功,会将此订单资金退还给用户. 限制时间为1天过了24小时该接口无法再使用。可以视为一个特殊的接口, 需要专门签约这个接口的权限
*
* 交易撤销: 交易撤销接口会将此订单关闭。如果用户支付成功,会将此订单资金退还给用户. 限制时间为1天过了24小时该接口无法再使用。可以视为一个特殊的接口
* 需要专门签约这个接口的权限
* TODO 如果返回已经关闭, 也视为关闭成功
*/
@Retryable(value = RetryableException.class)
public void close(PayOrder payOrder) {
// 只有部分需要调用支付宝网关进行关闭
AlipayTradeCloseModel model = new AlipayTradeCloseModel();
model.setOutTradeNo(String.valueOf(payOrder.getId()));
try {
AlipayTradeCloseResponse response = AliPayApi.tradeCloseToResponse(model);
if (!Objects.equals(AliPayCode.SUCCESS, response.getCode())) {
log.error("网关返回撤销失败: {}", response.getSubMsg());
log.error("网关返回关闭失败: {}", response.getSubMsg());
throw new PayFailureException(response.getSubMsg());
}
} catch (AlipayApiException e) {

View File

@@ -5,9 +5,9 @@ import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.rest.dto.LabelValue;
import cn.bootx.platform.daxpay.code.AliPayCode;
import cn.bootx.platform.daxpay.code.AliPayWay;
import cn.bootx.platform.daxpay.core.channel.alipay.dao.AlipayConfigManager;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.param.channel.alipay.AlipayConfigParam;
import cn.bootx.platform.daxpay.core.channel.alipay.dao.AliPayConfigManager;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.param.channel.alipay.AliPayConfigParam;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.CharsetUtil;
@@ -32,17 +32,17 @@ import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class AlipayConfigService {
public class AliPayConfigService {
/** 默认支付宝配置的主键ID */
private final static Long ID = 0L;
private final AlipayConfigManager alipayConfigManager;
private final AliPayConfigManager alipayConfigManager;
/**
* 修改
*/
@Transactional(rollbackFor = Exception.class)
public void update(AlipayConfigParam param) {
AlipayConfig alipayConfig = alipayConfigManager.findById(ID).orElseThrow(() -> new DataNotExistException("支付宝配置不存在"));
public void update(AliPayConfigParam param) {
AliPayConfig alipayConfig = alipayConfigManager.findById(ID).orElseThrow(() -> new DataNotExistException("支付宝配置不存在"));
BeanUtil.copyProperties(param, alipayConfig, CopyOptions.create().ignoreNullValue());
alipayConfigManager.updateById(alipayConfig);
}
@@ -60,7 +60,7 @@ public class AlipayConfigService {
/**
* 获取支付配置
*/
public AlipayConfig getConfig(){
public AliPayConfig getConfig(){
return alipayConfigManager.findById(ID).orElseThrow(() -> new DataNotExistException("支付宝配置不存在"));
}
@@ -69,7 +69,7 @@ public class AlipayConfigService {
* 初始化IJPay服务
*/
@SneakyThrows
public void initConfig(AlipayConfig alipayConfig) {
public void initConfig(AliPayConfig alipayConfig) {
AliPayApiConfig aliPayApiConfig;
// 公钥

View File

@@ -6,10 +6,9 @@ import cn.bootx.platform.daxpay.common.entity.OrderRefundableInfo;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.channel.alipay.dao.AliPayOrderManager;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayOrder;
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderChannelManager;
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderManager;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrderChannel;
import cn.bootx.platform.daxpay.core.order.pay.service.PayOrderChannelService;
import cn.bootx.platform.daxpay.param.pay.PayWayParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -38,34 +37,15 @@ public class AliPayOrderService {
private final PayOrderManager payOrderManager;
private final PayOrderChannelManager payOrderChannelManager;
private final PayOrderChannelService payOrderChannelService;
/**
* 支付调起成功 更新payment中异步支付类型信息, 如果支付完成, 创建支付宝支付单
*/
public void updatePaySuccess(PayOrder payOrder, PayWayParam payWayParam) {
payOrder.setAsyncPay(true)
.setAsyncPayChannel(PayChannelEnum.ALI.getCode());
// 更新支付宝异步支付类型信息
Optional<PayOrderChannel> payOrderChannelOpt = payOrderChannelManager.findByPaymentIdAndChannel(payOrder.getId(), PayChannelEnum.ALI.getCode());
if (!payOrderChannelOpt.isPresent()){
payOrderChannelManager.deleteByPaymentIdAndAsync(payOrder.getId());
payOrderChannelManager.save(new PayOrderChannel()
.setPaymentId(payOrder.getId())
.setChannel(PayChannelEnum.ALI.getCode())
.setAmount(payWayParam.getAmount())
.setPayWay(payWayParam.getWay())
.setChannelExtra(payWayParam.getChannelExtra())
.setAsync(true)
);
} else {
payOrderChannelOpt.get()
.setChannelExtra(payWayParam.getChannelExtra())
.setPayWay(payWayParam.getWay());
payOrderChannelManager.updateById(payOrderChannelOpt.get());
}
payOrder.setAsyncPay(true).setAsyncPayChannel(PayChannelEnum.ALI.getCode());
payOrderChannelService.updateChannel(payWayParam,payOrder);
// 更新支付宝可退款类型信息
List<OrderRefundableInfo> refundableInfos = payOrder.getRefundableInfos();
@@ -109,7 +89,7 @@ public class AliPayOrderService {
}
/**
* 取消状态
* 取消状态, 按正常来说不会出现支付宝订单需要取消的情况
*/
public void updateClose(Long paymentId) {
Optional<AliPayOrder> aliPaymentOptional = aliPayOrderManager.findByPaymentId(paymentId);
@@ -120,9 +100,9 @@ public class AliPayOrderService {
}
/**
* 更新退款
* 更新退款. 分为部分退款和全部退款
*/
public void updatePayRefund(Long paymentId, int amount) {
public void updateRefund(Long paymentId, int amount) {
Optional<AliPayOrder> aliPaymentOptional = aliPayOrderManager.findByPaymentId(paymentId);
aliPaymentOptional.ifPresent(payment -> {
int refundableBalance = payment.getRefundableBalance() - amount;

View File

@@ -27,7 +27,7 @@ import java.util.Objects;
public class AliPayRefundService {
/**
* 退款
* 退款, 调用支付宝退款
*/
public void refund(PayOrder payOrder, int amount) {
AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel();

View File

@@ -7,7 +7,7 @@ import cn.bootx.platform.daxpay.code.PayWayEnum;
import cn.bootx.platform.daxpay.common.context.AsyncPayLocal;
import cn.bootx.platform.daxpay.common.context.NoticeLocal;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.channel.AliPayParam;
@@ -48,7 +48,7 @@ public class AliPayService {
/**
* 支付前检查支付方式是否可用
*/
public void validation(PayWayParam payWayParam, AlipayConfig alipayConfig) {
public void validation(PayWayParam payWayParam, AliPayConfig alipayConfig) {
if (CollUtil.isNotEmpty(alipayConfig.getPayWays())){
throw new PayFailureException("支付宝未配置可用的支付方式");
@@ -64,7 +64,7 @@ public class AliPayService {
/**
* 调起支付
*/
public void pay(PayOrder payOrder, PayWayParam payWayParam, AliPayParam aliPayParam, AlipayConfig alipayConfig) {
public void pay(PayOrder payOrder, PayWayParam payWayParam, AliPayParam aliPayParam, AliPayConfig alipayConfig) {
Integer amount = payWayParam.getAmount();
String payBody = null;
// 异步线程存储
@@ -97,7 +97,7 @@ public class AliPayService {
/**
* wap支付
*/
public String wapPay(int amount, PayOrder payment, AlipayConfig alipayConfig) {
public String wapPay(int amount, PayOrder payment, AliPayConfig alipayConfig) {
NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo();
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
@@ -131,7 +131,7 @@ public class AliPayService {
/**
* app支付
*/
public String appPay(int amount, PayOrder payment, AlipayConfig alipayConfig) {
public String appPay(int amount, PayOrder payment, AliPayConfig alipayConfig) {
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
@@ -156,7 +156,7 @@ public class AliPayService {
/**
* PC支付
*/
public String webPay(int amount, PayOrder payment, AlipayConfig alipayConfig) {
public String webPay(int amount, PayOrder payment, AliPayConfig alipayConfig) {
NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo();
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
@@ -189,7 +189,7 @@ public class AliPayService {
/**
* 二维码支付(扫码支付)
*/
public String qrCodePay(int amount, PayOrder payment, AlipayConfig alipayConfig) {
public String qrCodePay(int amount, PayOrder payment, AliPayConfig alipayConfig) {
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setSubject(payment.getTitle());
@@ -213,7 +213,7 @@ public class AliPayService {
/**
* 付款码支付
*/
public String barCode(int amount, PayOrder payment, AliPayParam aliPayParam, AlipayConfig alipayConfig) {
public String barCode(int amount, PayOrder payment, AliPayParam aliPayParam, AliPayConfig alipayConfig) {
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
AlipayTradePayModel model = new AlipayTradePayModel();

View File

@@ -3,6 +3,8 @@ package cn.bootx.platform.daxpay.core.channel.alipay.service;
import cn.bootx.platform.daxpay.code.AliPayCode;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.channel.alipay.dao.AliPayOrderManager;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.core.payment.sync.result.GatewaySyncResult;
import cn.hutool.json.JSONUtil;
@@ -14,7 +16,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Objects;
/**
@@ -26,44 +27,49 @@ import java.util.Objects;
@Slf4j
@Service
@RequiredArgsConstructor
public class AlipaySyncService {
public class AliPaySyncService {
private final AliPayOrderManager payOrderManager;
/**
* 与支付宝网关同步状态 1 远程支付成功 2 交易创建等待买家付款 3 超时关闭 4 查询不到 5 查询失败
* 与支付宝网关同步状态, 退款状态会参加
* 1 远程支付成功
* 2 交易创建等待买家付款
* 3 超时关闭
* 4 查询不到
* 5 查询失败
*/
public GatewaySyncResult syncPayStatus(Long paymentId) {
public GatewaySyncResult syncPayStatus(PayOrder payOrder) {
GatewaySyncResult syncResult = new GatewaySyncResult().setSyncStatus(PaySyncStatusEnum.FAIL.getCode());
// 查询
try {
AlipayTradeQueryModel queryModel = new AlipayTradeQueryModel();
queryModel.setOutTradeNo(String.valueOf(paymentId));
queryModel.setOutTradeNo(String.valueOf(payOrder.getId()));
// 查询退款参数
AlipayTradeQueryResponse response = AliPayApi.tradeQueryToResponse(queryModel);
String tradeStatus = response.getTradeStatus();
syncResult.setJson(JSONUtil.toJsonStr(response));
// 支付完成
if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_SUCCESS) || Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_FINISHED)) {
HashMap<String, String> map = new HashMap<>(1);
// TODO 写入到
map.put(AliPayCode.TRADE_NO, response.getTradeNo());
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS.getCode()).setMap(map);
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(response.getTradeNo());
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS.getCode());
}
// 待支付
if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_WAIT_BUYER_PAY)) {
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_WAIT.getCode());
}
// 已关闭
// 已关闭或支付完成后全额退款
if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_CLOSED)) {
return syncResult.setSyncStatus(PaySyncStatusEnum.CLOSED.getCode());
// 根据支付订单区分退款的情况, TODO 后期添加查询退款信息的逻辑
if (Objects.equals(payOrder.getStatus(), PayStatusEnum.REFUNDED.getCode())){
return syncResult.setSyncStatus(PaySyncStatusEnum.REFUND.getCode());
} else {
return syncResult.setSyncStatus(PaySyncStatusEnum.CLOSED.getCode());
}
}
// 未找到
if (Objects.equals(response.getSubCode(), AliPayCode.ACQ_TRADE_NOT_EXIST)) {
return syncResult.setSyncStatus(PaySyncStatusEnum.NOT_FOUND.getCode());
}
// 退款 支付宝查不到这个状态
}
catch (AlipayApiException e) {
log.error("查询订单失败:", e);
@@ -71,26 +77,4 @@ public class AlipaySyncService {
}
return syncResult;
}
/**
* 比对网关状态和支付单状态
*/
public boolean isStatusSync(GatewaySyncResult syncResult, PayOrder payOrder) {
String syncStatus = syncResult.getSyncStatus();
String orderStatus = payOrder.getStatus();
// 支付成功比对
if (orderStatus.equals(PayStatusEnum.SUCCESS.getCode()) && syncStatus.equals(PaySyncStatusEnum.PAY_SUCCESS.getCode())){
return true;
}
// 待支付比对
if (orderStatus.equals(PayStatusEnum.PROGRESS.getCode()) && syncStatus.equals(PaySyncStatusEnum.PAY_WAIT.getCode())){
return true;
}
// 支付关闭比对
if (orderStatus.equals(PayStatusEnum.CLOSE.getCode()) && syncStatus.equals(PaySyncStatusEnum.CLOSED.getCode())){
return true;
}
return false;
}
}

View File

@@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.core.channel.voucher.convert;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherLog;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayment;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayOrder;
import cn.bootx.platform.daxpay.dto.channel.voucher.VoucherDto;
import cn.bootx.platform.daxpay.dto.channel.voucher.VoucherLogDto;
import cn.bootx.platform.daxpay.dto.channel.voucher.VoucherPayOrderDto;
@@ -22,6 +22,6 @@ public interface VoucherConvert {
VoucherLogDto convert(VoucherLog in);
VoucherPayOrderDto convert(VoucherPayment in);
VoucherPayOrderDto convert(VoucherPayOrder in);
}

View File

@@ -1,6 +1,6 @@
package cn.bootx.platform.daxpay.core.channel.voucher.dao;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayment;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayOrder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@@ -9,6 +9,6 @@ import org.apache.ibatis.annotations.Mapper;
* @since 2022/3/14
*/
@Mapper
public interface VoucherPaymentMapper extends BaseMapper<VoucherPayment> {
public interface VoucherPayOrderMapper extends BaseMapper<VoucherPayOrder> {
}

View File

@@ -1,7 +1,7 @@
package cn.bootx.platform.daxpay.core.channel.voucher.dao;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayment;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayOrder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
@@ -15,13 +15,13 @@ import java.util.Optional;
@Slf4j
@Repository
@RequiredArgsConstructor
public class VoucherPaymentManager extends BaseManager<VoucherPaymentMapper, VoucherPayment> {
public class VoucherPaymentManager extends BaseManager<VoucherPayOrderMapper, VoucherPayOrder> {
/**
* 根据支付id
* 根据支付id查询
*/
public Optional<VoucherPayment> findByPaymentId(Long paymentId) {
return this.findByField(VoucherPayment::getPaymentId, paymentId);
public Optional<VoucherPayOrder> findByPaymentId(Long paymentId) {
return this.findByField(VoucherPayOrder::getPaymentId, paymentId);
}
}

View File

@@ -24,7 +24,7 @@ import lombok.experimental.Accessors;
@DbTable(comment = "储值卡支付记录")
@Accessors(chain = true)
@TableName(value = "pay_voucher_payment",autoResultMap = true)
public class VoucherPayment extends BasePayOrder implements EntityBaseFunction<VoucherPayOrderDto> {
public class VoucherPayOrder extends BasePayOrder implements EntityBaseFunction<VoucherPayOrderDto> {
/** 扣款储值卡 */
@DbColumn(comment = "扣款储值卡")

View File

@@ -3,7 +3,7 @@ package cn.bootx.platform.daxpay.core.channel.voucher.service;
import cn.bootx.platform.common.core.exception.BizException;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.core.channel.voucher.dao.VoucherPaymentManager;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayment;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayOrder;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherRecord;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.param.pay.PayParam;
@@ -24,7 +24,7 @@ import java.util.Optional;
@Slf4j
@Service
@RequiredArgsConstructor
public class VoucherPaymentService {
public class VoucherPayOrderService {
private final VoucherPaymentManager voucherPaymentManager;
@@ -32,25 +32,25 @@ public class VoucherPaymentService {
* 添加支付记录
*/
public void savePayment(PayOrder payOrder, PayParam payParam, PayWayParam payMode, VoucherRecord voucherRecord) {
VoucherPayment voucherPayment = new VoucherPayment().setVoucherRecord(voucherRecord);
voucherPayment.setPaymentId(payOrder.getId())
VoucherPayOrder voucherPayOrder = new VoucherPayOrder().setVoucherRecord(voucherRecord);
voucherPayOrder.setPaymentId(payOrder.getId())
.setBusinessNo(payParam.getBusinessNo())
.setAmount(payMode.getAmount())
.setRefundableBalance(payMode.getAmount())
.setStatus(payOrder.getStatus());
voucherPaymentManager.save(voucherPayment);
voucherPaymentManager.save(voucherPayOrder);
}
/**
* 更新成功状态
*/
public void updateSuccess(Long paymentId) {
Optional<VoucherPayment> payment = voucherPaymentManager.findByPaymentId(paymentId);
Optional<VoucherPayOrder> payment = voucherPaymentManager.findByPaymentId(paymentId);
if (payment.isPresent()) {
VoucherPayment voucherPayment = payment.get();
voucherPayment.setStatus(PayStatusEnum.SUCCESS.getCode())
VoucherPayOrder voucherPayOrder = payment.get();
voucherPayOrder.setStatus(PayStatusEnum.SUCCESS.getCode())
.setPayTime(LocalDateTime.now());
voucherPaymentManager.updateById(voucherPayment);
voucherPaymentManager.updateById(voucherPayOrder);
}
}
@@ -58,7 +58,7 @@ public class VoucherPaymentService {
* 关闭操作
*/
public void updateClose(Long paymentId) {
VoucherPayment payment = voucherPaymentManager.findByPaymentId(paymentId)
VoucherPayOrder payment = voucherPaymentManager.findByPaymentId(paymentId)
.orElseThrow(() -> new BizException("未查询到查询交易记录"));
payment.setStatus(PayStatusEnum.CLOSE.getCode());
voucherPaymentManager.updateById(payment);
@@ -68,7 +68,7 @@ public class VoucherPaymentService {
* 更新退款
*/
public void updateRefund(Long paymentId, int amount) {
Optional<VoucherPayment> voucherPayment = voucherPaymentManager.findByPaymentId(paymentId);
Optional<VoucherPayOrder> voucherPayment = voucherPaymentManager.findByPaymentId(paymentId);
voucherPayment.ifPresent(payOrder -> {
int refundableBalance = payOrder.getRefundableBalance() - amount;
payOrder.setRefundableBalance(refundableBalance);

View File

@@ -6,7 +6,7 @@ import cn.bootx.platform.daxpay.core.channel.voucher.dao.VoucherManager;
import cn.bootx.platform.daxpay.core.channel.voucher.dao.VoucherPaymentManager;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherLog;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayment;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherPayOrder;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherRecord;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
@@ -20,9 +20,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;
/**
* 储值卡支付
*
@@ -63,8 +60,6 @@ public class VoucherPayService {
String cardNo = voucherPayParam.getCardNo();
Voucher voucher = voucherManager.findByCardNo(cardNo).orElseThrow(()->new PayFailureException("储值卡不存在"));
// 判断是否有重复or无效的储值卡
// 卡信息校验
String timeCheck = voucherQueryService.check(voucher);
if (StrUtil.isNotBlank(timeCheck)) {
@@ -187,94 +182,39 @@ public class VoucherPayService {
/**
* 退款
* 全额退款支持分别退回到原有卡和统一退回到某张卡中, 默认退回到原有卡中
* 部分退款, 会退到指定的一张卡上, 如果不指定, 则自动退到有效期最久的卡上
*/
@Transactional(rollbackFor = Exception.class)
public void refund(Long paymentId, Integer amount) {
VoucherPayment voucherPayment = voucherPaymentManager.findByPaymentId(paymentId)
VoucherPayOrder voucherPayOrder = voucherPaymentManager.findByPaymentId(paymentId)
.orElseThrow(() -> new PayFailureException("储值卡支付记录不存在"));
// 全部退款还是部分退款
// if (BigDecimalUtil.compareTo(amount,voucherPayment.getAmount())==0){
// // 是否全部退到一张卡中
// if (voucherRefundParam.isRefundToOne()){
// this.refundToOne(voucherPayment, voucherPayment.getRefundVoucherNo());
// } else {
// // 退回到原有卡中
// this.refundToRaw(voucherPayment);
// }
// } else {
// this.refundToOne(voucherPayment, voucherRefundParam.getRefundVoucherNo());
// }
// 退回到原有卡中
this.refundToRaw(voucherPayOrder);
}
/**
* 退款到原有的卡中
*/
private void refundToRaw(VoucherPayment voucherPayment){
int voucherAmount = voucherPayment.getAmount();
private void refundToRaw(VoucherPayOrder voucherPayOrder){
int voucherAmount = voucherPayOrder.getAmount();
// 获取储值卡扣款信息
VoucherRecord voucherRecord = voucherPayment.getVoucherRecord();
VoucherRecord voucherRecord = voucherPayOrder.getVoucherRecord();
Voucher voucher = voucherManager.findByCardNo(voucherRecord.getCardNo())
.orElseThrow(() -> new PayFailureException("储值卡不存在"));
// 退款 和 记录日志
voucher.setBalance(voucherAmount + voucher.getBalance());
voucher.setBalance(voucherAmount + voucher.getBalance());
VoucherLog voucherLog = new VoucherLog()
.setType(VoucherCode.LOG_REFUND_SELF)
.setVoucherId(voucher.getId())
.setVoucherNo(voucher.getCardNo())
.setAmount(voucherAmount)
.setPaymentId(voucherPayment.getPaymentId())
.setBusinessId(voucherPayment.getStatus())
.setPaymentId(voucherPayOrder.getPaymentId())
.setBusinessId(voucherPayOrder.getStatus())
.setRemark(String.format("退款金额 %d ", voucherAmount));
voucherManager.updateById(voucher);
voucherLogManager.save(voucherLog);
}
/**
* 对储值卡进行排序
* 有期限的在前面, 同样有期限到期时间短的在前面, 同样到期日余额小的在前面, 金额一样id小的前面
*/
private List<Voucher> sort(List<Voucher> vouchers){
vouchers.sort(this::compareTime);
return vouchers;
}
/**
* 比较储值卡的期限
*/
private int compareTime(Voucher v1,Voucher v2){
// 期限对比, 都为长期
if (v1.isEnduring()&&v2.isEnduring()){
// 比较余额
return compareBalance(v1,v2);
}
// 都不为长期, 且金额一致
if (Objects.equals(v1.getEndTime(),v2.getEndTime())){
// 比较余额
return compareBalance(v1,v2);
}
// 期限对比 其中一个为长期
if (v1.isEnduring()^v2.isEnduring()){
return v1.isEnduring()?1:-1;
}
// 比较期限
return v1.getEndTime().compareTo(v2.getEndTime());
}
/**
* 比较储值卡的余额, 余额一致比较主键
*/
private int compareBalance(Voucher v1,Voucher v2) {
// int i = BigDecimalUtil.compareTo(v1.getBalance(), v2.getBalance());
// if (i==0){
// return Long.compare(v1.getId(),v2.getId());
// }
// return i;
return 1;
}
}

View File

@@ -1,7 +1,7 @@
package cn.bootx.platform.daxpay.core.channel.wechat.convert;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayment;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayOrder;
import cn.bootx.platform.daxpay.dto.channel.wechat.WeChatPayConfigDto;
import cn.bootx.platform.daxpay.dto.channel.wechat.WeChatPayOrderDto;
import cn.bootx.platform.daxpay.param.channel.wechat.WeChatPayConfigParam;
@@ -23,8 +23,8 @@ public interface WeChatConvert {
WeChatPayConfigDto convert(WeChatPayConfig in);
WeChatPayOrderDto convert(WeChatPayment in);
WeChatPayOrderDto convert(WeChatPayOrder in);
WeChatPayment convert(WeChatPayOrderDto in);
WeChatPayOrder convert(WeChatPayOrderDto in);
}

View File

@@ -1,7 +1,7 @@
package cn.bootx.platform.daxpay.core.channel.wechat.dao;
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayment;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayOrder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
@@ -17,10 +17,10 @@ import java.util.Optional;
@Slf4j
@Repository
@RequiredArgsConstructor
public class WeChatPaymentManager extends BaseManager<WeChatPaymentMapper, WeChatPayment> {
public class WeChatPayOrderManager extends BaseManager<WeChatPayOrderMapper, WeChatPayOrder> {
public Optional<WeChatPayment> findByPaymentId(Long paymentId) {
return findByField(WeChatPayment::getPaymentId, paymentId);
public Optional<WeChatPayOrder> findByPaymentId(Long paymentId) {
return findByField(WeChatPayOrder::getPaymentId, paymentId);
}
}

View File

@@ -1,10 +1,10 @@
package cn.bootx.platform.daxpay.core.channel.wechat.dao;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayment;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayOrder;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface WeChatPaymentMapper extends BaseMapper<WeChatPayment> {
public interface WeChatPayOrderMapper extends BaseMapper<WeChatPayOrder> {
}

View File

@@ -17,7 +17,7 @@ import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@TableName("pay_wechat_payment")
public class WeChatPayment extends BasePayOrder implements EntityBaseFunction<WeChatPayOrderDto> {
public class WeChatPayOrder extends BasePayOrder implements EntityBaseFunction<WeChatPayOrderDto> {
/**
* 微信交易号

View File

@@ -4,6 +4,7 @@ import cn.bootx.platform.common.redis.RedisClient;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.WeChatPayCode;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.callback.dao.CallbackNotifyManager;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
import cn.bootx.platform.daxpay.core.payment.callback.service.PayCallbackService;
@@ -49,7 +50,7 @@ public class WeChatPayCallbackService extends AbsPayCallbackStrategy {
*/
@Override
public Long getPaymentId() {
Map<String, String> params = PARAMS.get();
Map<String, String> params = PaymentContextLocal.get().getCallbackParam();
String paymentId = params.get(WeChatPayCode.OUT_TRADE_NO);
return Long.valueOf(paymentId);
}
@@ -59,7 +60,7 @@ public class WeChatPayCallbackService extends AbsPayCallbackStrategy {
*/
@Override
public String getTradeStatus() {
Map<String, String> params = PARAMS.get();
Map<String, String> params = PaymentContextLocal.get().getCallbackParam();
if (WxPayKit.codeIsOk(params.get(WeChatPayCode.RESULT_CODE))) {
return PayStatusEnum.SUCCESS.getCode();
}
@@ -73,7 +74,7 @@ public class WeChatPayCallbackService extends AbsPayCallbackStrategy {
*/
@Override
public boolean verifyNotify() {
Map<String, String> params = PARAMS.get();
Map<String, String> params = PaymentContextLocal.get().getCallbackParam();
String callReq = JSONUtil.toJsonStr(params);
log.info("微信发起回调 报文: {}", callReq);
String appId = params.get(APPID);

View File

@@ -4,20 +4,19 @@ import cn.bootx.platform.common.core.exception.BizException;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.common.context.AsyncPayLocal;
import cn.bootx.platform.daxpay.common.entity.OrderRefundableInfo;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.channel.wechat.dao.WeChatPaymentManager;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayment;
import cn.bootx.platform.daxpay.core.channel.wechat.dao.WeChatPayOrderManager;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayOrder;
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderManager;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrderChannel;
import cn.bootx.platform.daxpay.common.entity.OrderRefundableInfo;
import cn.bootx.platform.daxpay.core.order.pay.service.PayOrderChannelService;
import cn.bootx.platform.daxpay.param.pay.PayWayParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -35,7 +34,9 @@ public class WeChatPayOrderService {
private final PayOrderManager paymentService;
private final WeChatPaymentManager weChatPaymentManager;
private final PayOrderChannelService payOrderChannelService;
private final WeChatPayOrderManager weChatPayOrderManager;
/**
* 支付调起成功 更新payment中异步支付类型信息, 如果支付完成, 创建微信支付单
@@ -44,68 +45,65 @@ public class WeChatPayOrderService {
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();;
payOrder.setAsyncPay(true).setAsyncPayChannel(PayChannelEnum.WECHAT.getCode());
List<PayOrderChannel> payTypeInfos = new ArrayList<>();
List<OrderRefundableInfo> refundableInfos = new ArrayList<>();
// 清除已有的异步支付类型信息
payTypeInfos.removeIf(payTypeInfo -> PayChannelEnum.ASYNC_TYPE_CODE.contains(payTypeInfo.getChannel()));
refundableInfos.removeIf(payTypeInfo -> PayChannelEnum.ASYNC_TYPE_CODE.contains(payTypeInfo.getChannel()));
// 添加微信支付类型信息
payTypeInfos.add(new PayOrderChannel().setChannel(PayChannelEnum.WECHAT.getCode())
.setPayWay(payWayParam.getWay())
.setAmount(payWayParam.getAmount())
.setChannelExtra(payWayParam.getChannelExtra()));
// TODO 更新支付方式列表
payOrderChannelService.updateChannel(payWayParam,payOrder);
// 更新微信可退款类型信息
refundableInfos.add(
new OrderRefundableInfo().setChannel(PayChannelEnum.WECHAT.getCode())
.setAmount(payWayParam.getAmount()));
List<OrderRefundableInfo> refundableInfos = payOrder.getRefundableInfos();
refundableInfos.removeIf(payTypeInfo -> PayChannelEnum.ASYNC_TYPE_CODE.contains(payTypeInfo.getChannel()));
refundableInfos.add(new OrderRefundableInfo()
.setChannel(PayChannelEnum.WECHAT.getCode())
.setAmount(payWayParam.getAmount())
);
payOrder.setRefundableInfos(refundableInfos);
// 如果支付完成(付款码情况) 调用 updateSyncSuccess 创建微信支付记录
if (Objects.equals(payOrder.getStatus(), PayStatusEnum.SUCCESS.getCode())) {
this.createWeChatPayment(payOrder, payWayParam, asyncPayInfo.getTradeNo());
this.createWeChatOrder(payOrder, payWayParam.getAmount());
}
}
/**
* 异步支付成功, 更新支付记录成功状态, 并创建微信支付记录
*/
public void updateAsyncSuccess(Long id, PayWayParam payWayParam, String tradeNo) {
public void updateAsyncSuccess(Long id, PayWayParam payWayParam) {
PayOrder payOrder = paymentService.findById(id).orElseThrow(() -> new BizException("支付记录不存在"));
this.createWeChatPayment(payOrder, payWayParam, tradeNo);
this.createWeChatOrder(payOrder, payWayParam.getAmount());
}
/**
* 并创建微信支付记录
*/
private void createWeChatPayment(PayOrder payment, PayWayParam payWayParam, String tradeNo) {
private void createWeChatOrder(PayOrder payOrder, int amount) {
String tradeNo = PaymentContextLocal.get()
.getAsyncPayInfo()
.getTradeNo();
// 创建微信支付记录
WeChatPayment wechatPayment = new WeChatPayment();
wechatPayment.setTradeNo(tradeNo)
.setPaymentId(payment.getId())
.setAmount(payWayParam.getAmount())
.setRefundableBalance(payWayParam.getAmount())
.setBusinessNo(payment.getBusinessNo())
WeChatPayOrder wechatPayOrder = new WeChatPayOrder();
wechatPayOrder.setTradeNo(tradeNo)
.setPaymentId(payOrder.getId())
.setAmount(amount)
.setRefundableBalance(amount)
.setBusinessNo(payOrder.getBusinessNo())
.setStatus(PayStatusEnum.SUCCESS.getCode())
.setPayTime(LocalDateTime.now());
weChatPaymentManager.save(wechatPayment);
weChatPayOrderManager.save(wechatPayOrder);
}
/**
* 取消状态
*/
public void updateClose(Long paymentId) {
Optional<WeChatPayment> weChatPaymentOptional = weChatPaymentManager.findByPaymentId(paymentId);
Optional<WeChatPayOrder> weChatPaymentOptional = weChatPayOrderManager.findByPaymentId(paymentId);
weChatPaymentOptional.ifPresent(weChatPayment -> {
weChatPayment.setStatus(PayStatusEnum.CLOSE.getCode());
weChatPaymentManager.updateById(weChatPayment);
weChatPayOrderManager.updateById(weChatPayment);
});
}
/**
* 更新退款
*/
public void updatePayRefund(Long paymentId, int amount) {
Optional<WeChatPayment> weChatPayment = weChatPaymentManager.findByPaymentId(paymentId);
public void updateRefund(Long paymentId, int amount) {
Optional<WeChatPayOrder> weChatPayment = weChatPayOrderManager.findByPaymentId(paymentId);
weChatPayment.ifPresent(payment -> {
int refundableBalance = payment.getRefundableBalance() - amount;
payment.setRefundableBalance(refundableBalance);
@@ -115,7 +113,7 @@ public class WeChatPayOrderService {
else {
payment.setStatus(PayStatusEnum.PARTIAL_REFUND.getCode());
}
weChatPaymentManager.updateById(payment);
weChatPayOrderManager.updateById(payment);
});
}

View File

@@ -12,11 +12,11 @@ import cn.bootx.platform.daxpay.common.context.AsyncPayLocal;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.core.payment.sync.result.GatewaySyncResult;
import cn.bootx.platform.daxpay.core.payment.sync.service.PaySyncService;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.param.channel.wechat.WeChatPayParam;
import cn.bootx.platform.daxpay.param.pay.PayWayParam;
import cn.bootx.platform.daxpay.result.pay.PaySyncResult;
import cn.bootx.platform.daxpay.util.PayUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.net.NetUtil;
@@ -210,7 +210,7 @@ public class WeChatPayService {
// 支付中, 发起轮训同步
if (Objects.equals(resultCode, WeChatPayCode.TRADE_FAIL)
&& Objects.equals(errCode, WeChatPayCode.TRADE_USERPAYING)) {
SpringUtil.getBean(this.getClass()).rotationSync(payment, weChatPayConfig);
SpringUtil.getBean(this.getClass()).rotationSync(payment);
return result.get(WeChatPayCode.TRANSACTION_ID);
}
@@ -272,15 +272,12 @@ public class WeChatPayService {
*/
@Async("bigExecutor")
@Retryable(value = RetryableException.class, maxAttempts = 10, backoff = @Backoff(value = 5000L))
public void rotationSync(PayOrder payOrder, WeChatPayConfig weChatPayConfig) {
GatewaySyncResult syncResult = weChatPaySyncService.syncPayStatus(payOrder.getId(), weChatPayConfig);
public void rotationSync(PayOrder payOrder) {
PaySyncResult paySyncResult = paySyncService.syncPayOrder(payOrder);
// 不为支付中状态后, 调用系统同步更新状态, 支付状态则继续重试
if (Objects.equals(PAY_WAIT.getCode(), syncResult.getSyncStatus())) {
if (Objects.equals(PAY_WAIT.getCode(), paySyncResult.getSyncStatus())) {
throw new RetryableException();
}
else {
paySyncService.syncPayOrder(payOrder);
}
}
}

View File

@@ -1,10 +1,8 @@
package cn.bootx.platform.daxpay.core.channel.wechat.service;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
import cn.bootx.platform.daxpay.code.WeChatPayCode;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.core.payment.sync.result.GatewaySyncResult;
import cn.hutool.json.JSONUtil;
import com.ijpay.core.enums.SignType;
@@ -60,7 +58,7 @@ public class WeChatPaySyncService {
// 支付完成
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_SUCCESS)
|| Objects.equals(tradeStatus, WeChatPayCode.TRADE_ACCEPT)) {
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS.getCode()).setMap(result);
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS.getCode());
}
// 待支付
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_NOTPAY)
@@ -85,33 +83,4 @@ public class WeChatPaySyncService {
}
return syncResult;
}
/**
* 比对网关状态和支付单状态
*/
public boolean isStatusSync(GatewaySyncResult syncResult, PayOrder payOrder) {
String syncStatus = syncResult.getSyncStatus();
String orderStatus = payOrder.getStatus();
// 支付成功比对
if (orderStatus.equals(PayStatusEnum.SUCCESS.getCode()) && syncStatus.equals(PaySyncStatusEnum.PAY_SUCCESS.getCode())){
return true;
}
// 待支付比对
if (orderStatus.equals(PayStatusEnum.PROGRESS.getCode()) && syncStatus.equals(PaySyncStatusEnum.PAY_WAIT.getCode())){
return true;
}
// 支付关闭比对
if (orderStatus.equals(PayStatusEnum.CLOSE.getCode()) && syncStatus.equals(PaySyncStatusEnum.CLOSED.getCode())){
return true;
}
// 退款比对
if (orderStatus.equals(PayStatusEnum.REFUNDED.getCode()) && syncStatus.equals(PaySyncStatusEnum.REFUND.getCode())){
return true;
}
return false;
}
}

View File

@@ -0,0 +1,49 @@
package cn.bootx.platform.daxpay.core.order.pay.service;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderChannelManager;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrderChannel;
import cn.bootx.platform.daxpay.param.pay.PayWayParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
/**
* 支付订单关联通道服务
* @author xxm
* @since 2023/12/31
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class PayOrderChannelService {
private final PayOrderChannelManager payOrderChannelManager;
/**
* 更新支付订单的通道信息
*/
@Transactional(rollbackFor = Exception.class)
public void updateChannel(PayWayParam payWayParam, PayOrder payOrder){
Optional<PayOrderChannel> payOrderChannelOpt = payOrderChannelManager.findByPaymentIdAndChannel(payOrder.getId(), PayChannelEnum.WECHAT.getCode());
if (!payOrderChannelOpt.isPresent()){
payOrderChannelManager.deleteByPaymentIdAndAsync(payOrder.getId());
payOrderChannelManager.save(new PayOrderChannel()
.setPaymentId(payOrder.getId())
.setChannel(PayChannelEnum.ALI.getCode())
.setAmount(payWayParam.getAmount())
.setPayWay(payWayParam.getWay())
.setChannelExtra(payWayParam.getChannelExtra())
.setAsync(true)
);
} else {
payOrderChannelOpt.get()
.setChannelExtra(payWayParam.getChannelExtra())
.setPayWay(payWayParam.getWay());
payOrderChannelManager.updateById(payOrderChannelOpt.get());
}
}
}

View File

@@ -50,7 +50,7 @@ public class PayCallbackService {
return new PayCallbackResult().setStatus(PayNotifyStatusEnum.FAIL.getCode()).setMsg("支付单不存在,记录回调记录");
}
// 回调时间超出了支付单超时时间, 记录一下, 不做处理 TODO 这块应该订单给正常处理了,
// 回调时间超出了支付单超时时间, 记录一下, 不做处理 TODO 这块应该订单给正常处理了,
if (Objects.nonNull(payOrder.getExpiredTime())
&& LocalDateTimeUtil.ge(LocalDateTime.now(), payOrder.getExpiredTime())) {
return new PayCallbackResult().setStatus(PayNotifyStatusEnum.FAIL.getCode()).setMsg("回调时间超出了支付单支付有效时间");
@@ -144,7 +144,7 @@ public class PayCallbackService {
// 4.处理方法, 支付时只有一种payModel(异步支付), 失败时payment的所有payModel都会生效
boolean handlerFlag = this.doHandler(payOrder, paymentStrategyList, (strategyList, paymentObj) -> {
// 执行异步支付方式的失败回调(不会有同步payModel)
strategyList.forEach(AbsPayStrategy::doCancelHandler);
strategyList.forEach(AbsPayStrategy::doCloseHandler);
// 修改payment支付状态为撤销
paymentObj.setStatus(PayStatusEnum.CLOSE.getCode());

View File

@@ -77,7 +77,7 @@ public class PayCloseService {
payCloseStrategies.forEach(AbsPayCloseStrategy::doCloseHandler);
}
catch (Exception e) {
// 记录关闭失败的记录
// TODO 记录关闭失败的记录
throw e;
}

View File

@@ -1,9 +1,9 @@
package cn.bootx.platform.daxpay.core.payment.close.strategy;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayCloseService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayOrderService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AlipayConfigService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayConfigService;
import cn.bootx.platform.daxpay.func.AbsPayCloseStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -23,7 +23,7 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@RequiredArgsConstructor
public class AliPayCloseStrategy extends AbsPayCloseStrategy {
private final AlipayConfigService alipayConfigService;
private final AliPayConfigService alipayConfigService;
private final AliPayOrderService aliPayOrderService;
@@ -34,7 +34,7 @@ public class AliPayCloseStrategy extends AbsPayCloseStrategy {
*/
@Override
public void doBeforeCloseHandler() {
AlipayConfig config = alipayConfigService.getConfig();
AliPayConfig config = alipayConfigService.getConfig();
alipayConfigService.initConfig(config);
}

View File

@@ -1,5 +1,6 @@
package cn.bootx.platform.daxpay.core.payment.close.strategy;
import cn.bootx.platform.daxpay.core.channel.cash.service.CashService;
import cn.bootx.platform.daxpay.func.AbsPayCloseStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -18,12 +19,12 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Service
@RequiredArgsConstructor
public class CashPayCloseStrategy extends AbsPayCloseStrategy {
private final CashService cashService;
/**
* 关闭操作
*/
@Override
public void doCloseHandler() {
cashService.close(this.getOrder().getId());
}
}

View File

@@ -9,7 +9,7 @@ import org.springframework.stereotype.Service;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
*
* 云闪付
* @author xxm
* @since 2023/12/30
*/

View File

@@ -1,5 +1,7 @@
package cn.bootx.platform.daxpay.core.payment.close.strategy;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPayOrderService;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPayService;
import cn.bootx.platform.daxpay.func.AbsPayCloseStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -9,7 +11,7 @@ import org.springframework.stereotype.Service;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
*
* 储值卡
* @author xxm
* @since 2023/12/30
*/
@@ -19,11 +21,16 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@RequiredArgsConstructor
public class VoucherPayCloseStrategy extends AbsPayCloseStrategy {
private final VoucherPayService voucherPayService;
private final VoucherPayOrderService voucherPayOrderService;
/**
* 关闭操作
*/
@Override
public void doCloseHandler() {
voucherPayService.close(this.getOrder().getId());
voucherPayOrderService.updateClose(this.getOrder().getId());
}
}

View File

@@ -1,5 +1,7 @@
package cn.bootx.platform.daxpay.core.payment.close.strategy;
import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletPayOrderService;
import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletPayService;
import cn.bootx.platform.daxpay.func.AbsPayCloseStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -18,13 +20,15 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Service
@RequiredArgsConstructor
public class WalletPayCloseStrategy extends AbsPayCloseStrategy {
private final WalletPayService walletPayService;
private final WalletPayOrderService walletPayOrderService;
/**
* 关闭操作
*/
@Override
public void doCloseHandler() {
walletPayService.close(this.getOrder().getId());
walletPayOrderService.updateClose(this.getOrder().getId());
}
}

View File

@@ -13,7 +13,7 @@ import org.springframework.stereotype.Service;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
*
* 微信支付关闭策略
* @author xxm
* @since 2023/12/30
*/

View File

@@ -4,7 +4,7 @@ import cn.bootx.platform.daxpay.code.AliPayCode;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.common.exception.ExceptionInfo;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.service.*;
import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
@@ -37,11 +37,11 @@ public class AliPayStrategy extends AbsPayStrategy {
private final AliPayService aliPayService;
private final AlipayConfigService alipayConfigService;
private final AliPayConfigService alipayConfigService;
private final AliPayCloseService aliPayCancelService;
private AlipayConfig alipayConfig;
private AliPayConfig alipayConfig;
private AliPayParam aliPayParam;
@@ -120,23 +120,13 @@ public class AliPayStrategy extends AbsPayStrategy {
this.doCloseHandler();
}
/**
* 撤销支付
*/
@Override
public void doCancelHandler() {
this.initAlipayConfig();
// 关闭支付
aliPayCancelService.close(this.getOrder());
// 调用关闭本地支付记录
this.doCloseHandler();
}
/**
* 关闭支付记录
*/
@Override
public void doCloseHandler() {
// 关闭支付
aliPayCancelService.close(this.getOrder());
aliPaymentService.updateClose(this.getOrder().getId());
}

View File

@@ -4,7 +4,7 @@ import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.Voucher;
import cn.bootx.platform.daxpay.core.channel.voucher.entity.VoucherRecord;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPayService;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPaymentService;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPayOrderService;
import cn.bootx.platform.daxpay.func.AbsPayStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -27,9 +27,9 @@ public class VoucherPayStrategy extends AbsPayStrategy {
private final VoucherPayService voucherPayService;
private final VoucherPaymentService voucherPaymentService;
private final VoucherPayOrderService voucherPayOrderService;
private Voucher vouchers;
private Voucher voucher;
@Override
public PayChannelEnum getType() {
@@ -42,21 +42,23 @@ public class VoucherPayStrategy extends AbsPayStrategy {
@Override
public void doBeforePayHandler() {
// 获取并校验储值卡
this.vouchers = voucherPayService.getAndCheckVoucher(this.getPayWayParam());
this.voucher = voucherPayService.getAndCheckVoucher(this.getPayWayParam());
}
/**
* 支付操作
* 1. 异步支付: 发起支付时冻结, 支付完成后扣减, 支付失败和关闭支付后解冻
* 2. 同步支付: 直接扣减
*/
@Override
public void doPayHandler() {
VoucherRecord voucherRecord;
if (this.getOrder().isAsyncPay()){
voucherRecord = voucherPayService.freezeBalance(this.getPayWayParam().getAmount(), this.getOrder(), this.vouchers);
voucherRecord = voucherPayService.freezeBalance(this.getPayWayParam().getAmount(), this.getOrder(), this.voucher);
} else {
voucherRecord = voucherPayService.pay(this.getPayWayParam().getAmount(), this.getOrder(), this.vouchers);
voucherRecord = voucherPayService.pay(this.getPayWayParam().getAmount(), this.getOrder(), this.voucher);
}
voucherPaymentService.savePayment(this.getOrder(), getPayParam(), getPayWayParam(), voucherRecord);
voucherPayOrderService.savePayment(this.getOrder(), getPayParam(), getPayWayParam(), voucherRecord);
}
/**
@@ -67,7 +69,7 @@ public class VoucherPayStrategy extends AbsPayStrategy {
if (this.getOrder().isAsyncPay()){
voucherPayService.paySuccess(this.getOrder().getId());
}
voucherPaymentService.updateSuccess(this.getOrder().getId());
voucherPayOrderService.updateSuccess(this.getOrder().getId());
}
/**
@@ -76,7 +78,7 @@ public class VoucherPayStrategy extends AbsPayStrategy {
@Override
public void doCloseHandler() {
voucherPayService.close(this.getOrder().getId());
voucherPaymentService.updateClose(this.getOrder().getId());
voucherPayOrderService.updateClose(this.getOrder().getId());
}
}

View File

@@ -3,12 +3,13 @@ package cn.bootx.platform.daxpay.core.payment.pay.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.WeChatPayCode;
import cn.bootx.platform.daxpay.common.exception.ExceptionInfo;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.channel.wechat.dao.WeChatPayConfigManager;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayCloseService;
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayOrderService;
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayService;
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPaySyncService;
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayOrderService;
import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.func.AbsPayStrategy;
@@ -117,8 +118,8 @@ public class WeChatPayStrategy extends AbsPayStrategy {
*/
@Override
public void doAsyncSuccessHandler(Map<String, String> map) {
String tradeNo = map.get(WeChatPayCode.TRANSACTION_ID);
weChatPayOrderService.updateAsyncSuccess(this.getOrder().getId(), this.getPayWayParam(), tradeNo);
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(map.get(WeChatPayCode.TRANSACTION_ID));
weChatPayOrderService.updateAsyncSuccess(this.getOrder().getId(), this.getPayWayParam());
}
/**
@@ -126,19 +127,7 @@ public class WeChatPayStrategy extends AbsPayStrategy {
*/
@Override
public void doAsyncErrorHandler(ExceptionInfo exceptionInfo) {
// 调用撤销支付
this.doCancelHandler();
}
/**
* 撤销支付
*/
@Override
public void doCancelHandler() {
// 检查并获取微信支付配置
this.initWeChatPayConfig();
weChatPayCloseService.close(this.getOrder(), weChatPayConfig);
// 调用关闭本地支付记录
// 调用关闭支付
this.doCloseHandler();
}
@@ -147,6 +136,7 @@ public class WeChatPayStrategy extends AbsPayStrategy {
*/
@Override
public void doCloseHandler() {
weChatPayCloseService.close(this.getOrder(), weChatPayConfig);
weChatPayOrderService.updateClose(this.getOrder().getId());
}

View File

@@ -1,10 +1,10 @@
package cn.bootx.platform.daxpay.core.payment.refund.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayOrderService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayRefundService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AlipayConfigService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayConfigService;
import cn.bootx.platform.daxpay.core.order.pay.service.PayOrderService;
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
import lombok.RequiredArgsConstructor;
@@ -23,7 +23,7 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@RequiredArgsConstructor
public class AliPayRefundStrategy extends AbsPayRefundStrategy {
private final AlipayConfigService alipayConfigService;
private final AliPayConfigService alipayConfigService;
private final AliPayOrderService aliPayOrderService;
private final AliPayRefundService aliRefundService;
/**
@@ -44,7 +44,7 @@ public class AliPayRefundStrategy extends AbsPayRefundStrategy {
*/
@Override
public void doBeforeRefundHandler() {
AlipayConfig config = alipayConfigService.getConfig();
AliPayConfig config = alipayConfigService.getConfig();
alipayConfigService.initConfig(config);
}
@@ -54,7 +54,7 @@ public class AliPayRefundStrategy extends AbsPayRefundStrategy {
@Override
public void doRefundHandler() {
aliRefundService.refund(this.getOrder(), this.getChannelParam().getAmount());
aliPayOrderService.updatePayRefund(this.getOrder().getId(), this.getChannelParam().getAmount());
aliPayOrderService.updateRefund(this.getOrder().getId(), this.getChannelParam().getAmount());
payOrderService.updateRefundSuccess(this.getOrder(), this.getChannelParam().getAmount(), PayChannelEnum.ALI);
}

View File

@@ -2,7 +2,7 @@ package cn.bootx.platform.daxpay.core.payment.refund.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPayService;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPaymentService;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPayOrderService;
import cn.bootx.platform.daxpay.core.order.pay.service.PayOrderService;
import cn.bootx.platform.daxpay.func.AbsPayRefundStrategy;
import lombok.RequiredArgsConstructor;
@@ -21,7 +21,7 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@RequiredArgsConstructor
public class VoucherPayRefundStrategy extends AbsPayRefundStrategy {
private final VoucherPayService voucherPayService;
private final VoucherPaymentService voucherPaymentService;
private final VoucherPayOrderService voucherPayOrderService;
private final PayOrderService payOrderService;
/**
@@ -40,7 +40,7 @@ public class VoucherPayRefundStrategy extends AbsPayRefundStrategy {
@Override
public void doRefundHandler() {
voucherPayService.refund(this.getOrder().getId(), this.getChannelParam().getAmount());
voucherPaymentService.updateRefund(this.getOrder().getId(), this.getChannelParam().getAmount());
voucherPayOrderService.updateRefund(this.getOrder().getId(), this.getChannelParam().getAmount());
payOrderService.updateRefundSuccess(this.getOrder(), this.getChannelParam().getAmount(), PayChannelEnum.VOUCHER);
}
}

View File

@@ -55,7 +55,7 @@ public class WeChatPayRefundStrategy extends AbsPayRefundStrategy {
@Override
public void doRefundHandler() {
wechatRefundService.refund(this.getOrder(), this.getChannelParam().getAmount(), this.weChatPayConfig);
weChatPayOrderService.updatePayRefund(this.getOrder().getId(), this.getChannelParam().getAmount());
weChatPayOrderService.updateRefund(this.getOrder().getId(), this.getChannelParam().getAmount());
payOrderService.updateRefundSuccess(this.getOrder(), this.getChannelParam().getAmount(), PayChannelEnum.WECHAT);
}

View File

@@ -2,8 +2,13 @@ package cn.bootx.platform.daxpay.core.payment.repair.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayRepairSourceEnum;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayCloseService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayOrderService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayConfigService;
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderChannelManager;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrderChannel;
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
import cn.bootx.platform.daxpay.func.AbsPayRepairStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -13,7 +18,7 @@ import org.springframework.stereotype.Service;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
* 支付宝支付单修复策略
* 支付宝单修复策略
* @author xxm
* @since 2023/12/27
*/
@@ -24,17 +29,27 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
public class AliPayRepairStrategy extends AbsPayRepairStrategy {
private final AliPayOrderService orderService;
private final AliPayCloseService closeService;
@Override
public PayChannelEnum getType() {
return PayChannelEnum.ALI;
}
private final AliPayConfigService aliPayConfigService;
private final PayOrderChannelManager orderChannelManager;
/**
* 修复前处理
*/
@Override
public void doBeforeHandler() {
AliPayConfig config = aliPayConfigService.getConfig();
aliPayConfigService.initConfig(config);
}
/**
* 支付成功处理
*/
@Override
public void doSuccessHandler() {
orderService.updateAsyncSuccess(this.getOrder(), 0);
PayOrderChannel orderChannel = orderChannelManager.findByPaymentIdAndChannel(this.getOrder().getId(), PayChannelEnum.ALI.getCode())
.orElseThrow(() -> new PayFailureException("支付宝订单不存在"));
orderService.updateAsyncSuccess(this.getOrder(), orderChannel.getAmount());
}
/**
@@ -54,6 +69,6 @@ public class AliPayRepairStrategy extends AbsPayRepairStrategy {
*/
@Override
public void doRefundHandler() {
orderService.updatePayRefund(this.getOrder().getId(), 0);
orderService.updateRefund(this.getOrder().getId(), 0);
}
}

View File

@@ -1,7 +1,5 @@
package cn.bootx.platform.daxpay.core.payment.repair.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.common.entity.OrderRefundableInfo;
import cn.bootx.platform.daxpay.core.channel.cash.service.CashService;
import cn.bootx.platform.daxpay.func.AbsPayRepairStrategy;
import lombok.RequiredArgsConstructor;
@@ -9,9 +7,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.util.Objects;
import static cn.bootx.platform.daxpay.code.PayChannelEnum.CASH;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;
/**
@@ -27,29 +22,12 @@ public class CashPayRepairStrategy extends AbsPayRepairStrategy {
private final CashService cashService;
/**
* 策略标识
*
* @see PayChannelEnum
*/
@Override
public PayChannelEnum getType() {
return CASH;
}
/**
* 取消支付
*/
@Override
public void doCloseHandler() {
// 获取现金的可退款金额
Integer amount = this.getOrder()
.getRefundableInfos()
.stream()
.filter(info -> Objects.equals(info.getChannel(), CASH.getCode()))
.findFirst()
.map(OrderRefundableInfo::getAmount)
.orElse(0);
cashService.close(this.getOrder().getId());

View File

@@ -1,6 +1,5 @@
package cn.bootx.platform.daxpay.core.payment.repair.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.func.AbsPayRepairStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -19,15 +18,6 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Service
@RequiredArgsConstructor
public class UnionPayRepairStrategy extends AbsPayRepairStrategy {
/**
* 策略标识
*
* @see PayChannelEnum
*/
@Override
public PayChannelEnum getType() {
return null;
}
/**
* 取消支付

View File

@@ -1,6 +1,7 @@
package cn.bootx.platform.daxpay.core.payment.repair.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPayOrderService;
import cn.bootx.platform.daxpay.core.channel.voucher.service.VoucherPayService;
import cn.bootx.platform.daxpay.func.AbsPayRepairStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -19,21 +20,15 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Service
@RequiredArgsConstructor
public class VoucherPayRepairStrategy extends AbsPayRepairStrategy {
/**
* 策略标识
*
* @see PayChannelEnum
*/
@Override
public PayChannelEnum getType() {
return null;
}
private final VoucherPayService voucherPayService;
private final VoucherPayOrderService voucherPayOrderService;
/**
* 取消支付
*/
@Override
public void doCloseHandler() {
voucherPayService.close(this.getOrder().getId());
voucherPayOrderService.updateClose(this.getOrder().getId());
}
}

View File

@@ -1,6 +1,7 @@
package cn.bootx.platform.daxpay.core.payment.repair.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletPayOrderService;
import cn.bootx.platform.daxpay.core.channel.wallet.service.WalletPayService;
import cn.bootx.platform.daxpay.func.AbsPayRepairStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -19,21 +20,17 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Service
@RequiredArgsConstructor
public class WalletPayRepairStrategy extends AbsPayRepairStrategy {
/**
* 策略标识
*
* @see PayChannelEnum
*/
@Override
public PayChannelEnum getType() {
return null;
}
private final WalletPayOrderService walletPayOrderService;
private final WalletPayService walletPayService;
/**
* 取消支付
*/
@Override
public void doCloseHandler() {
walletPayService.close(this.getOrder().getId());
walletPayOrderService.updateClose(this.getOrder().getId());
}
}

View File

@@ -1,6 +1,10 @@
package cn.bootx.platform.daxpay.core.payment.repair.strategy;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayRepairSourceEnum;
import cn.bootx.platform.daxpay.core.channel.wechat.entity.WeChatPayConfig;
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayCloseService;
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayConfigService;
import cn.bootx.platform.daxpay.core.channel.wechat.service.WeChatPayOrderService;
import cn.bootx.platform.daxpay.func.AbsPayRepairStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -19,14 +23,34 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@Service
@RequiredArgsConstructor
public class WeChatPayRepairStrategy extends AbsPayRepairStrategy {
private final WeChatPayCloseService weChatPayCloseService;
private final WeChatPayOrderService weChatPayOrderService;
private final WeChatPayConfigService weChatPayConfigService;
private WeChatPayConfig weChatPayConfig;
/**
* 策略标识
*
* @see PayChannelEnum
* 修复前处理
*/
@Override
public PayChannelEnum getType() {
return null;
public void doBeforeHandler() {
this.weChatPayConfig = weChatPayConfigService.getConfig();
}
/**
* 支付成功处理
*/
@Override
public void doSuccessHandler() {
weChatPayOrderService.updateAsyncSuccess();
}
/**
* 退款处理 todo 需要结合退款同步功能进行协同实现
*/
@Override
public void doRefundHandler() {
}
/**
@@ -34,6 +58,10 @@ public class WeChatPayRepairStrategy extends AbsPayRepairStrategy {
*/
@Override
public void doCloseHandler() {
// 如果非同步出的订单取消状态, 则调用支付网关关闭订单
if (this.getRepairSource() != PayRepairSourceEnum.SYNC){
weChatPayCloseService.close(this.getOrder(),this.weChatPayConfig);
}
weChatPayOrderService.updateClose(this.getOrder().getId());
}
}

View File

@@ -4,8 +4,6 @@ import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Map;
import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.NOT_SYNC;
/**
@@ -24,10 +22,6 @@ public class GatewaySyncResult {
*/
private String syncStatus = NOT_SYNC.getCode();
// TODO 根据后期情况合并到上下文中
/** 网关返回参数(会被用到的参数) */
private Map<String, String> map;
/** 网关返回对象的json字符串 */
private String json;

View File

@@ -3,6 +3,7 @@ package cn.bootx.platform.daxpay.core.payment.sync.service;
import cn.bootx.platform.common.core.exception.BizException;
import cn.bootx.platform.daxpay.code.PayRepairSourceEnum;
import cn.bootx.platform.daxpay.code.PayRepairTypeEnum;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
import cn.bootx.platform.daxpay.core.order.pay.dao.PayOrderManager;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
@@ -53,11 +54,13 @@ public class PaySyncService {
if (!payOrder.isAsyncPay()){
return new PaySyncResult().setSuccess(true).setRepair(false);
}
// 执行同步逻辑
// 执行订单同步逻辑
return this.syncPayOrder(payOrder);
}
/**
* 同步支付状态 传入 payment 对象
* 同步支付状态
* 1. 如果状态一致, 不进行处理
* 2. 如果状态不一致, 调用修复逻辑进行修复
*/
public PaySyncResult syncPayOrder(PayOrder order) {
// 获取同步策略类
@@ -67,7 +70,7 @@ public class PaySyncService {
GatewaySyncResult syncResult = syncPayStrategy.doSyncStatus();
// 判断网关状态是否和支付单一致
boolean statusSync = syncPayStrategy.isStatusSync(syncResult);
boolean statusSync = this.isStatusSync(syncResult,order);
// 状态不一致,执行支付单修复逻辑
if (!statusSync){
// 根据同步记录对支付单进行处理处理
@@ -75,19 +78,43 @@ public class PaySyncService {
}
// 记录同步的结果
syncOrderService.saveRecord(syncResult,order);
return null;
return new PaySyncResult().setSuccess(true).setRepair(!statusSync).setSyncStatus(syncResult.getSyncStatus());
}
/**
* 支付单和网关状态是否一致
*/
public boolean isStatusSync(GatewaySyncResult syncResult, PayOrder order){
String syncStatus = syncResult.getSyncStatus();
String orderStatus = order.getStatus();
// 支付成功比对
if (orderStatus.equals(PayStatusEnum.SUCCESS.getCode()) && syncStatus.equals(PaySyncStatusEnum.PAY_SUCCESS.getCode())){
return true;
}
// 待支付比对
if (orderStatus.equals(PayStatusEnum.PROGRESS.getCode()) && syncStatus.equals(PaySyncStatusEnum.PAY_WAIT.getCode())){
return true;
}
// 支付关闭比对
if (orderStatus.equals(PayStatusEnum.CLOSE.getCode()) && syncStatus.equals(PaySyncStatusEnum.CLOSED.getCode())){
return true;
}
// 退款比对
if (orderStatus.equals(PayStatusEnum.REFUNDED.getCode()) && syncStatus.equals(PaySyncStatusEnum.REFUND.getCode())){
return true;
}
return false;
}
/**
* 根据同步的结果对支付单进行处理
* 1. 如果状态一致, 不进行处理
* 2. 如果状态不一致, 调用修复逻辑进行修复
*/
private void resultHandler(GatewaySyncResult syncResult, PayOrder payOrder){
PaySyncStatusEnum syncStatusEnum = PaySyncStatusEnum.getByCode(syncResult.getSyncStatus());
PayRepairParam repairParam = new PayRepairParam()
.setRepairSource(PayRepairSourceEnum.SYNC);
PayRepairParam repairParam = new PayRepairParam().setRepairSource(PayRepairSourceEnum.SYNC);
// 对支付网关同步的结果进行处理
switch (syncStatusEnum) {
// 支付成功 支付宝退款时也是支付成功状态, 除非支付完成
@@ -101,15 +128,15 @@ public class PaySyncService {
log.info("依然是付款状态");
break;
}
// 订单已经关闭超时关闭 和 网关没找到记录, 支付宝退款完成也是这个状态
// 订单已经关闭超时关闭 和 网关没找到记录,
case CLOSED:
case NOT_FOUND: {
// 判断下是否超时, 同时payment 变更为取消支付
// 判断下是否超时, 变更为关闭支付
repairParam.setRepairType(PayRepairTypeEnum.CLOSE);
repairService.repair(payOrder, repairParam);
break;
}
// 交易退款
// 交易退款 TODO 未实现
case REFUND: {
repairParam.setRepairType(PayRepairTypeEnum.REFUND);
repairService.repair(payOrder, repairParam);
@@ -117,7 +144,7 @@ public class PaySyncService {
}
// 调用出错
case FAIL: {
// 不进行处理
// 不进行处理 TODO 添加重试
log.warn("支付状态同步接口调用出错");
break;
}

View File

@@ -1,9 +1,9 @@
package cn.bootx.platform.daxpay.core.payment.sync.strategy;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AlipayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AlipayConfigService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AlipaySyncService;
import cn.bootx.platform.daxpay.core.channel.alipay.entity.AliPayConfig;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPayConfigService;
import cn.bootx.platform.daxpay.core.channel.alipay.service.AliPaySyncService;
import cn.bootx.platform.daxpay.func.AbsPaySyncStrategy;
import cn.bootx.platform.daxpay.core.payment.sync.result.GatewaySyncResult;
import lombok.RequiredArgsConstructor;
@@ -22,9 +22,9 @@ import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROT
@RequiredArgsConstructor
public class AliPaySyncStrategy extends AbsPaySyncStrategy {
private final AlipayConfigService alipayConfigService;
private final AliPayConfigService alipayConfigService;
private final AlipaySyncService alipaySyncService;
private final AliPaySyncService alipaySyncService;
/**
* 异步支付单与支付网关进行状态比对
@@ -32,7 +32,7 @@ public class AliPaySyncStrategy extends AbsPaySyncStrategy {
@Override
public GatewaySyncResult doSyncStatus() {
this.initAlipayConfig();
return alipaySyncService.syncPayStatus(this.getOrder().getId());
return alipaySyncService.syncPayStatus(this.getOrder());
}
/**
@@ -40,7 +40,7 @@ public class AliPaySyncStrategy extends AbsPaySyncStrategy {
*/
private void initAlipayConfig() {
// 检查并获取支付宝支付配置
AlipayConfig config = alipayConfigService.getConfig();
AliPayConfig config = alipayConfigService.getConfig();
alipayConfigService.initConfig(config);
}
}

View File

@@ -18,7 +18,7 @@ import java.util.List;
@Data
@Accessors(chain = true)
@Schema(title = "支付宝配置")
public class AlipayConfigDto extends BaseDto implements Serializable {
public class AliPayConfigDto extends BaseDto implements Serializable {
private static final long serialVersionUID = 6641158663606363171L;

View File

@@ -2,6 +2,7 @@ package cn.bootx.platform.daxpay.func;
import cn.bootx.platform.common.redis.RedisClient;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.common.local.PaymentContextLocal;
import cn.bootx.platform.daxpay.core.callback.dao.CallbackNotifyManager;
import cn.bootx.platform.daxpay.core.callback.entity.CallbackNotify;
import cn.bootx.platform.daxpay.core.payment.callback.result.PayCallbackResult;
@@ -36,26 +37,20 @@ public abstract class AbsPayCallbackStrategy implements PayStrategy {
* 支付回调
*/
public String payCallback(Map<String, String> params) {
PARAMS.set(params);
try {
log.info("支付回调处理: {}", params);
// 验证消息
if (!this.verifyNotify()) {
return null;
}
// 去重处理
if (!this.duplicateChecker()) {
return this.getReturnMsg();
}
// 调用统一回调处理
PayCallbackResult result = payCallbackService.callback(this.getPaymentId(), this.getTradeStatus(),
params);
// 记录回调记录
this.saveNotifyRecord(result);
PaymentContextLocal.get().getCallbackParam().putAll(params);
log.info("支付回调处理: {}", params);
// 验证消息
if (!this.verifyNotify()) {
return null;
}
finally {
PARAMS.remove();
// 去重处理
if (!this.duplicateChecker()) {
return this.getReturnMsg();
}
// 调用统一回调处理
PayCallbackResult result = payCallbackService.callback(this.getPaymentId(), this.getTradeStatus(), params);
// 记录回调记录
this.saveNotifyRecord(result);
return this.getReturnMsg();
}
@@ -99,8 +94,9 @@ public abstract class AbsPayCallbackStrategy implements PayStrategy {
* 保存回调记录
*/
public void saveNotifyRecord(PayCallbackResult result) {
Map<String, String> callbackParam = PaymentContextLocal.get().getCallbackParam();
CallbackNotify payNotifyRecord = new CallbackNotify()
.setNotifyInfo(JSONUtil.toJsonStr(PARAMS.get()))
.setNotifyInfo(JSONUtil.toJsonStr(callbackParam))
.setNotifyTime(LocalDateTime.now())
.setPaymentId(this.getPaymentId())
.setPayChannel(this.getPayChannel().getCode())

View File

@@ -1,6 +1,5 @@
package cn.bootx.platform.daxpay.func;
import cn.bootx.platform.daxpay.code.PayChannelEnum;
import cn.bootx.platform.daxpay.code.PayRepairSourceEnum;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import lombok.Getter;
@@ -32,10 +31,11 @@ public abstract class AbsPayRepairStrategy {
}
/**
* 策略标识
* @see PayChannelEnum
* 修复前处理
*/
public abstract PayChannelEnum getType();
public void doBeforeHandler(){
}
/**
* 支付成功处理
@@ -50,7 +50,7 @@ public abstract class AbsPayRepairStrategy {
public abstract void doCloseHandler();
/**
* 退款处理
* 退款处理 todo 需要结合退款同步功能进行协同实现
*/
public void doRefundHandler() {

View File

@@ -84,17 +84,8 @@ public abstract class AbsPayStrategy implements PayStrategy{
}
/**
* 撤销支付操作,支付交易返回失败或支付系统超时,调用该接口撤销交易 默认为关闭本地支付记录
* 关闭支付. 支付交易返回失败或支付系统超时调通该接口关闭支付
*/
@Deprecated
public void doCancelHandler() {
this.doCloseHandler();
}
/**
* 关闭本地支付记录
*/
@Deprecated
public abstract void doCloseHandler();

View File

@@ -1,6 +1,5 @@
package cn.bootx.platform.daxpay.func;
import cn.bootx.platform.daxpay.code.PayStatusEnum;
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
import cn.bootx.platform.daxpay.core.order.pay.entity.PayOrder;
import cn.bootx.platform.daxpay.core.payment.sync.result.GatewaySyncResult;
@@ -33,31 +32,4 @@ public abstract class AbsPaySyncStrategy implements PayStrategy{
*/
public abstract GatewaySyncResult doSyncStatus();
/**
* 支付单和网关状态是否一致
*/
public boolean isStatusSync(GatewaySyncResult syncResult){
String syncStatus = syncResult.getSyncStatus();
String orderStatus = order.getStatus();
// 支付成功比对
if (orderStatus.equals(PayStatusEnum.SUCCESS.getCode()) && syncStatus.equals(PaySyncStatusEnum.PAY_SUCCESS.getCode())){
return true;
}
// 待支付比对
if (orderStatus.equals(PayStatusEnum.PROGRESS.getCode()) && syncStatus.equals(PaySyncStatusEnum.PAY_WAIT.getCode())){
return true;
}
// 支付关闭比对
if (orderStatus.equals(PayStatusEnum.CLOSE.getCode()) && syncStatus.equals(PaySyncStatusEnum.CLOSED.getCode())){
return true;
}
// 退款比对
if (orderStatus.equals(PayStatusEnum.REFUNDED.getCode()) && syncStatus.equals(PaySyncStatusEnum.REFUND.getCode())){
return true;
}
return false;
}
}

View File

@@ -13,7 +13,7 @@ import java.util.List;
@Data
@Accessors(chain = true)
@Schema(title = "支付宝配置参数")
public class AlipayConfigParam {
public class AliPayConfigParam {
@Schema(description = "名称")
private String name;