三方支付系统中的补单机制为例通用单据补偿模式
2023-01-16
2005浏览
三方支付系统中的补单机制为例通用单据补偿模式中的支付单继续推进后续流程;若不一致则返回错误。比如支付单已经完成了所有资金处理,状态机已经是终态,那么接口可以直接返回相应结果。异步通知,在支付单推进到终态后进行。本文首先介绍了什么是补单,接着基于三方支付系统的实现完整阐述了补单机制的演进过程,最终演化为一种相对通用的异常处理模式,即基于消息队列、有限状态机与多重任务兜底的业务层最终一致性保障机制,供大家参考指正。

0 前言

日常生活中,从线下超市购物到线上外卖订餐、电商网购等,支付无处不在,无论是现金、POS机刷卡,还是微信支付宝等第三方支付。 在线支付,一次到账,及时便捷的极致体验。 当然,也有几次体验不够流畅。 比如早期我们在PC版12306上买火车票,在支付完成的时候,经常会出现订单支付状态没有及时更新的情况。 时间拖延,有时甚至在无偿状态下长时间等待。

支付过程中,由于各种原因(比如外部通道处理有问题,异步回调不来),中途停止,用户看到订单还未支付,不会知道该怎么办。 这时候就需要一种机制来推动这个交易的完成。 本文以三方支付系统中的补单机制为例,介绍一种更通用的单据补偿模型。

一、三方支付系统介绍 1.1 什么是三方支付

所谓第三方支付,就是与各大银行签约,独立于商户和银行,具有一定实力和信誉保证,为商户和消费者提供支付结算服务的第三方独立机构。 它是买卖双方之间的可信第三方,充当担保人和资金托管人。 三方支付也可以称为虚拟账户支付。 消费者在第三方支付机构开立虚拟账户,使用虚拟账户内的资金进行支付。 业内常见的三方支付包括支付宝、微信支付、美团支付、京东支付等。

1.2 三方支付交易支付系统

什么是交易,最直观的描述就是“一只手付款,一只手发货”。 交易将在买卖双方之间形成债权债务关系。 交易的存在是支付的前提,用户通过一定的支付方式完成交易。 交易是支付过程的驱动,根据具体场景组合不同的支付指令,完成交易资金的转移。

支付是交易处理资金流动的工具,目的是清偿债权债务关系; 支持多种支付方式(如银行卡支付、余额支付、优惠券组合支付、类似花呗的信用支付等),负责对接账户、计费系统等资金处理能力,接收支付指令,并推动资金汇兑的完成。 将实际支付行为(实际资金)与内部记账(虚拟资金)相结合,保证虚实相符。

三方支付整体业务架构如图1所示,其中交易核心和支付核心在业务划分上都属于“收单支付域”,具有收、付、退、充等共同功能、转账及普通交易取现。 它还包括支持电子商务业务的组合支付、担保和账户共享的能力。 其中,交易与支付核心有一个异常检查模块,包含了所有业务的赔付流程,也是本文的主要部分。

补单_帅同社区积分补单在哪_移动补卡业务受理单

图1. 三方支付业务架构

2、什么是补货单&为什么需要补货单

某笔交易在支付过程中因链路出现各种异常而中断。 此时事务处于中间状态。 这种情况俗称“牌单”,即牌不动,不继续向下。 进步。 在另一种情况下,支付核心向通道发起扣费。 通道接受支付后,银行卡扣款成功,但由于种种原因,没有向支付核心发起回调。 结果导致支付没有完成,用户也没有享受到相应的权利,但是银行卡里的钱却被扣了。 这种情况称为“掉单”。

不管是卡单还是丢单,都是处于中间状态的单。 订单补货是补偿处于中间状态的订单,直到到达最终状态(成功或失败)。 订单补货一般有两个关键点。 一是补偿的有效性。 在极端情况下,补偿可能多次失败。 你不能就这样放弃。 需要有一个自下而上的机制; 另一个是补偿的及时性,因为交易暂停时间越长,用户体验越差。

交易核心和支付核心的订单补货相辅相成,在设计和实现上具有一定的相似性。 下面以支付核心的补单为例,介绍异常补单机制。

3、补单是如何实现的?

