第三方支付-账务系统之记账

488 阅读10分钟

支付

流程

支付流程包含了两个阶段

  1. 第一个阶段-支付

这个阶段,只是支付了,但是还没有支付成功。何时支付成功?要等渠道异步通知。

因为没有支付成功,所以不是在这个阶段记账。何时记账?等支付成功之后,才记账。

  1. 第二个阶段-渠道通知成功支付

支付公司,都是需要和外部对接,现在主要是和银联/网联对接。在支付行业,支付订单的支付结果都不是实时成功的,而是异步成功。

怎么个异步成功法?就是渠道银联会通知支付公司支付成功结果。也就是说,在渠道调用支付公司通知支付成功的时候,支付公司在这个时候才会把支付订单更新为支付成功状态。

支付订单支付成功之后,才会记账(商户余额加钱100)。


第一个阶段-渠道通知支付成功,这个阶段其实包含两个记账的点:

  1. 支付公司备付金加钱100

支付公司备付金的记账,是站在银联的角度,把消费者银行卡的钱转账到了支付公司备付金的银行卡。但是,支付公司的记账,一般是指给商户余额记账。

  1. 商户余额加钱100

在支付成功之后,也就是支付公司备付金收到钱之后,才记账(商户余额加钱100),这个是在站在支付公司的角度来说的。需要注意的是,因为支付公司给商户余额记账只是一个虚拟的假的数字,这个数字和银行卡数字的区别是,银行卡数字的钱就是真的钱,而支付公司的商户余额的数字不是真的钱。

重点来了,这两个记账的点,其实是有严格的顺序要求的,就是支付公司必须先确保自己备付金银行卡收到了钱,然后才敢在商户余额加钱。否则,很可能给商户余额加钱之后,但是支付公司备付金没有收到钱,这个时候支付公司很显然就亏钱了。

流程图

第一个阶段-支付

第二个阶段-渠道通知支付成功

记账

支付公司的记账,是指商户余额加钱和减钱。

在第二个阶段-渠道通知支付成功的时候,支付公司会记账(商户余额加钱100),其实就是相当于商家收到了消费者支付的100块钱。

重点来了,因为渠道通知支付成功的时候,支付公司备付金必然先收到了钱。所以,这个时候,是同步记账还是异步记账呢?都可以。


如果是同步记账,就要确保

  1. 更新支付状态为成功
  2. 记账

这两个操作都成功,或者都失败。其实就是一个事务,而且一般都是分布式事务(账务系统一般是独立的系统),所以需要确保分布式事务都成功,或者都失败。


那能异步记账吗?

其实是可以的。为什么可以异步记账?因为支付公司备付金银行卡已经收到了钱,就不担心会有资金损失。所以,什么时候给商家余额加钱这个记账操作,其实是可以晚一点的。既然可以晚一点,就可以异步。

这里说的异步,其实也是准实时,而不是延迟很久才记账。因为这里说的异步,只是把记账和更新支付状态为成功从一个事务拆开了。

具体怎么实现异步记账?有两种方法,

  1. 基于数据库

更新支付状态为成功之后,先创建记账任务表记录。

然后,job轮询记账任务表,再调用账务系统记账。

  1. 基于mq


异步记账的好处是什么?

  1. 高性能

无论是发mq消息,还是创建记账任务表,这个操作都比调用账务系统记账更轻量级,因为账务系统本身是很复杂的,比如还需要记科目,如果是复式记账,账务系统就会更复杂。越复杂,耗时就越慢。所以,异步记账可以提高处理速度。

  1. 重试

异步记账如果异常,是可以重试的。反正,支付公司备付金银行卡已经收到了钱,慢慢重试也没关系,只要最终记账成功即可。

退款

流程

退款也是两个阶段,其实支付都是两个阶段,因为不是实时成功,即不是同步调用成功,而是要等渠道通知支付成功。

但是,在具体实现上,我们可以把第一个阶段拆分为两个阶段:

  1. 先受理退款

受理是指,商家退款的时候,支付公司创建退款订单。但是,这个时候还没有发往渠道。

所以,这个阶段只是受理了商户的退款请求。但是,支付公司并没有把这个退款交易发往银联。

这个阶段总共做了两个重要的事情:1)创建退款订单,即相当于受理退款。 2)然后,再记账(先冻结),即商户余额减钱,但是特别需要注意的是,这里的记账是先冻结,先冻结的目的是,防止在真正退款真正记账真正扣钱的时候,商户余额还有钱可扣。

  1. 然后,再异步发往渠道

这一步才会把退款交易发往银联。而且,这一步可以是异步的。

