mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-09-08 13:37:35 +00:00
feat 支付同步/发起支付时, 如果订单已经超时, 但状态还是待支付, 触发修复操作关闭订单, 增加支付单关闭记录功能, 同步记录/关闭记录/修复记录 增加记录请求ID, 支付单存在异步支付时, 支付时间需要读取支付网关的返回的时间
fix 支付宝关闭支付订单,如果网关已经关闭,会返回错误导致本地订单无法关闭
This commit is contained in:
@@ -13,6 +13,8 @@
|
||||
## 🙏🙏🙏 求star呀,走过路过留个star吧,非常非常感谢。🙏🙏🙏
|
||||
|
||||
## 🍈项目介绍
|
||||
[**查看开发进度**](https://gitee.com/bootx/dax-pay/issues/I8TQ9Q)
|
||||
|
||||
单商户模式模式重构中, 敬请期待!!!
|
||||
|
||||
|
||||
|
48
_doc/Task.md
48
_doc/Task.md
@@ -1,28 +1,40 @@
|
||||
2.0.0
|
||||
2.0.0 重构进度
|
||||
- 已经完成的
|
||||
- 参数签名和验签机制
|
||||
- 开放接口供第三方调用
|
||||
- 将零散的上下文对象进行抽取为统一的上下文对象
|
||||
- 拆分原有的策略类,实现粒度更细
|
||||
- 去除用户概念,作为独立的支付网关使用, 不与其他系统产生耦合性
|
||||
- [x] 参数签名和验签机制
|
||||
- [x] 开放接口供第三方调用
|
||||
- [x] 将零散的上下文对象进行抽取为统一的上下文对象
|
||||
- [x] 拆分原有的策略类,实现粒度更细
|
||||
- [x] 去除用户概念,作为独立的支付网关使用, 不与其他系统产生耦合性
|
||||
- 2023-12-31:
|
||||
- 支付关闭相关逻辑
|
||||
- 各支付通道补充相关未实现的逻辑
|
||||
- 支付订单修复逻辑, 用于回调和支付同步后不一致的情况处理
|
||||
- [x] 支付关闭相关逻辑
|
||||
- [x] 各支付通道补充相关未实现的逻辑
|
||||
- [x] 支付订单修复逻辑, 用于回调和同步不一致的情况处理
|
||||
- 2024-01-01:
|
||||
- 支付订单修复逻辑, 用于回调和支付同步后不一致的情况处理
|
||||
- [x] 支付订单修复逻辑, 用于回调和支付同步后不一致的情况处理
|
||||
- 2024-01-02:
|
||||
- 添加管理端的各类`Controller`
|
||||
- x 支持定时同步支付中订单状态, 借助订单超时任务
|
||||
- 订单取消/修复/取消/同步添加分布式锁, 防止操作订单时出现重复操作
|
||||
- [x] 添加管理端的各类`Controller`
|
||||
- [x] 支持定时同步支付中订单状态, 借助订单超时任务
|
||||
- 2024-01-03:
|
||||
- [x] 支付流程联调
|
||||
- [x] 支付同步和支付修复流程优化
|
||||
- [x] 支付平台全局性配置
|
||||
- 2024-01-04:
|
||||
- [x] 支付同步时, 如果订单已经超时, 但状态还是待支付, 触发修复操作关闭订单
|
||||
- [x] 发起支付时, 如果已经超过订单超时时间, 但状态还是待支付, 触发同步和修复操作
|
||||
- [x] 支付宝关闭支付订单,如果网关已经关闭,会返回错误导致本地订单无法关闭
|
||||
- [x] 增加支付单关闭记录功能
|
||||
- [x] 支付单存在异步支付时, 支付时间需要读取支付网关的返回的时间
|
||||
- [x] 同步记录/关闭记录/修复记录 增加记录请求ID
|
||||
- 2024-01-05:
|
||||
- [x] 支付同步日志记录, 无论同步成功还是失败, 以及修复成功还是失败, 都需要记录日志
|
||||
- [ ] 超时自动取消功能联调
|
||||
- **任务池**
|
||||
- 订单取消/修复/取消/同步添加分布式锁, 防止操作订单时出现重复操作
|
||||
- 支付配置支持数据库配置和配置文件配置
|
||||
- 支付订单的各类操作接入订单超时任务处理
|
||||
- 超时任务处理支持轮训表+Redis过期事件
|
||||
- 增加回调机制
|
||||
- 增加消息通知机制
|
||||
- 超时任务处理支持轮训表
|
||||
- 增加回调机制(通知客户端)
|
||||
- 增加消息通知机制(通知客户端)
|
||||
- 新增支付单预警功能, 处理支付单与网关状态不一致且无法自动修复的情况
|
||||
- 记录支付修复单的情况, 主要分为自动修复, 人工介入
|
||||
- 支付平台全局性配置
|
||||
- 微信消息通知相关配置
|
||||
- 钉钉消息通知配置
|
||||
|
@@ -1,8 +1,12 @@
|
||||
package cn.bootx.platform.daxpay.code;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 支付状态
|
||||
* @author xxm
|
||||
@@ -27,4 +31,14 @@ public enum PayStatusEnum {
|
||||
/** 名称 */
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* 根据编码获取枚举
|
||||
*/
|
||||
public static PayStatusEnum findByCode(String code){
|
||||
return Arrays.stream(PayStatusEnum.values())
|
||||
.filter(payStatusEnum -> Objects.equals(payStatusEnum.getCode(), code))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new DataNotExistException("该枚举不存在"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -16,18 +16,14 @@ import java.util.Objects;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum PaySyncStatusEnum {
|
||||
|
||||
NOT_SYNC("not_sync", "不需要同步"),
|
||||
FAIL("fail", "查询失败"),
|
||||
PAY_SUCCESS("pay_success", "支付成功"),
|
||||
PAY_WAIT("pay_wait", "等待付款中"),
|
||||
CLOSED("closed", "已关闭"),
|
||||
REFUND("refund", "已退款"),
|
||||
NOT_FOUND("not_found", "未查询到订单"),
|
||||
/** 例如支付宝支付后, 客户未进行操作, 将不会创建出订单, 所以同步会返回未查询到订单 */
|
||||
IGNORE("ignore", "忽略"),
|
||||
/** 本地订单到了超时时间, 但是网关和本地都未关闭, 需要触发关闭相关处理 */
|
||||
TIMEOUT("timeout", "超时未关闭"),
|
||||
FAIL("fail", "查询失败");
|
||||
TIMEOUT("timeout", "超时未关闭");
|
||||
|
||||
/** 编码 */
|
||||
private final String code;
|
||||
|
@@ -27,7 +27,7 @@ public abstract class PayCommonParam {
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
@Schema(description = "商户扩展参数,回调时会原样返回")
|
||||
private String extraParam;
|
||||
private String attach;
|
||||
|
||||
@Schema(description = "是否不进行同步通知的跳转")
|
||||
private boolean notReturn;
|
||||
|
@@ -18,5 +18,5 @@ public class PayCommonResult {
|
||||
private String reqId = MDC.get(CommonCode.TRACE_ID);
|
||||
|
||||
@Schema(description = "商户扩展参数,回调时会原样返回")
|
||||
private String extraParam;
|
||||
private String attach;
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.NOT_SYNC;
|
||||
import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.FAIL;
|
||||
|
||||
/**
|
||||
* 支付单同步结果
|
||||
@@ -21,13 +21,23 @@ public class PaySyncResult extends PayCommonResult{
|
||||
|
||||
/**
|
||||
* 支付网关同步状态
|
||||
* @see PaySyncStatusEnum#NOT_SYNC
|
||||
* @see PaySyncStatusEnum
|
||||
*/
|
||||
private String syncStatus = NOT_SYNC.getCode();
|
||||
private String syncStatus = FAIL.getCode();
|
||||
|
||||
@Schema(description = "是否同步成功")
|
||||
private boolean success;
|
||||
|
||||
@Schema(description = "失败原因")
|
||||
private String errorMsg;
|
||||
|
||||
@Schema(description = "是否进行了修复")
|
||||
private boolean repair;
|
||||
|
||||
@Schema(description = "支付单修复前状态")
|
||||
private String oldStatus;
|
||||
|
||||
@Schema(description = "支付单修复后状态")
|
||||
private String repairStatus;
|
||||
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ public class PayCallbackController {
|
||||
@Operation(summary = "支付宝回调")
|
||||
@PostMapping("/alipay")
|
||||
public String aliPay(HttpServletRequest request) {
|
||||
|
||||
Map<String, String> stringStringMap = AliPayApi.toMap(request);
|
||||
return aliPayCallbackService.payCallback(stringStringMap);
|
||||
}
|
||||
|
@@ -44,6 +44,9 @@ public interface AliPayCode {
|
||||
/** 支付宝流水号 */
|
||||
String TRADE_NO = "trade_no";
|
||||
|
||||
/** 交易付款时间 yyyy-MM-dd HH:mm:ss */
|
||||
String GMT_PAYMENT = "gmt_payment";
|
||||
|
||||
/** appId */
|
||||
String APP_ID = "app_id";
|
||||
|
||||
@@ -76,6 +79,8 @@ public interface AliPayCode {
|
||||
// 错误提示
|
||||
/** 交易不存在 */
|
||||
String ACQ_TRADE_NOT_EXIST = "ACQ.TRADE_NOT_EXIST";
|
||||
/** 交易不存在 */
|
||||
String ACQ_TRADE_STATUS_ERROR = "ACQ.TRADE_STATUS_ERROR";
|
||||
|
||||
// 网关返回码
|
||||
String SUCCESS = "10000";
|
||||
|
@@ -57,6 +57,9 @@ public interface WeChatPayCode {
|
||||
/** 微信交易单号 */
|
||||
String TRANSACTION_ID = "transaction_id";
|
||||
|
||||
/** 支付完成时间 */
|
||||
String TIME_END = "time_end";
|
||||
|
||||
// 交易状态
|
||||
/** 支付成功 */
|
||||
String TRADE_SUCCESS = "SUCCESS";
|
||||
|
@@ -18,7 +18,6 @@ public class AsyncPayLocal {
|
||||
/** 异步支付方式 */
|
||||
private PayWayEnum payWay;
|
||||
|
||||
|
||||
/**
|
||||
* 第三方支付平台订单号
|
||||
* 1. 如付款码支付直接成功时会出现
|
||||
@@ -33,4 +32,7 @@ public class AsyncPayLocal {
|
||||
/** 订单失效时间, 优先用这个 */
|
||||
private LocalDateTime expiredTime;
|
||||
|
||||
/** 支付完成时间(通常用于接收异步支付返回的时间) */
|
||||
private LocalDateTime payTime;
|
||||
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ public class PaymentContext {
|
||||
/** 平台全局配置 */
|
||||
private final PlatformLocal platform = new PlatformLocal();
|
||||
|
||||
/** 异步支付相关信息, 不只局限在支付流程,同步、退款、回调中都会用到 */
|
||||
/** 异步支付相关信息, 不只局限在支付流程,同步、回调中都会用到 */
|
||||
private final AsyncPayLocal asyncPayInfo = new AsyncPayLocal();
|
||||
|
||||
/** 异步退款相关信息 */
|
||||
|
@@ -18,7 +18,7 @@ public class RequestLocal {
|
||||
private String clientIp;
|
||||
|
||||
/** 商户扩展参数,回调时会原样返回 */
|
||||
private String extraParam;
|
||||
private String attach;
|
||||
|
||||
/** 签名 */
|
||||
private String sign;
|
||||
|
@@ -20,7 +20,7 @@ import lombok.experimental.Accessors;
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@DbTable(comment = "支付宝支付记录")
|
||||
@TableName("pay_ali_payment")
|
||||
@TableName("pay_ali_pay_order")
|
||||
public class AliPayOrder extends BasePayOrder implements EntityBaseFunction<AliPaymentDto> {
|
||||
|
||||
/** 支付宝交易号 */
|
||||
|
@@ -1,15 +1,16 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.alipay.service;
|
||||
|
||||
import cn.bootx.platform.common.core.util.CertUtil;
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.common.redis.RedisClient;
|
||||
import cn.bootx.platform.daxpay.service.code.AliPayCode;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.dao.CallbackRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.callback.service.PayCallbackService;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.dao.PayCallbackRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.func.AbsPayCallbackStrategy;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -20,9 +21,12 @@ import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.bootx.platform.daxpay.service.code.AliPayCode.*;
|
||||
|
||||
/**
|
||||
* 支付宝回调处理
|
||||
*
|
||||
@@ -35,7 +39,7 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
|
||||
|
||||
private final AliPayConfigService aliasConfigService;
|
||||
|
||||
public AliPayCallbackService(RedisClient redisClient, CallbackRecordManager callbackRecordManager,
|
||||
public AliPayCallbackService(RedisClient redisClient, PayCallbackRecordManager callbackRecordManager,
|
||||
PayCallbackService payCallbackService, AliPayConfigService aliasConfigService) {
|
||||
super(redisClient, callbackRecordManager, payCallbackService);
|
||||
this.aliasConfigService = aliasConfigService;
|
||||
@@ -55,8 +59,8 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
|
||||
@Override
|
||||
public String getTradeStatus() {
|
||||
Map<String, String> params = PaymentContextLocal.get().getCallbackParam();
|
||||
String tradeStatus = params.get(AliPayCode.TRADE_STATUS);
|
||||
if (Objects.equals(tradeStatus, AliPayCode.NOTIFY_TRADE_SUCCESS)) {
|
||||
String tradeStatus = params.get(TRADE_STATUS);
|
||||
if (Objects.equals(tradeStatus, NOTIFY_TRADE_SUCCESS)) {
|
||||
return PayStatusEnum.SUCCESS.getCode();
|
||||
}
|
||||
return PayStatusEnum.FAIL.getCode();
|
||||
@@ -70,7 +74,7 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
|
||||
public boolean verifyNotify() {
|
||||
Map<String, String> params =PaymentContextLocal.get().getCallbackParam();
|
||||
String callReq = JSONUtil.toJsonStr(params);
|
||||
String appId = params.get(AliPayCode.APP_ID);
|
||||
String appId = params.get(APP_ID);
|
||||
if (StrUtil.isBlank(appId)) {
|
||||
log.error("支付宝回调报文 appId 为空 {}", callReq);
|
||||
return false;
|
||||
@@ -81,7 +85,7 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (Objects.equals(alipayConfig.getAuthType(), AliPayCode.AUTH_TYPE_KEY)) {
|
||||
if (Objects.equals(alipayConfig.getAuthType(), AUTH_TYPE_KEY)) {
|
||||
return AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipayPublicKey(), CharsetUtil.UTF_8, AlipayConstants.SIGN_TYPE_RSA2);
|
||||
}
|
||||
else {
|
||||
@@ -99,7 +103,16 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
|
||||
@Override
|
||||
public void initContext() {
|
||||
Map<String, String> callbackParam = PaymentContextLocal.get().getCallbackParam();
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(callbackParam.get(AliPayCode.TRADE_NO));
|
||||
// 订单号
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(callbackParam.get(TRADE_NO));
|
||||
// 支付时间
|
||||
String gmpTime = callbackParam.get(GMT_PAYMENT);
|
||||
if (StrUtil.isNotBlank(gmpTime)) {
|
||||
LocalDateTime time = LocalDateTimeUtil.parse(gmpTime, DatePattern.NORM_DATETIME_PATTERN);
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setPayTime(time);
|
||||
} else {
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setPayTime(LocalDateTime.now());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,7 +121,7 @@ public class AliPayCallbackService extends AbsPayCallbackStrategy {
|
||||
@Override
|
||||
public Long getPaymentId() {
|
||||
Map<String, String> params = PaymentContextLocal.get().getCallbackParam();
|
||||
return Long.valueOf(params.get(AliPayCode.OUT_TRADE_NO));
|
||||
return Long.valueOf(params.get(OUT_TRADE_NO));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,7 +1,9 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.alipay.service;
|
||||
|
||||
import cn.bootx.platform.common.spring.exception.RetryableException;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.AliPayCode;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.result.GatewaySyncResult;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import com.alipay.api.AlipayApiException;
|
||||
@@ -25,13 +27,16 @@ import java.util.Objects;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AliPayCloseService {
|
||||
private final AliPaySyncService paySyncService;
|
||||
|
||||
/**
|
||||
* 关闭支付 此处使用交易关闭接口, 支付宝支持 交易关闭 和 交易撤销 两种关闭订单的方式, 区别如下
|
||||
* 交易关闭: 只有订单在未支付的状态下才可以进行关闭, 商户不需要额外申请就有此接口的权限
|
||||
* 交易撤销: 如果用户支付成功,会将此订单资金退还给用户. 限制时间为1天,过了24小时,该接口无法再使用。可以视为一个特殊的接口, 需要专门签约这个接口的权限
|
||||
*
|
||||
* TODO 如果返回已经关闭, 也视为关闭成功, 考虑如果关闭识别, 查询一下网关的状态进行对比
|
||||
* 1. 如果未查询到支付单,视为支付关闭,
|
||||
* 2. 如果返回"当前交易状态不支持此操作", 同步网关支付状态, 判断网关是否已经被关闭
|
||||
*
|
||||
*/
|
||||
@Retryable(value = RetryableException.class)
|
||||
public void close(PayOrder payOrder) {
|
||||
@@ -41,6 +46,16 @@ public class AliPayCloseService {
|
||||
try {
|
||||
AlipayTradeCloseResponse response = AliPayApi.tradeCloseToResponse(model);
|
||||
if (!Objects.equals(AliPayCode.SUCCESS, response.getCode())) {
|
||||
// 如果返回"当前交易状态不支持此操作", 同步网关支付状态, 判断网关是否已经被关闭
|
||||
if (Objects.equals(response.getSubCode(),AliPayCode.ACQ_TRADE_STATUS_ERROR)){
|
||||
if (this.syncStatus(payOrder)){
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 返回"交易不存在"视同关闭成功
|
||||
if (Objects.equals(response.getSubCode(),AliPayCode.ACQ_TRADE_NOT_EXIST)){
|
||||
return;
|
||||
}
|
||||
log.error("网关返回关闭失败: {}", response.getSubMsg());
|
||||
throw new PayFailureException(response.getSubMsg());
|
||||
}
|
||||
@@ -50,4 +65,23 @@ public class AliPayCloseService {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 关闭失败后, 获取支付网关的状态, 如果是关闭返回true, 其他情况抛出异常
|
||||
*/
|
||||
private boolean syncStatus(PayOrder payOrder){
|
||||
GatewaySyncResult gatewaySyncResult = paySyncService.syncPayStatus(payOrder);
|
||||
// 已经关闭
|
||||
if (Objects.equals(gatewaySyncResult.getSyncStatus(), PaySyncStatusEnum.CLOSED)){
|
||||
return true;
|
||||
}
|
||||
// 同步错误
|
||||
else if (Objects.equals(gatewaySyncResult.getSyncStatus(), PaySyncStatusEnum.FAIL)){
|
||||
throw new PayFailureException("关闭失败, 原因: "+gatewaySyncResult.getErrorMsg());
|
||||
}
|
||||
// 其他状态
|
||||
else {
|
||||
throw new PayFailureException("当前交易状态不支持关闭操作, 请对订单同步状态后再进行操作");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,10 +1,10 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.alipay.service;
|
||||
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.AliPayCode;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.dao.AliPayOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.result.GatewaySyncResult;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrder;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -16,6 +16,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@@ -28,8 +29,6 @@ import java.util.Objects;
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AliPaySyncService {
|
||||
private final AliPayOrderManager payOrderManager;
|
||||
|
||||
/**
|
||||
* 与支付宝网关同步状态, 退款状态会
|
||||
* 1 远程支付成功
|
||||
@@ -47,10 +46,13 @@ public class AliPaySyncService {
|
||||
// 查询退款参数
|
||||
AlipayTradeQueryResponse response = AliPayApi.tradeQueryToResponse(queryModel);
|
||||
String tradeStatus = response.getTradeStatus();
|
||||
syncResult.setJson(JSONUtil.toJsonStr(response));
|
||||
syncResult.setSyncInfo(JSONUtil.toJsonStr(response));
|
||||
// 支付完成
|
||||
if (Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_SUCCESS) || Objects.equals(tradeStatus, AliPayCode.PAYMENT_TRADE_FINISHED)) {
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(response.getTradeNo());
|
||||
// 支付完成时间
|
||||
LocalDateTime payTime = LocalDateTimeUtil.of(response.getSendPayDate());
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setPayTime(payTime);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS);
|
||||
}
|
||||
// 待支付
|
||||
@@ -68,12 +70,12 @@ public class AliPaySyncService {
|
||||
}
|
||||
// 支付宝支付后, 客户未进行操作将不会创建出订单, 所以交易不存在等于未查询订单
|
||||
if (Objects.equals(response.getSubCode(), AliPayCode.ACQ_TRADE_NOT_EXIST)) {
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.IGNORE);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_WAIT);
|
||||
}
|
||||
}
|
||||
catch (AlipayApiException e) {
|
||||
log.error("查询订单失败:", e);
|
||||
syncResult.setMsg(e.getErrMsg());
|
||||
syncResult.setErrorMsg(e.getErrMsg());
|
||||
}
|
||||
return syncResult;
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@DbTable(comment = "现金支付记录")
|
||||
@TableName("pay_cash_payment")
|
||||
@TableName("pay_cash_pay_order")
|
||||
@Accessors(chain = true)
|
||||
public class CashPayOrder extends BasePayOrder {
|
||||
|
||||
|
@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
|
||||
@Data
|
||||
@DbTable(comment = "云闪付支付订单")
|
||||
@Accessors(chain = true)
|
||||
@TableName("pay_union_payment")
|
||||
@TableName("pay_union_pay_order")
|
||||
public class UnionPayOrder extends BasePayOrder {
|
||||
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@ import lombok.experimental.Accessors;
|
||||
@Data
|
||||
@DbTable(comment = "储值卡支付记录")
|
||||
@Accessors(chain = true)
|
||||
@TableName(value = "pay_voucher_payment",autoResultMap = true)
|
||||
@TableName(value = "pay_voucher_pay_order",autoResultMap = true)
|
||||
public class VoucherPayOrder extends BasePayOrder implements EntityBaseFunction<VoucherPayOrderDto> {
|
||||
|
||||
/** 扣款储值卡 */
|
||||
|
@@ -1,14 +1,16 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.wechat.service;
|
||||
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
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.service.code.WeChatPayCode;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.dao.CallbackRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.dao.PayCallbackRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.callback.service.PayCallbackService;
|
||||
import cn.bootx.platform.daxpay.service.func.AbsPayCallbackStrategy;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.ijpay.core.enums.SignType;
|
||||
@@ -16,11 +18,13 @@ import com.ijpay.core.kit.WxPayKit;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.bootx.platform.daxpay.service.code.WeChatPayCode.APPID;
|
||||
import static cn.bootx.platform.daxpay.service.code.WeChatPayCode.TIME_END;
|
||||
|
||||
|
||||
/**
|
||||
@@ -34,7 +38,7 @@ import static cn.bootx.platform.daxpay.service.code.WeChatPayCode.APPID;
|
||||
public class WeChatPayCallbackService extends AbsPayCallbackStrategy {
|
||||
private final WeChatPayConfigService weChatPayConfigService;
|
||||
|
||||
public WeChatPayCallbackService(RedisClient redisClient, CallbackRecordManager callbackRecordManager,
|
||||
public WeChatPayCallbackService(RedisClient redisClient, PayCallbackRecordManager callbackRecordManager,
|
||||
PayCallbackService payCallbackService, WeChatPayConfigService weChatPayConfigService) {
|
||||
super(redisClient, callbackRecordManager, payCallbackService);
|
||||
this.weChatPayConfigService = weChatPayConfigService;
|
||||
@@ -101,7 +105,16 @@ public class WeChatPayCallbackService extends AbsPayCallbackStrategy {
|
||||
@Override
|
||||
public void initContext() {
|
||||
Map<String, String> callbackParam = PaymentContextLocal.get().getCallbackParam();
|
||||
// 订单号
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setTradeNo(callbackParam.get(WeChatPayCode.TRANSACTION_ID));
|
||||
// 支付时间
|
||||
String timeEnd = callbackParam.get(TIME_END);
|
||||
if (StrUtil.isNotBlank(timeEnd)) {
|
||||
LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.PURE_DATETIME_PATTERN);
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setPayTime(time);
|
||||
} else {
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setPayTime(LocalDateTime.now());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,9 +1,12 @@
|
||||
package cn.bootx.platform.daxpay.service.core.channel.wechat.service;
|
||||
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.WeChatPayCode;
|
||||
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.payment.sync.result.GatewaySyncResult;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.ijpay.core.enums.SignType;
|
||||
import com.ijpay.core.kit.WxPayKit;
|
||||
@@ -13,6 +16,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -42,7 +46,7 @@ public class WeChatPaySyncService {
|
||||
try {
|
||||
String xmlResult = WxPayApi.orderQuery(params);
|
||||
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
|
||||
syncResult.setJson(JSONUtil.toJsonStr(result));
|
||||
syncResult.setSyncInfo(JSONUtil.toJsonStr(result));
|
||||
// 查询失败
|
||||
if (!WxPayKit.codeIsOk(result.get(WeChatPayCode.RETURN_CODE))) {
|
||||
log.warn("查询微信订单失败:{}", result);
|
||||
@@ -56,8 +60,10 @@ public class WeChatPaySyncService {
|
||||
}
|
||||
String tradeStatus = result.get(WeChatPayCode.TRADE_STATE);
|
||||
// 支付完成
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_SUCCESS)
|
||||
|| Objects.equals(tradeStatus, WeChatPayCode.TRADE_ACCEPT)) {
|
||||
if (Objects.equals(tradeStatus, WeChatPayCode.TRADE_SUCCESS) || Objects.equals(tradeStatus, WeChatPayCode.TRADE_ACCEPT)) {
|
||||
String timeEnd = result.get(WeChatPayCode.TIME_END);
|
||||
LocalDateTime time = LocalDateTimeUtil.parse(timeEnd, DatePattern.PURE_DATETIME_PATTERN);
|
||||
PaymentContextLocal.get().getAsyncPayInfo().setPayTime(time);
|
||||
return syncResult.setSyncStatus(PaySyncStatusEnum.PAY_SUCCESS);
|
||||
}
|
||||
// 待支付
|
||||
@@ -79,7 +85,7 @@ public class WeChatPaySyncService {
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
log.error("查询订单失败:", e);
|
||||
syncResult.setMsg(e.getMessage());
|
||||
syncResult.setErrorMsg(e.getMessage());
|
||||
}
|
||||
return syncResult;
|
||||
}
|
||||
|
@@ -1,14 +1,17 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.close.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.common.entity.OrderRefundableInfo;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.close.factory.PayCloseStrategyFactory;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayUnsupportedMethodException;
|
||||
import cn.bootx.platform.daxpay.service.func.AbsPayCloseStrategy;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayCloseParam;
|
||||
import cn.bootx.platform.daxpay.service.common.entity.OrderRefundableInfo;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.close.factory.PayCloseStrategyFactory;
|
||||
import cn.bootx.platform.daxpay.service.core.record.close.entity.PayCloseRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.record.close.service.PayCloseRecordService;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.service.func.AbsPayCloseStrategy;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -29,6 +32,7 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class PayCloseService {
|
||||
private final PayOrderService payOrderService;
|
||||
private final PayCloseRecordService payCloseRecordService;
|
||||
|
||||
/**
|
||||
* 关闭支付
|
||||
@@ -48,7 +52,7 @@ public class PayCloseService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消支付记录
|
||||
* 关闭支付记录
|
||||
*/
|
||||
private void close(PayOrder payOrder) {
|
||||
// 状态检查, 只有支付中可以进行取消支付
|
||||
@@ -76,8 +80,9 @@ public class PayCloseService {
|
||||
// 4.执行关闭策略
|
||||
payCloseStrategies.forEach(AbsPayCloseStrategy::doCloseHandler);
|
||||
}
|
||||
catch (Exception e) {
|
||||
// TODO 记录关闭失败的记录
|
||||
catch (PayFailureException e) {
|
||||
// 记录关闭失败的记录
|
||||
this.saveRecord(payOrder,false,e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -92,5 +97,27 @@ public class PayCloseService {
|
||||
// 取消订单
|
||||
payOrder.setStatus(PayStatusEnum.CLOSE.getCode());
|
||||
payOrderService.updateById(payOrder);
|
||||
this.saveRecord(payOrder,true,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存关闭记录
|
||||
*/
|
||||
private void saveRecord(PayOrder payOrder, boolean closed, String errMsg){
|
||||
String clientIp = PaymentContextLocal.get()
|
||||
.getRequest()
|
||||
.getClientIp();
|
||||
String reqId = PaymentContextLocal.get()
|
||||
.getRequest()
|
||||
.getReqId();
|
||||
PayCloseRecord record = new PayCloseRecord()
|
||||
.setPaymentId(payOrder.getId())
|
||||
.setAsyncChannel(payOrder.getAsyncChannel())
|
||||
.setClosed(closed)
|
||||
.setErrorMsg(errMsg)
|
||||
.setClientIp(clientIp)
|
||||
.setReqId(reqId);
|
||||
payCloseRecordService.saveRecord(record);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -52,7 +52,7 @@ public class PaymentAssistService {
|
||||
private void initRequest(PayCommonParam payCommonParam){
|
||||
RequestLocal request = PaymentContextLocal.get().getRequest();
|
||||
request.setClientIp(payCommonParam.getClientIp())
|
||||
.setExtraParam(payCommonParam.getExtraParam())
|
||||
.setAttach(payCommonParam.getAttach())
|
||||
.setSign(payCommonParam.getSign())
|
||||
.setVersion(payCommonParam.getVersion())
|
||||
.setReqTime(payCommonParam.getReqTime())
|
||||
|
@@ -4,10 +4,14 @@ import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
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.PayWayParam;
|
||||
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.payment.sync.service.PaySyncService;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.builder.PaymentBuilder;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.dao.PayOrderChannelManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.dao.PayOrderExtraManager;
|
||||
@@ -15,9 +19,6 @@ import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrderChannel;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrderExtra;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayWayParam;
|
||||
import cn.bootx.platform.daxpay.service.util.PayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -40,6 +41,8 @@ import java.util.stream.Collectors;
|
||||
@RequiredArgsConstructor
|
||||
public class PayAssistService {
|
||||
|
||||
private final PaySyncService paySyncService;
|
||||
|
||||
private final PayOrderService payOrderService;
|
||||
private final PayOrderExtraManager payOrderExtraManager;
|
||||
private final PayOrderChannelManager payOrderChannelManager;
|
||||
@@ -167,9 +170,22 @@ public class PayAssistService {
|
||||
// 根据订单查询支付记录
|
||||
PayOrder payOrder = payOrderService.findByBusinessNo(businessNo).orElse(null);
|
||||
if (Objects.nonNull(payOrder)) {
|
||||
// 待支付
|
||||
if (Objects.equals(payOrder.getStatus(), PayStatusEnum.PROGRESS.getCode())){
|
||||
// 如果支付超时, 触发订单同步操作, 同时抛出异常
|
||||
if (Objects.nonNull(payOrder.getExpiredTime()) && LocalDateTimeUtil.ge(LocalDateTime.now(), payOrder.getExpiredTime())) {
|
||||
paySyncService.syncPayOrder(payOrder);
|
||||
throw new PayFailureException("支付已超时,请重新确认支付状态");
|
||||
}
|
||||
return payOrder;
|
||||
}
|
||||
// 已经支付状态
|
||||
if (PayStatusEnum.SUCCESS.getCode().equals(payOrder.getStatus())) {
|
||||
throw new PayFailureException("已经支付成功,请勿重新支付");
|
||||
}
|
||||
// 支付失败类型状态
|
||||
List<String> tradesStatus = Arrays.asList(PayStatusEnum.FAIL.getCode(), PayStatusEnum.CANCEL.getCode(),
|
||||
PayStatusEnum.CLOSE.getCode());
|
||||
PayStatusEnum.CLOSE.getCode(), PayStatusEnum.TIMEOUT.getCode());
|
||||
if (tradesStatus.contains(payOrder.getStatus())) {
|
||||
throw new PayFailureException("支付失败或已经被关闭");
|
||||
}
|
||||
@@ -178,13 +194,10 @@ public class PayAssistService {
|
||||
if (tradesStatus.contains(payOrder.getStatus())) {
|
||||
throw new PayFailureException("退款中");
|
||||
}
|
||||
// 支付超时状态
|
||||
if (Objects.nonNull(payOrder.getExpiredTime())
|
||||
&& LocalDateTimeUtil.ge(LocalDateTime.now(), payOrder.getExpiredTime())) {
|
||||
throw new PayFailureException("支付已超时");
|
||||
// 其他状态直接抛出兜底异常
|
||||
throw new PayFailureException("订单不是待支付状态,请重新确认订单状态");
|
||||
}
|
||||
}
|
||||
return payOrder;
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -55,7 +55,7 @@ public class PayService {
|
||||
// 异步支付方式检查
|
||||
PayUtil.validationAsyncPay(payParam);
|
||||
|
||||
// 获取并校验支付订单状态
|
||||
// 获取并校验支付订单状态, 如果超时, 触发支付单同步和修复动作
|
||||
PayOrder payOrder = payAssistService.getOrderAndCheck(payParam.getBusinessNo());
|
||||
|
||||
// 初始化上下文
|
||||
|
@@ -108,7 +108,7 @@ public class PayRefundAssistService {
|
||||
* 保存退款记录 成不成功都记录
|
||||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void saveRefundOrder(RefundParam refundParam, PayOrder payOrder){
|
||||
public void saveOrder(RefundParam refundParam, PayOrder payOrder){
|
||||
AsyncRefundLocal asyncRefundInfo = PaymentContextLocal.get().getAsyncRefundInfo();
|
||||
// 退款金额
|
||||
Integer amount = refundParam.getRefundChannels()
|
||||
@@ -119,15 +119,15 @@ public class PayRefundAssistService {
|
||||
PayRefundOrder refundOrder = new PayRefundOrder()
|
||||
.setRefundRequestNo(asyncRefundInfo.getRefundNo())
|
||||
.setAmount(amount)
|
||||
.setClientIp(refundParam.getClientIp())
|
||||
.setPaymentId(payOrder.getId())
|
||||
.setBusinessNo(payOrder.getBusinessNo())
|
||||
.setRefundTime(LocalDateTime.now())
|
||||
.setTitle(payOrder.getTitle())
|
||||
.setErrorMsg(asyncRefundInfo.getErrorMsg())
|
||||
.setErrorCode(asyncRefundInfo.getErrorCode())
|
||||
.setStatus(Objects.isNull(asyncRefundInfo.getErrorCode()) ? PayRefundStatusEnum.SUCCESS.getCode()
|
||||
: PayRefundStatusEnum.FAIL.getCode());
|
||||
.setStatus(Objects.isNull(asyncRefundInfo.getErrorCode()) ? PayRefundStatusEnum.SUCCESS.getCode() : PayRefundStatusEnum.FAIL.getCode())
|
||||
.setClientIp(refundParam.getClientIp())
|
||||
.setReqId(PaymentContextLocal.get().getRequest().getReqId());
|
||||
payRefundOrderManager.save(refundOrder);
|
||||
}
|
||||
}
|
||||
|
@@ -107,7 +107,7 @@ public class PayRefundService {
|
||||
}
|
||||
catch (Exception e) {
|
||||
// 记录退款失败的记录
|
||||
payRefundAssistService.saveRefundOrder(refundParam,payOrder);
|
||||
payRefundAssistService.saveOrder(refundParam,payOrder);
|
||||
throw e;
|
||||
}
|
||||
|
||||
@@ -137,6 +137,6 @@ public class PayRefundService {
|
||||
}
|
||||
payOrder.setRefundableBalance(refundableBalance);
|
||||
payOrderService.updateById(payOrder);
|
||||
payRefundAssistService.saveRefundOrder(refundParam,payOrder);
|
||||
payRefundAssistService.saveOrder(refundParam,payOrder);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,19 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.repair.result;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 修复结果
|
||||
* @author xxm
|
||||
* @since 2024/1/4
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class RepairResult {
|
||||
/** 修复前状态 */
|
||||
private PayStatusEnum oldStatus;
|
||||
/** 修复后状态 */
|
||||
private PayStatusEnum repairStatus;
|
||||
}
|
@@ -2,8 +2,10 @@ package cn.bootx.platform.daxpay.service.core.payment.repair.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.common.entity.OrderRefundableInfo;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.repair.factory.PayRepairStrategyFactory;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.repair.param.PayRepairParam;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.repair.result.RepairResult;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.service.func.AbsPayRepairStrategy;
|
||||
@@ -32,7 +34,7 @@ public class PayRepairService {
|
||||
* 修复支付单
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class )
|
||||
public void repair(PayOrder order, PayRepairParam repairParam){
|
||||
public RepairResult repair(PayOrder order, PayRepairParam repairParam){
|
||||
// 从退款记录中获取支付通道 退款记录中的支付通道跟支付时关联的支付通道一致
|
||||
List<String> channels = order.getRefundableInfos()
|
||||
.stream()
|
||||
@@ -41,16 +43,20 @@ public class PayRepairService {
|
||||
// 初始化修复参数
|
||||
List<AbsPayRepairStrategy> repairStrategies = PayRepairStrategyFactory.createAsyncLast(channels);
|
||||
repairStrategies.forEach(repairStrategy -> repairStrategy.initRepairParam(order, repairParam.getRepairSource()));
|
||||
RepairResult repairResult = new RepairResult().setOldStatus(PayStatusEnum.findByCode(order.getStatus()));
|
||||
// 根据不同的类型执行对应的修复逻辑
|
||||
switch (repairParam.getRepairType()) {
|
||||
case SUCCESS:
|
||||
this.success(order, repairStrategies);
|
||||
repairResult.setRepairStatus(PayStatusEnum.SUCCESS);
|
||||
break;
|
||||
case CLOSE:
|
||||
this.close(order, repairStrategies);
|
||||
repairResult.setRepairStatus(PayStatusEnum.CLOSE);
|
||||
break;
|
||||
case TIMEOUT:
|
||||
this.timeout(order, repairStrategies);
|
||||
repairResult.setRepairStatus(PayStatusEnum.TIMEOUT);
|
||||
break;
|
||||
case REFUND:
|
||||
this.refund(order, repairStrategies);
|
||||
@@ -58,6 +64,7 @@ public class PayRepairService {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return repairResult;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,6 +73,9 @@ public class PayRepairService {
|
||||
* 回调: 将异步支付状态修改为成功
|
||||
*/
|
||||
private void success(PayOrder payment, List<AbsPayRepairStrategy> strategies) {
|
||||
LocalDateTime payTime = PaymentContextLocal.get()
|
||||
.getAsyncPayInfo()
|
||||
.getPayTime();
|
||||
|
||||
// 执行个通道的成功处理方法
|
||||
strategies.forEach(AbsPayRepairStrategy::doSuccessHandler);
|
||||
@@ -73,7 +83,7 @@ public class PayRepairService {
|
||||
// 修改订单支付状态为成功
|
||||
payment.setStatus(PayStatusEnum.SUCCESS.getCode());
|
||||
// TODO 读取支付网关中的时间
|
||||
payment.setPayTime(LocalDateTime.now());
|
||||
payment.setPayTime(payTime);
|
||||
payOrderService.updateById(payment);
|
||||
}
|
||||
|
||||
|
@@ -4,10 +4,10 @@ import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.NOT_SYNC;
|
||||
import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.FAIL;
|
||||
|
||||
/**
|
||||
* 支付网关同步状态记录对象
|
||||
* 支付网关同步结果
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2021/4/21
|
||||
@@ -17,15 +17,15 @@ import static cn.bootx.platform.daxpay.code.PaySyncStatusEnum.NOT_SYNC;
|
||||
public class GatewaySyncResult {
|
||||
|
||||
/**
|
||||
* 支付网关同步状态
|
||||
* @see PaySyncStatusEnum#NOT_SYNC
|
||||
* 支付网关订单状态
|
||||
* @see PaySyncStatusEnum
|
||||
*/
|
||||
private PaySyncStatusEnum syncStatus = NOT_SYNC;
|
||||
private PaySyncStatusEnum syncStatus = FAIL;
|
||||
|
||||
/** 网关返回对象的json字符串 */
|
||||
private String json;
|
||||
/** 网关返回的对象, 序列化为json字符串 */
|
||||
private String syncInfo;
|
||||
|
||||
/** 错误提示 */
|
||||
private String msg;
|
||||
private String errorMsg;
|
||||
|
||||
}
|
||||
|
@@ -9,20 +9,24 @@ import cn.bootx.platform.daxpay.param.pay.PaySyncParam;
|
||||
import cn.bootx.platform.daxpay.result.pay.PaySyncResult;
|
||||
import cn.bootx.platform.daxpay.service.code.PayRepairSourceEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.PayRepairTypeEnum;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.repair.param.PayRepairParam;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.repair.service.PayRepairService;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.factory.PaySyncStrategyFactory;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.result.GatewaySyncResult;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.service.core.record.sync.service.PaySyncOrderService;
|
||||
import cn.bootx.platform.daxpay.service.core.record.sync.entity.PaySyncRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.record.sync.service.PaySyncRecordService;
|
||||
import cn.bootx.platform.daxpay.service.func.AbsPaySyncStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -37,13 +41,14 @@ import java.util.Objects;
|
||||
public class PaySyncService {
|
||||
private final PayOrderService payOrderService;
|
||||
|
||||
private final PaySyncOrderService syncOrderService;
|
||||
private final PaySyncRecordService paySyncRecordService;
|
||||
|
||||
private final PayRepairService repairService;
|
||||
|
||||
/**
|
||||
* 支付同步
|
||||
* 支付同步, 开启一个新的事务, 不受外部抛出异常的影响
|
||||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public PaySyncResult sync(PaySyncParam param) {
|
||||
PayOrder payOrder = null;
|
||||
if (Objects.nonNull(param.getPaymentId())){
|
||||
@@ -62,28 +67,49 @@ public class PaySyncService {
|
||||
return this.syncPayOrder(payOrder);
|
||||
}
|
||||
/**
|
||||
* 同步支付状态
|
||||
* 同步支付状态, 开启一个新的事务, 不受外部抛出异常的影响
|
||||
* 1. 如果状态一致, 不进行处理
|
||||
* 2. 如果状态不一致, 调用修复逻辑进行修复
|
||||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public PaySyncResult syncPayOrder(PayOrder order) {
|
||||
// 获取同步策略类
|
||||
AbsPaySyncStrategy syncPayStrategy = PaySyncStrategyFactory.create(order.getAsyncChannel());
|
||||
syncPayStrategy.initPayParam(order);
|
||||
// 获取网关支付状态
|
||||
// 记录支付单同步前后的状态
|
||||
String oldStatus = order.getStatus();
|
||||
String repairStatus = null;
|
||||
|
||||
// 执行同步操作, 获取支付网关同步的结果
|
||||
GatewaySyncResult syncResult = syncPayStrategy.doSyncStatus();
|
||||
// 判断是否同步成功
|
||||
if (Objects.equals(syncResult.getSyncStatus(), PaySyncStatusEnum.FAIL)){
|
||||
// 同步失败, 返回失败响应, 同时记录失败的日志
|
||||
this.saveRecord(order, syncResult, true, oldStatus, null, syncResult.getErrorMsg());
|
||||
return new PaySyncResult().setErrorMsg(syncResult.getErrorMsg());
|
||||
}
|
||||
|
||||
// 判断网关状态是否和支付单一致, 同时更新网关同步状态
|
||||
boolean statusSync = this.checkStatusSync(syncResult,order);
|
||||
try {
|
||||
// 状态不一致,执行支付单修复逻辑
|
||||
if (!statusSync){
|
||||
// 根据同步记录对支付单进行处理处理
|
||||
this.resultHandler(syncResult, order);
|
||||
repairStatus = order.getStatus();
|
||||
}
|
||||
// 记录同步的结果
|
||||
syncOrderService.saveRecord(syncResult,order);
|
||||
} catch (Exception e) {
|
||||
// 同步失败, 返回失败响应, 同时记录失败的日志 TODO 后面异常范围能这么宽泛
|
||||
syncResult.setSyncStatus(PaySyncStatusEnum.FAIL);
|
||||
this.saveRecord(order, syncResult, false, oldStatus, null, e.getMessage());
|
||||
return new PaySyncResult().setErrorMsg(e.getMessage());
|
||||
}
|
||||
|
||||
// 同步成功记录日志
|
||||
this.saveRecord( order, syncResult, !statusSync, oldStatus, repairStatus, null);
|
||||
return new PaySyncResult()
|
||||
.setSuccess(true)
|
||||
.setRepair(!statusSync)
|
||||
.setRepairStatus(repairStatus)
|
||||
.setSyncStatus(syncResult.getSyncStatus().getCode());
|
||||
}
|
||||
|
||||
@@ -97,9 +123,8 @@ public class PaySyncService {
|
||||
if (orderStatus.equals(PayStatusEnum.SUCCESS.getCode()) && syncStatus.equals(PaySyncStatusEnum.PAY_SUCCESS)){
|
||||
return true;
|
||||
}
|
||||
|
||||
// 待支付比对 网关忽略和支付中都代表待支付, 需要处理订单超时的情况
|
||||
List<PaySyncStatusEnum> enums = Arrays.asList(PaySyncStatusEnum.PAY_WAIT, PaySyncStatusEnum.IGNORE);
|
||||
// 待支付比对 支付中都代表待支付, 需要处理订单超时的情况
|
||||
List<PaySyncStatusEnum> enums = Collections.singletonList(PaySyncStatusEnum.PAY_WAIT);
|
||||
if (orderStatus.equals(PayStatusEnum.PROGRESS.getCode()) && enums.contains(syncStatus)){
|
||||
// 判断支付单是否支付超时, 如果待支付状态下触发超时
|
||||
if (LocalDateTimeUtil.le(order.getExpiredTime(), LocalDateTime.now())){
|
||||
@@ -153,9 +178,6 @@ public class PaySyncService {
|
||||
repairService.repair(payOrder, repairParam);
|
||||
break;
|
||||
}
|
||||
// 不需要进行处理
|
||||
case IGNORE:
|
||||
break;
|
||||
// 调用出错
|
||||
case TIMEOUT:
|
||||
repairParam.setRepairType(PayRepairTypeEnum.TIMEOUT);
|
||||
@@ -166,10 +188,34 @@ public class PaySyncService {
|
||||
log.warn("支付状态同步接口调用出错");
|
||||
break;
|
||||
}
|
||||
case NOT_SYNC:
|
||||
default: {
|
||||
throw new BizException("代码有问题");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存同步记录
|
||||
* @param payOrder 支付单
|
||||
* @param syncResult 同步结果
|
||||
* @param repair 是否修复
|
||||
* @param oldStatus 修复前的状态
|
||||
* @param repairStatus 修复后的状态
|
||||
* @param errorMsg 错误信息
|
||||
*/
|
||||
private void saveRecord(PayOrder payOrder,GatewaySyncResult syncResult, boolean repair, String oldStatus, String repairStatus, String errorMsg){
|
||||
PaySyncRecord paySyncRecord = new PaySyncRecord()
|
||||
.setPaymentId(payOrder.getId())
|
||||
.setChannel(payOrder.getAsyncChannel())
|
||||
.setSyncInfo(syncResult.getSyncInfo())
|
||||
.setSyncStatus(syncResult.getSyncStatus().getCode())
|
||||
.setRepairOrder(repair)
|
||||
.setOldStatus(oldStatus)
|
||||
.setRepairStatus(repairStatus)
|
||||
.setErrorMsg(errorMsg)
|
||||
.setClientIp(PaymentContextLocal.get().getRequest().getClientIp())
|
||||
.setReqId(PaymentContextLocal.get().getRequest().getReqId());
|
||||
paySyncRecordService.saveRecord(paySyncRecord);
|
||||
}
|
||||
}
|
||||
|
@@ -1,14 +0,0 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.callback.convert;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 回调通知转换
|
||||
* @author xxm
|
||||
* @since 2023/12/18
|
||||
*/
|
||||
@Mapper
|
||||
public interface CallbackRecordMConvert {
|
||||
CallbackRecordMConvert CONVERT = Mappers.getMapper(CallbackRecordMConvert.class);
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.callback.convert;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.entity.PayCallbackRecord;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.callback.PayCallbackRecordDto;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* 回调通知转换
|
||||
* @author xxm
|
||||
* @since 2023/12/18
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayCallbackRecordConvert {
|
||||
PayCallbackRecordConvert CONVERT = Mappers.getMapper(PayCallbackRecordConvert.class);
|
||||
|
||||
PayCallbackRecordDto convert(PayCallbackRecord in);
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.callback.dao;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.entity.CallbackRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.entity.PayCallbackRecord;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@@ -12,5 +12,5 @@ import org.springframework.stereotype.Repository;
|
||||
*/
|
||||
@Slf4j
|
||||
@Repository
|
||||
public class CallbackRecordManager extends BaseManager<CallbackRecordMapper, CallbackRecord> {
|
||||
public class PayCallbackRecordManager extends BaseManager<PayCallbackRecordMapper, PayCallbackRecord> {
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.callback.dao;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.entity.CallbackRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.entity.PayCallbackRecord;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@@ -10,5 +10,5 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
* @since 2023/12/18
|
||||
*/
|
||||
@Mapper
|
||||
public interface CallbackRecordMapper extends BaseMapper<CallbackRecord> {
|
||||
public interface PayCallbackRecordMapper extends BaseMapper<PayCallbackRecord> {
|
||||
}
|
@@ -1,11 +1,16 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.callback.entity;
|
||||
|
||||
import cn.bootx.platform.common.core.function.EntityBaseFunction;
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.convert.PayCallbackRecordConvert;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.callback.PayCallbackRecordDto;
|
||||
import cn.bootx.table.modify.annotation.DbComment;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import cn.bootx.table.modify.mysql.annotation.DbMySqlFieldType;
|
||||
import cn.bootx.table.modify.mysql.constants.MySqlFieldTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
@@ -20,7 +25,9 @@ import java.time.LocalDateTime;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CallbackRecord extends MpCreateEntity {
|
||||
@DbTable(comment = "网关回调通知")
|
||||
@TableName("pay_callback_record")
|
||||
public class PayCallbackRecord extends MpCreateEntity implements EntityBaseFunction<PayCallbackRecordDto> {
|
||||
/** 支付记录id */
|
||||
@DbComment("支付记录id")
|
||||
private Long paymentId;
|
||||
@@ -46,7 +53,6 @@ public class CallbackRecord extends MpCreateEntity {
|
||||
|
||||
/**
|
||||
* 回调处理状态
|
||||
* @see
|
||||
*/
|
||||
@DbComment("回调处理状态")
|
||||
private String status;
|
||||
@@ -58,4 +64,12 @@ public class CallbackRecord extends MpCreateEntity {
|
||||
/** 回调时间 */
|
||||
@DbComment("回调时间")
|
||||
private LocalDateTime notifyTime;
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*/
|
||||
@Override
|
||||
public PayCallbackRecordDto toDto() {
|
||||
return PayCallbackRecordConvert.CONVERT.convert(this);
|
||||
}
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.callback.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 接收到的支付回调通知
|
||||
* @author xxm
|
||||
* @since 2023/12/18
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class CallbackRecordService {
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.callback.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.dao.PayCallbackRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.entity.PayCallbackRecord;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.callback.PayCallbackRecordDto;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 接收到的支付回调通知
|
||||
* @author xxm
|
||||
* @since 2023/12/18
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PayCallbackRecordService {
|
||||
|
||||
private final PayCallbackRecordManager callbackRecordManager;
|
||||
|
||||
/**
|
||||
* 根据id查询
|
||||
*/
|
||||
public PayCallbackRecordDto findById(Long id) {
|
||||
return callbackRecordManager.findById(id).map(PayCallbackRecord::toDto).orElseThrow(DataNotExistException::new);
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.close.convert;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.record.close.entity.PayCloseRecord;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.close.PayCloseRecordDto;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/1/4
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayCloseRecordConvert {
|
||||
PayCloseRecordConvert CONVERT = Mappers.getMapper(PayCloseRecordConvert.class);
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*/
|
||||
PayCloseRecordDto convert(PayCloseRecord in);
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.close.dao;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.close.entity.PayCloseRecord;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/1/4
|
||||
*/
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class PayCloseRecordManager extends BaseManager<PayCloseRecordMapper, PayCloseRecord> {
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.close.dao;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.record.close.entity.PayCloseRecord;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/1/4
|
||||
*/
|
||||
@Mapper
|
||||
public interface PayCloseRecordMapper extends BaseMapper<PayCloseRecord> {
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.close.entity;
|
||||
|
||||
import cn.bootx.platform.common.core.function.EntityBaseFunction;
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.service.core.record.close.convert.PayCloseRecordConvert;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.close.PayCloseRecordDto;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
import cn.bootx.table.modify.annotation.DbComment;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付关闭记录
|
||||
* @author xxm
|
||||
* @since 2024/1/4
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@DbTable(comment = "支付关闭记录")
|
||||
@TableName("pay_close_record")
|
||||
public class PayCloseRecord extends MpCreateEntity implements EntityBaseFunction<PayCloseRecordDto> {
|
||||
|
||||
/** 支付记录id */
|
||||
@DbComment("支付记录id")
|
||||
private Long paymentId;
|
||||
|
||||
/**
|
||||
* 关闭的异步支付通道, 可以为空
|
||||
* @see PayChannelEnum#getCode()
|
||||
*/
|
||||
@DbComment("关闭的异步支付通道")
|
||||
private String asyncChannel;
|
||||
|
||||
/**
|
||||
* 是否关闭成功
|
||||
*/
|
||||
@DbComment("是否关闭成功")
|
||||
private boolean closed;
|
||||
|
||||
@DbComment("错误消息")
|
||||
private String errorMsg;
|
||||
|
||||
/** 客户端IP */
|
||||
@DbColumn(comment = "客户端IP")
|
||||
private String clientIp;
|
||||
|
||||
/** 请求链路ID */
|
||||
@DbColumn(comment = "请求链路ID")
|
||||
private String reqId;
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*/
|
||||
@Override
|
||||
public PayCloseRecordDto toDto() {
|
||||
return PayCloseRecordConvert.CONVERT.convert(this);
|
||||
}
|
||||
}
|
@@ -0,0 +1,26 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.close.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.record.close.dao.PayCloseRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.close.entity.PayCloseRecord;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 支付关闭记录
|
||||
* @author xxm
|
||||
* @since 2024/1/4
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PayCloseRecordService {
|
||||
private final PayCloseRecordManager manager;
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void saveRecord(PayCloseRecord record){
|
||||
manager.save(record);
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.refund.convert;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.record.refund.entity.PayRefundOrder;
|
||||
import cn.bootx.platform.daxpay.service.dto.order.refund.PayRefundOrderDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.refund.PayRefundOrderDto;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.daxpay.service.core.record.refund.entity.PayRefundOrder;
|
||||
import cn.bootx.platform.daxpay.service.dto.order.refund.PayRefundOrderDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.refund.PayRefundOrderDto;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@@ -6,7 +6,9 @@ import cn.bootx.platform.daxpay.code.PayRefundStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.common.entity.OrderRefundableInfo;
|
||||
import cn.bootx.platform.daxpay.service.common.typehandler.RefundableInfoTypeHandler;
|
||||
import cn.bootx.platform.daxpay.service.core.record.refund.convert.RefundConvert;
|
||||
import cn.bootx.platform.daxpay.service.dto.order.refund.PayRefundOrderDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.refund.PayRefundOrderDto;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import cn.bootx.table.modify.mysql.annotation.DbMySqlFieldType;
|
||||
import cn.bootx.table.modify.mysql.constants.MySqlFieldTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
@@ -27,39 +29,54 @@ import java.util.List;
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@DbTable(comment = "退款订单")
|
||||
@TableName(value = "pay_refund_order", autoResultMap = true)
|
||||
public class PayRefundOrder extends MpBaseEntity implements EntityBaseFunction<PayRefundOrderDto> {
|
||||
|
||||
/** 支付单号 */
|
||||
@DbColumn(comment = "关联的业务号")
|
||||
private Long paymentId;
|
||||
|
||||
/** 关联的业务号 */
|
||||
@DbColumn(comment = "关联的业务号")
|
||||
private String businessNo;
|
||||
|
||||
/** 异步方式关联退款请求号(部分退款情况) */
|
||||
@DbColumn(comment = "异步方式关联退款请求号(部分退款情况)")
|
||||
private String refundRequestNo;
|
||||
|
||||
/** 标题 */
|
||||
@DbColumn(comment = "标题")
|
||||
private String title;
|
||||
|
||||
/** 退款金额 */
|
||||
@DbColumn(comment = "退款金额")
|
||||
private Integer amount;
|
||||
|
||||
/** 剩余可退 */
|
||||
@DbColumn(comment = "剩余可退")
|
||||
private Integer refundableBalance;
|
||||
|
||||
/** 请求链路ID */
|
||||
@DbColumn(comment = "请求链路ID")
|
||||
private String reqId;
|
||||
|
||||
/** 退款终端ip */
|
||||
@DbColumn(comment = "退款终端ip")
|
||||
private String clientIp;
|
||||
|
||||
/** 退款原因 */
|
||||
@DbColumn(comment = "退款原因")
|
||||
private String reason;
|
||||
|
||||
/** 退款时间 */
|
||||
@DbColumn(comment = "退款时间")
|
||||
private LocalDateTime refundTime;
|
||||
|
||||
/**
|
||||
* 退款信息列表
|
||||
*/
|
||||
@DbColumn(comment = "退款信息列表")
|
||||
@TableField(typeHandler = RefundableInfoTypeHandler.class)
|
||||
@DbMySqlFieldType(MySqlFieldTypeEnum.LONGTEXT)
|
||||
private List<OrderRefundableInfo> refundableInfo;
|
||||
@@ -68,12 +85,15 @@ public class PayRefundOrder extends MpBaseEntity implements EntityBaseFunction<P
|
||||
* 退款状态
|
||||
* @see PayRefundStatusEnum
|
||||
*/
|
||||
@DbColumn(comment = "退款状态")
|
||||
private String status;
|
||||
|
||||
/** 错误码 */
|
||||
@DbColumn(comment = "错误码")
|
||||
private String errorCode;
|
||||
|
||||
/** 错误信息 */
|
||||
@DbColumn(comment = "错误信息")
|
||||
private String errorMsg;
|
||||
|
||||
@Override
|
||||
|
@@ -6,7 +6,7 @@ import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.daxpay.service.core.record.refund.dao.PayRefundOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.refund.entity.PayRefundOrder;
|
||||
import cn.bootx.platform.daxpay.service.dto.order.refund.PayRefundOrderDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.refund.PayRefundOrderDto;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -25,6 +25,10 @@ public class PayRefundRecordService {
|
||||
|
||||
private final PayRefundOrderManager refundRecordManager;
|
||||
|
||||
// TODO 记录退款记录
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*/
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package cn.bootx.platform.daxpay.service.core.record.sync.convert;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.record.sync.entity.PaySyncRecord;
|
||||
import cn.bootx.platform.daxpay.service.dto.order.sync.PaySyncRecordDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.sync.PaySyncRecordDto;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import cn.bootx.platform.common.mybatisplus.base.MpIdEntity;
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.daxpay.service.core.record.sync.entity.PaySyncRecord;
|
||||
import cn.bootx.platform.daxpay.service.dto.order.sync.PaySyncRecordDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.sync.PaySyncRecordDto;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -28,7 +28,7 @@ public class PaySyncRecordManager extends BaseManager<PaySyncRecordMapper, PaySy
|
||||
return lambdaQuery().orderByDesc(MpIdEntity::getId)
|
||||
.like(Objects.nonNull(param.getPaymentId()), PaySyncRecord::getPaymentId, param.getPaymentId())
|
||||
.eq(Objects.nonNull(param.getChannel()), PaySyncRecord::getChannel, param.getChannel())
|
||||
.eq(Objects.nonNull(param.getStatus()), PaySyncRecord::getStatus, param.getStatus())
|
||||
.eq(Objects.nonNull(param.getStatus()), PaySyncRecord::getSyncStatus, param.getStatus())
|
||||
.page(mpPage);
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,8 @@ import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.platform.daxpay.service.core.record.sync.convert.PaySyncRecordConvert;
|
||||
import cn.bootx.platform.daxpay.service.dto.order.sync.PaySyncRecordDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.sync.PaySyncRecordDto;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
import cn.bootx.table.modify.annotation.DbComment;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import cn.bootx.table.modify.mysql.annotation.DbMySqlFieldType;
|
||||
@@ -15,8 +16,6 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付同步订单
|
||||
* @author xxm
|
||||
@@ -33,7 +32,6 @@ public class PaySyncRecord extends MpCreateEntity implements EntityBaseFunction<
|
||||
@DbComment("支付记录id")
|
||||
private Long paymentId;
|
||||
|
||||
|
||||
/**
|
||||
* 支付通道
|
||||
* @see PayChannelEnum#getCode()
|
||||
@@ -51,19 +49,32 @@ public class PaySyncRecord extends MpCreateEntity implements EntityBaseFunction<
|
||||
* @see PaySyncStatusEnum
|
||||
*/
|
||||
@DbComment("同步状态")
|
||||
private String status;
|
||||
private String syncStatus;
|
||||
|
||||
/**
|
||||
* 支付单如果状态不一致, 是否修复成功
|
||||
*/
|
||||
@DbComment("是否进行修复")
|
||||
private boolean repairOrder;
|
||||
|
||||
@DbComment("错误消息")
|
||||
private String msg;
|
||||
/** 支付单修复前状态 */
|
||||
@DbComment("支付单修复前状态")
|
||||
private String oldStatus;
|
||||
/** 支付单修复后状态 */
|
||||
|
||||
/** 同步时间 */
|
||||
@DbComment("同步时间")
|
||||
private LocalDateTime syncTime;
|
||||
@DbComment("支付单修复后状态")
|
||||
private String repairStatus;
|
||||
|
||||
@DbComment("错误消息")
|
||||
private String errorMsg;
|
||||
|
||||
/** 客户端IP */
|
||||
@DbColumn(comment = "客户端IP")
|
||||
private String clientIp;
|
||||
|
||||
/** 请求链路ID */
|
||||
@DbColumn(comment = "请求链路ID")
|
||||
private String reqId;
|
||||
|
||||
/**
|
||||
* 转换
|
||||
|
@@ -4,11 +4,9 @@ import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.bootx.platform.common.core.rest.PageResult;
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.daxpay.service.core.record.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.record.sync.dao.PaySyncRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.sync.entity.PaySyncRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.result.GatewaySyncResult;
|
||||
import cn.bootx.platform.daxpay.service.dto.order.sync.PaySyncRecordDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.sync.PaySyncRecordDto;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -16,8 +14,6 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 支付同步记录
|
||||
* @author xxm
|
||||
@@ -26,21 +22,14 @@ import java.time.LocalDateTime;
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PaySyncOrderService {
|
||||
public class PaySyncRecordService {
|
||||
private final PaySyncRecordManager orderManager;
|
||||
|
||||
/**
|
||||
* 记录同步记录
|
||||
* 记录同步记录 同步支付单的不进行记录
|
||||
*/
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
||||
public void saveRecord(GatewaySyncResult paySyncResult, PayOrder payment){
|
||||
PaySyncRecord paySyncRecord = new PaySyncRecord()
|
||||
.setPaymentId(payment.getId())
|
||||
.setChannel(payment.getAsyncChannel())
|
||||
.setSyncInfo(paySyncResult.getJson())
|
||||
.setStatus(paySyncResult.getSyncStatus().getCode())
|
||||
.setMsg(paySyncResult.getMsg())
|
||||
.setSyncTime(LocalDateTime.now());
|
||||
public void saveRecord(PaySyncRecord paySyncRecord){
|
||||
orderManager.save(paySyncRecord);
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.channel.alipay;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.pay.PayOrderDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.channel.voucher;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.pay.PayOrderDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.channel.wallet;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.pay.PayOrderDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.channel.wechat;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.dto.order.pay.PayOrderDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.pay.PayOrderDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
@@ -0,0 +1,19 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.record.callback;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付回调记录
|
||||
* @author xxm
|
||||
* @since 2024/1/4
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "回调记录")
|
||||
public class PayCallbackRecordDto extends BaseDto {
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.record.close;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 支付关闭记录
|
||||
* @author xxm
|
||||
* @since 2024/1/4
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "支付关闭记录")
|
||||
public class PayCloseRecordDto extends BaseDto {
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.order.pay;
|
||||
package cn.bootx.platform.daxpay.service.dto.record.pay;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
@@ -1,4 +1,4 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.order.refund;
|
||||
package cn.bootx.platform.daxpay.service.dto.record.refund;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import cn.bootx.platform.daxpay.code.PayRefundStatusEnum;
|
@@ -1,8 +1,9 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.order.sync;
|
||||
package cn.bootx.platform.daxpay.service.dto.record.sync;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.code.PaySyncStatusEnum;
|
||||
import cn.bootx.table.modify.annotation.DbComment;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -33,7 +34,7 @@ public class PaySyncRecordDto extends BaseDto {
|
||||
private String channel;
|
||||
|
||||
/** 通知消息 */
|
||||
@Schema(description = "通知消息")
|
||||
@Schema(description = "同步消息")
|
||||
private String syncInfo;
|
||||
|
||||
/**
|
||||
@@ -43,10 +44,20 @@ public class PaySyncRecordDto extends BaseDto {
|
||||
@Schema(description = "同步状态")
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 支付单如果状态不一致, 是否修复成功
|
||||
*/
|
||||
@DbComment("是否进行修复")
|
||||
private boolean repairOrder;
|
||||
|
||||
@Schema(description = "错误消息")
|
||||
private String msg;
|
||||
|
||||
/** 同步时间 */
|
||||
@Schema(description = "同步时间")
|
||||
private LocalDateTime syncTime;
|
||||
|
||||
/** 客户端IP */
|
||||
@Schema(description = "客户端IP")
|
||||
private String clientIp;
|
||||
}
|
@@ -3,8 +3,8 @@ package cn.bootx.platform.daxpay.service.func;
|
||||
import cn.bootx.platform.common.redis.RedisClient;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.dao.CallbackRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.entity.CallbackRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.dao.PayCallbackRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.record.callback.entity.PayCallbackRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.callback.result.PayCallbackResult;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.callback.service.PayCallbackService;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
@@ -26,7 +26,7 @@ public abstract class AbsPayCallbackStrategy implements PayStrategy {
|
||||
|
||||
private final RedisClient redisClient;
|
||||
|
||||
private final CallbackRecordManager callbackRecordManager;
|
||||
private final PayCallbackRecordManager callbackRecordManager;
|
||||
|
||||
private final PayCallbackService payCallbackService;
|
||||
|
||||
@@ -100,7 +100,7 @@ public abstract class AbsPayCallbackStrategy implements PayStrategy {
|
||||
*/
|
||||
public void saveNotifyRecord(PayCallbackResult result) {
|
||||
Map<String, String> callbackParam = PaymentContextLocal.get().getCallbackParam();
|
||||
CallbackRecord payNotifyRecord = new CallbackRecord()
|
||||
PayCallbackRecord payNotifyRecord = new PayCallbackRecord()
|
||||
.setNotifyInfo(JSONUtil.toJsonStr(callbackParam))
|
||||
.setNotifyTime(LocalDateTime.now())
|
||||
.setPaymentId(this.getPaymentId())
|
||||
|
Reference in New Issue
Block a user