fix 异步支付失败情况下数据保存不完整问题

This commit is contained in:
xxm1995
2024-03-26 16:48:39 +08:00
parent 8c74eb7fee
commit 7d0d5d7110
5 changed files with 50 additions and 33 deletions

View File

@@ -22,7 +22,7 @@
## 🧭 特色功能
- 封装各类支付通道的接口为统一的接口,方便业务系统进行调用,简化对接多种支付方式的复杂度
- 已对接`微信支付``支付宝`相关的接口,目前已经支持`V2`版本的接口,后续版本将支持`V3`版本的接口
- 已对接`微信支付``支付宝`和云闪付相关的接口,后续版本将支持`V3`版本的接口
- 支持组合支付,满足用户系统需要多种方式同时进行支付的场景。
- 提供`HTTP`方式接口调用能力,和`Java`版本的`SDK`,方便业务系统进行对接
- 接口请求和响应数据支持启用签名机制,可根据实际需要进行开关,保证交易安全可靠
@@ -150,16 +150,14 @@ public class SimplePayOrderTest {
```
## 🍎 系统截图
### H5收银台演示
![h5.png](https://s11.ax1x.com/2024/02/12/pF8nPMV.png)
### 支付演示
![pay.png](https://s11.ax1x.com/2024/02/12/pF8np2q.png)
### 收银台演示
![pc.jpg](https://s11.ax1x.com/2024/02/12/pF8n9x0.jpg)
![微信截图_20240326141126](https://jsd.cdn.zzko.cn/gh/xxm1995/picx-images-hosting@master/daxpay/微信截图_20240326141126.es9yupxd3.webp)
### 驾驶舱
![QQ截图20240326141912](https://jsd.cdn.zzko.cn/gh/xxm1995/picx-images-hosting@master/daxpay/QQ截图20240326141912.60u0cpvjg5.webp)
### H5收银台演示
![h5](https://jsd.cdn.zzko.cn/gh/xxm1995/picx-images-hosting@master/daxpay/h5.839t0s61xr.webp)
### 支付通道配置
![](https://s11.ax1x.com/2024/02/13/pF8s2VS.jpg)
![微信截图_20240326142208](https://jsd.cdn.zzko.cn/gh/xxm1995/picx-images-hosting@master/daxpay/微信截图_20240326142208.6bgu5vdv60.webp)
## 🛣️ 路线图
> 当前处于功能开发阶段,部分功能可能会有调整,`V2.1.0`时将作为正式生产可用版本进行发布之后会保证系统版本非大版本升级时API接口和数据接口向前兼容

View File

@@ -1,21 +1,16 @@
2.0.4:
- [x] 支付流程也改为先落库后支付情况, 避免极端情况导致掉单
- [x] 首页驾驶舱功能: 各通道收入和支付情况
- [x] 第一排: (数字格式)显示今日收入、支出金额,支付订单数量、退款总订单数, 时间分支分为: 今日金额/昨日金额/七天内金额
- [x] 第二排: (饼图)显示各通道各支付方式数量和占比, 时间分为: 今日金额/昨日金额/七天内金额
- [x] 第三排: (折线图)显示各通道支付分为支付金额和退款,时间分为: 今日金额/昨日金额/七天内金额
- [x] 云闪付支持对账功能
- [x] 对账文件支持手动导入
- [x] 结算台DEMO增加云闪付示例
- [x] 增加支付限额
- [x] 各通道(异步支付)支持单独的限额
- [x] 整个订单支持整体的限额
2.0.5:
- [ ] 资金流水优化
- [ ] 支持分账
- [ ] 增加撤销功能,用于处理线下支付订单的情况
- [ ] 统计报表功能
- [ ] 修复创建支付订单报错时, 订单保存数据不完整
- [ ] 针对同步/对账等出现脏数据导致阻塞的问题, 进行优化
- [ ] 同步接口
- [ ] 对账接口
2.0.x 版本内容
- [ ] 微信新增V3版本接口
- [ ] 付款码支付自动路由到V2接口
- [ ] 资金流水优化
- [ ] 统一关闭接口增加使用撤销关闭订单
- [ ] 支持分账
- [ ] 增加各类日志记录,例如钱包的各项操作
- [ ] 增加撤销功能,用于处理线下支付订单的情况
- [ ] 数据库表进行规则, 字段设置长度, 增加索引

View File

@@ -72,10 +72,12 @@ public class PayOrderExtra extends MpBaseEntity implements EntityBaseFunction<Pa
/** 错误码 */
@DbColumn(comment = "错误码")
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private String errorCode;
/** 错误信息 */
@DbColumn(comment = "错误信息")
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private String errorMsg;
/**

View File

@@ -81,7 +81,7 @@ public class PayService {
payParam.setPayChannels(Collections.singletonList(payChannelParam));
// 复用支付下单接口
return this.pay(payParam);
}
}
/**
@@ -206,7 +206,7 @@ public class PayService {
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
// 获取支付方式,通过工厂生成对应的策略组
List<AbsPayStrategy> strategies = PayStrategyFactory.createAsyncLast(payParam.getPayChannels());
List<AbsPayStrategy> strategies = PayStrategyFactory.createAsyncLast(payParam.getPayChannels());
if (CollectionUtil.isEmpty(strategies)) {
throw new PayUnsupportedMethodException();
}
@@ -219,9 +219,8 @@ public class PayService {
// 执行支付前处理动作, 进行各种校验
asyncPayStrategy.doBeforePayHandler();
// 创建支付订单和扩展记录并返回支付订单对象
PayOrder payOrder = payAssistService.createPayOrder(payParam);
asyncPayStrategy.setOrder(payOrder);
// 执行支付前的保存动作, 保持订单和通道订单的原子性
PayOrder payOrder = SpringUtil.getBean(this.getClass()).firstPreAsyncPay(asyncPayStrategy, payParam);
// 支付操作
try {
@@ -238,6 +237,19 @@ public class PayService {
}
/**
* 异步单通道支付的订单预保存, 保存订单和通道订单
*/
@Transactional(rollbackFor = Exception.class)
public PayOrder firstPreAsyncPay(AbsPayStrategy asyncPayStrategy, PayParam payParam){
// 创建支付订单和扩展记录并返回支付订单对象
PayOrder payOrder = payAssistService.createPayOrder(payParam);
asyncPayStrategy.setOrder(payOrder);
// 生成通道支付订单
asyncPayStrategy.generateChannelOrder();
return payOrder;
}
/**
* 首次单通道异步支付成功后操作, 更新订单和扥爱松
*/
@@ -254,9 +266,13 @@ public class PayService {
.setPayTime(LocalDateTime.now());
}
payOrderService.updateById(payOrder);
// 扩展记录更新
PayOrderExtra payOrderExtra = payInfo.getPayOrderExtra();
payOrderExtra.setErrorMsg(null);
payOrderExtraManager.update(payOrderExtra);
// 如果支付完成 发送通知
if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){
clientNoticeService.registerPayNotice(payOrder, payInfo.getPayOrderExtra(), payInfo.getPayChannelOrders());
clientNoticeService.registerPayNotice(payOrder, payOrderExtra, payInfo.getPayChannelOrders());
}
return PayBuilder.buildPayResultByPayOrder(payOrder);
}
@@ -348,10 +364,13 @@ public class PayService {
.setPayTime(LocalDateTime.now());
}
payOrderService.updateById(payOrder);
payOrderService.updateById(payOrder);
// 扩展记录更新
PayOrderExtra payOrderExtra = payInfo.getPayOrderExtra();
payOrderExtra.setErrorMsg(null);
payOrderExtraManager.update(payOrderExtra);
// 如果支付完成 发送通知
if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){
clientNoticeService.registerPayNotice(payOrder, payInfo.getPayOrderExtra(), payInfo.getPayChannelOrders());
clientNoticeService.registerPayNotice(payOrder, payOrderExtra, payInfo.getPayChannelOrders());
}
return PayBuilder.buildPayResultByPayOrder(payOrder);
}
@@ -428,6 +447,9 @@ public class PayService {
.setPayTime(LocalDateTime.now());
}
payOrderService.updateById(payOrder);
// 扩展记录更新
payOrderExtra.setErrorMsg(null);
payOrderExtraManager.update(payOrderExtra);
// 如果支付完成 发送通知
if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){
// 查询通道订单

View File

@@ -165,7 +165,7 @@ dax-pay:
# 演示模块
demo:
# 网关地址
server-url: http://localhost:9000/server
server-url: http://localhost:9000
# 前端h5地址
front-h5-url: http://localhost:5173/#
# 签名秘钥