那具体是怎么异步的?在刚才受理退款的时候,可以先创建发往渠道退款任务表记录。然后,基于job轮询该任务表。

那为什么可以异步?为什么要异步?原因是因为退款的时候,本质是要把支付公司备付金银行卡的钱转账到消费者银行卡。支付公司作为一个商业公司,和所有的电商公司/支付公司一样,都是优先确保支付成功/交易成功,而且都是准实时。但是退款的周期是以天为单位,一方面是不想让你退款,更重要的一方面是,退款的处理在安全上更为谨慎,速度也更慢,因为处理错了,支付公司就要亏钱。而支付的时候之所以速度快,是因为速度越快,交易越多,赚的钱就越多。

这个阶段总共做了两个重要的事情:1)记账(后解冻/扣款),注意,这里才是真正的扣钱成功 2)然后,发往渠道退款。


所以,退款总共分三个阶段:

  1. 第一个阶段-受理退款
  2. 第二个阶段-发往渠道退款
  3. 第三个阶段-渠道通知退款成功

流程图

第一个阶段-先受理退款

第二个阶段-发往渠道退款

第三个阶段-渠道通知退款成功

记账

  1. 记账和发往渠道的顺序

退款和支付,最大的一个区别是,支付是先发往渠道(支付公司先确保自己收到钱),渠道通知成功之后再记账(然后再给商家余额加钱)。

但是,退款是先记账(支付公司先确保从商家余额扣钱,本质还是先确保支付公司自己收到钱),后发往渠道退款(然后再发往渠道退款)。

所以,之所以有顺序的差异,本质都是因为支付公司首先要确保的是支付公司自己要先收到钱。

  1. 先冻结和后解冻

为什么要分冻结和解冻呢?为什么要分两个阶段呢?这个其实不一定非得这样,如果是受理退款的时候,然后直接就发往渠道退款,其实是没有必要这么设计的,就直接先记账,后发往渠道就可以了。

但是,异步有异步的好处,这是一个权衡和平衡的过程。说白了,就是退款的实时性没有支付那么高,然后就把发往渠道这个子步骤单独拆分为一个阶段。如果采用了拆分这个设计方案,那么就必须要在受理退款的时候就要先冻结,然后在发往渠道的时候再解冻。

记账-同步还是异步?

支付

可以异步做,因为渠道通知支付成功的时候,支付公司备付金银行卡反正已经收到了钱,它就可以稍微慢一点给商户余额加钱。这里说的慢一点,不是真的慢,而是从纯技术的角度来说的,如果是实时同步调用,那么耗时就是ms级别,如果是异步调用和异步处理其实也是ms级别(但是仍然会比实时同步调用慢个几ms),最多秒级别。

所以,异步的作用,主要是为了在业务上如果能解耦就解耦,说白了,就是能拆分成多个阶段就是拆分成多个阶段,不要让单个阶段太重,特别是如果只有一个阶段,那这个阶段就包含了所有的业务逻辑,处理速度就必然慢,系统的性能就不可能高。异步解耦拆分,就是为了解决高性能问题。

退款

受理退款的时候,必须要确保扣款成功,即必须要确保冻结成功。否则,就是受理退款失败。

为什么必须要同步记账?因为支付公司必须确保自己先收到钱,从商户余额先冻结钱就是确保支付公司自己先拿到这个要退款的钱,支付公司才敢把这笔退款订单发往渠道,因为发往渠道之后,其实就是要把支付公司备付金银行卡的钱转账到消费者银行卡。

说白了,就是只要是从商户余额扣钱(先冻结),就必须确保同步。但是,后面的解冻其实是可以异步的,因为只要冻结了,这个钱就跑步了,就不会被商家提现,就可以确保支付公司在发往渠道退款的时候就不会亏钱。

总结

我们发现一个规律,就是只要是给商家余额加钱,那么就都可以异步,因为这样可以解决高性能问题,而且支付公司在业务上在资金上不会亏钱。

相反,只要是给商家余额减钱,那么必须是同步。同步减钱的本质,也是确保支付公司先收到钱。

记账-是先记账还是先发往渠道?

上面其实已经讲过,因为比较重要,这里再讲一遍。

退款和支付,最大的一个区别是,支付是先发往渠道(支付公司先确保自己收到钱),渠道通知成功之后再记账(然后再给商家余额加钱)。

但是,退款是先记账(支付公司先确保从商家余额扣钱,本质还是先确保支付公司自己收到钱),后发往渠道退款(然后再发往渠道退款)。

所以,之所以有顺序的差异,本质都是因为支付公司首先要确保的是支付公司自己要先收到钱。