本章首先了解业务流程,说明实现订单补货的基本前提,然后介绍订单补货机制的演进路线,各版本存在的问题,以及下一版本如何解决。

3.1 基金运作的有限状态机和有限状态机的幂等辨识

我们先以用户发起余额提现为例来说明业务流程,简化后如图2所示。

移动补卡业务受理单_帅同社区积分补单在哪_补单

图 2. 余额提取流程

首先生成支付指令,然后请求记账系统扣除用户账户下的余额,然后向外部通道发起支付操作。 资金运作完成后,统一处理结果,更新单据信息。 最后,还有一些上下游的异步通知。 正式包括消息和 RPC 回调。

我们将每笔关键资金操作情况记录入库,如下表所示。 其中,取款是指钱从哪里来,存是指钱到哪里去,而reversal是指交易的回滚。 在提现场景中补单,钱从用户的支付账户中提取到用户的银行卡中。 其他场景如充值(银行卡->用户支付账户),会有不同的资金流向。 表中最后两行加粗的场景还没有达到最终状态,需要我们进行补偿。

补单_帅同社区积分补单在哪_移动补卡业务受理单

为了便于理解,我们这里省略了反转的相关操作,一个余额提现过程的状态机转换如图3所示。

移动补卡业务受理单_帅同社区积分补单在哪_补单

图 3. 带状态机转换的余额提取流程

可重入性和幂等性保证

发起支付涉及系统间的多次调用,网络原因造成的通信超时是常见问题。 同时,上游系统也可能重新发起请求,这就需要我们的系统保证运算结果的幂等性。 少数用户也可能有多个终端同时操作带来的并发请求,我们需要保证接口的可重入性。 除了服务本身,我们的下游依赖也需要保证它们的接口具有相同的能力。

先说说可重入性和幂等性。

具体在业务上,幂等性是针对一个已经到达最终状态的支付。 对于第一次未能获得最终业务结果的请求,再次发起调用的结果可能不同(处理->处理成功或失败)。 那么如何保证业务流程的可重入性和幂等性呢? 让我们分别分解每个步骤:

生成付款单:首先,付款单可以使用业务方传递的唯一外部订单号作为唯一索引。 如果插入数据库时​​出现唯一索引冲突,则查询已有数据进行幂等参数校验。 如果第二次请求的参数完全一致,说明是重复请求,可以使用DB中的支付顺序继续推进后续流程; 如果它们不一致,将返回错误。 资金处理流程:账户系统和通道系统各自保证接口的幂等性。 我们也会维护每个下游操作的状态,根据状态机来决定是否进行,尽量不向下游输出重复的流量。 例如支付订单已经完成所有的资金处理,状态机处于final状态,那么接口可以直接返回相应的结果。 更新支付订单信息,首先对支付订单加行级排他锁,然后更新,保证多个并发请求只有一个成功。 异步通知,支付订单推送到最终状态后进行。

有了可重入性和幂等性的保证,我们就可以大量复用前向过程来实现补货接口。

3.2 初始版本

一般来说,订单补货最常见的形式是设置定时任务定时扫表完成业务补款。 实现相对简单,但时效性不够,收款、转账等交易用户体验不佳。 我们采用了通过消息队列立即补偿的方式,如图4所示。补偿消费者不做补偿工作​​,而是解析消息,通过RPC调用支付核心暴露的补偿接口。 为什么不直接在消费者那里补偿呢? 这主要是考虑将逻辑汇聚到一处,方便维护。

移动补卡业务受理单_帅同社区积分补单在哪_补单

图4 余额提取异常时的订单补货流程

当然,补单还是有可能失败,我们可以重新发送补偿信息。 但是不能一直这样下去,所以需要设置一个最大重试次数,超过之后就不要发送了。 当补偿多次失败时,通常是下游系统出现问题。 这时候,我们需要放慢补偿的频率。 随着重试次数的增加,每次补偿的时间间隔会逐渐增加。 通过RocketMQ的延迟消息实现。

以下是我想到的三个问题:

如果异常消息发送失败,上游没有重试机制,订单可能会一直挂在这里,如图5所示。补偿消费者对核心补货订单请求付款失败。 可能是超时了但是实际补偿成功了,或者请求根本就没有通过,如图6所示,如果重试了最大次数还是失败了,这个命令应该怎么办。

