一、前提
本方案是基于 「微信非付款码支付」 进行设计的。
二、业务场景
首先,大家先大概了解下「预约」和「取消预约」两个流程。
- 预约
- 取消预约
三、遇到的问题
试想如下场景:
用户预约,拉起微信支付后选择支付,但是在支付回调通知前,用户又发起了取消。此时该如何实现取消逻辑呢?
此时,订单的状态处于 “待支付”,是允许取消还是不允许取消呢?首先,说下 “不允许取消” 这种情况在业务上是不可能成立的,为什么这么说呢?因为,只有那些处于 “支付中” 状态的订单不允许取消才合理,而我们只有 “待支付”、“支付成功” 状态,我们无法得到 “支付中” 这个状态。
所以,只能允许取消!!!!
如果允许取消的话,是退款还是不退款呢?通过当前订单状态 “待支付”,我们也没办法判断用户是取消支付了(未发生真正的支付不需要进行退款),还是支付了但我方系统还未得到支付回调通知(发生了真正的支付需要进行退款)。
分别在 “取消支付”、“支付了我方系统还未得到支付回调通知” 两个场景下分别进行 退款、不退款 都会出现那些问题呢?
操作 | 订单状态 | 取消支付 | 支付了我方系统还未得到支付回调通知 |
---|---|---|---|
不退款 | 待支付 => 取消 | 因为根本没发生实际的支付,所以不退款是合理的 | 订单虽然成功取消了,但由于不退款,造成用户无法得到退款的钱 |
退款 | 待支付 => 取消 | 因为根本没发生实际的支付,所以所有退款都会失败 | 1、退款失败(那些在微信端还在支付中的订单);2、退款成功(刚好支付完成且成功) |
四、方案设计
-
用户在前端触发「取消」
-
支付回调通知
判断 “支付成功” 的交易是否有对应的「由于取消产生的待退款任务」,如果存在,则需要进行退库退款。至此,通过以上 2 步,我们来看看可能会出现的所有场景,如下:
这里需要重点说明的是 场景四。由于并发的情况,会造成一个本该被处理的「由于取消产生的待退款任务」可能永远都无法被处理的情况产生。 -
定时任务
为了解决 场景四 的问题,我们还需要一个定时任务来进行最后的兜底处理。