和支付有点不一样
支付的时候,是在支付成功之后,即渠道通知支付成功的时候:
1、更新本地订单状态为成功
2、记账
先插入记账流水,后异步轮询。
3、通知商户
4、通知代付
为什么不是直接调用记账接口记账?
因为记账很复杂,所以为了提高性能
,交易这边只是简单的插入记账流水,后面再异步轮询流水。
更新订单状态和记账,同一个事务。
那退款怎么记账?
退款的时候,和支付最大的不同,主要是资金安全的不同,支付是收款,相当于入金。退款是出金。
入金的时候,支付公司已经收到钱了,所以给商家记账的时候,就可以异步。本质也是为了提高性能。商家的钱,晚点到账也没关系,这里说的晚点是和实时交易相比,其实也是准实时。只不过为了提高实时交易的性能,然后呢,就搞了个:流水 + 异步轮询。
那出金呢?出金的话,必须要确保资金安全,而且比入金更苛刻,因为绝对不能出现钱已经退到消费者银行卡了,但是商户的钱却没有扣款成功的情况。所以,退款的时候,就是必须先冻结资金:
1、先冻结
注意是直接同步调用接口记账。如果失败,直接拒绝。也不需要在交易系统这边插入记账流水。
2、再创建退款订单
创建退款订单之前,就必须要要确保冻结成功
3、创建退款明细事件
刚才只是冻结,那什么时候真正扣款?
异步轮询事件,其实就是退款的时候插入的创建退款明细事件,这个事件干嘛的呢?创建退款明细。
所以,核心流程是:
1、创建退款明细
2、记账
先插入记账流水,后异步轮询。
刚才上一步已经创建退款明细,那何时发往渠道?
异步轮询退款明细的时候,发往渠道。
这个时候,还会有记账相关的东西吗?没有。
流程图
说明:下面流程图里的pool,其实就是处理退款交易的服务,只不过呢,退款很多动作都是基于异步,所以把相关接口从实时交易服务拆分到了pool服务,其实大概就是轮询池的意思。总之,轮询的时候,job——》pool,因为都是异步。
第一个阶段-退款
先冻结
直接同步调用记账接口,无记账流水
第二个阶段-异步轮询创建退款明细事件,创建退款明细
解冻:真正扣款
先插入记账流水,然后再慢慢解冻
第三个阶段-异步轮询退款明细,发往渠道
无任何记账相关的东西,因为之前两步都已经处理完了记账相关的事情。
第四个阶段-渠道通知退款成功
更没有任何记账相关的东西,因为上一步就已经没有任何记账相关的东西。而支付的时候,是在渠道通知支付成功的时候,才敢记账。
总结
出于出金的资金安全考虑,必须先冻结,和入金不一样,这个ok,是没有问题的。
但是,异步的阶段有点多,可以稍微优化一下。当然,这是一个权衡的问题,就是资金安全和高性能权衡的问题。