移动补卡业务受理单_帅同社区积分补单在哪_补单

图 5. 补偿消息发送失败

补单_移动补卡业务受理单_帅同社区积分补单在哪

图 6. 补偿消息消费失败

3.3 改进版

对于问题1,如果重试后发送失败,我们引入一个异常消息表来存储发送失败的消息。 该表记录了订单号、当前重试次数、异常分类、记录状态、消息体等字段。 如果图6中的步骤4发送消息失败,将订单放入DB中的异常表中补单,设置定时任务处理。 以目前RocketMQ的可用性,异常数据很少出现。 如图7所示。

帅同社区积分补单在哪_补单_移动补卡业务受理单

图 7. 消息生产/消费异常的改进版本 - 1

对于第二个问题,如果补偿消费者调用支付核心失败,补偿消费者HandleMessage会向上层抛出错误。 利用RocketMQ的梯度重试机制,当消费重试次数达到一定上限时,就会进入死信队列。 如图8所示,这种情况一般是由于业务或网络问题。 恢复后,可以从死信队列中拉取这些消息,统一处理。

移动补卡业务受理单_补单_帅同社区积分补单在哪

图 8. 消息生产/消费异常的改进版本 - 2

当然还有更极端的情况,如果MQ和DB请求都失败了怎么办? 就目前MQ和DB的可用性来说,基本不需要同时考虑故障,人工干预告警即可。

对于问题3,如果重试超过了最大次数,但还是补偿不成功,一般是下游依赖有问题。 在这种情况下,我们也将其放入异常表中。

针对这两类漏网之鱼,需要支持人工干预的单笔/批量支付单赔付操作能力; 最好有一个自下而上的任务,在业务低峰时段运行,扫描业务单据表,不会在一段时间内完成订单补偿。

另外,自下而上的任务可能会造成消息的短暂堆积,影响在线实时补偿流程的进度,可以使用独立队列进行隔离。

3.4 最终版本

其实,如果异步通知操作只有异常,没必要每次都走完整个业务流程,缺什么补什么就可以了。 因此,我们将异常分为多种类型,将一些异步操作和业务处理分离,进行细化处理:

图 9 以这些异常为例说明了每种补偿类型的消息参数。

帅同社区积分补单在哪_移动补卡业务受理单_补单

图 9. 分类补偿

我们最终的订单补货系统如图10所示,它既通过即时消息保证了补货的及时性,又主动出击; 它还通过重试延迟消息、登陆失败消息的异常表和自下而上的任务来确保补偿的有效性。 性是万无一失的盾牌。 不仅可以用于支付单据的补偿,还可以通过保证流程的可重入性来作为通用的解决方案,但不适用于无状态、不可重入的业务表单。

移动补卡业务受理单_帅同社区积分补单在哪_补单

图 10. 异常补偿系统

4.总结

本文首先介绍什么是补单,然后基于三方支付系统的实现,全面阐述补单机制的演化过程,最后演化为一种比较常见的异常处理方式,即基于消息队列、有限状态机和多任务。 业务层的最终一致性保证机制,供大家参考修正。

以上内容均来自网络搜集,如有侵权联系客服删除

图文阅读
最新文章
淘宝自补发快递:安全但成本高,真实礼品快递空包代发可解决?
2022-10-30 08:02:14
甩货:通过低价促销搞定基础销量和评价的有效方法
2022-10-30 08:02:14
掌握这些关键点,轻松做好拼多多店铺运营
2022-10-30 08:02:14
利用直通车等多种方式,快速提升淘宝商品销量
2022-10-30 08:02:14
空包裹刷单利益链曝光:快递员、公司、商家均参与,用户信息成牺牲品
2022-10-30 08:02:14
快手小店补单方法大揭秘!如何利用短视频平台流量提升店铺销量?
2022-10-30 08:02:14
9 年电商人陈升分享:淘宝蓝海无货源年利润超 200W 的秘诀
2022-10-30 08:02:14
补单和补单的区别是什么?的方法有哪些?
2022-10-30 08:02:14
 
QQ在线咨询
客服热线
客服微信号
STU006