gitbook/分布式金融架构课/docs/324117.md
2022-09-03 22:05:03 +08:00

235 lines
22 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 02 | 原理解读:如何理解第三方支付的业务逻辑和系统组件?
你好,我是任杰。这节课我们聊一聊如何理解支付业务逻辑和系统组件。
在[上一节课](https://time.geekbang.org/column/article/323701)中,我已经从宏观角度带你梳理了扫码支付从前到后的整个流程。我们发现,虽然扫码支付是一个非常便捷的用户产品,但是它后面涉及到了很多的机构和业务流程。
你有没有好奇过,第三方支付公司是怎么解决这些复杂业务问题的呢?如果你在金融行业呆过一段时间,就会发现不只是扫码支付,其他的金融业务都很复杂。那我们有没有可能复用第三方支付的这些经验,来解决其他的金融业务问题呢?
和我们解数学应用题一样,要应对第三方支付这类复杂的业务问题,我们**首先要分析它里面的核心原理是什么。接下来尝试通过核心原理来推算出可能的规律。这些规律就决定了系统架构的演进规律**。如果你掌握了这些分析问题的方法,碰到其他复杂的金融业务问题时就能游刃有余地解决了。
所以,接下来我们先搞懂支付涉及的核心金融原理,然后按照架构由简到难的顺序,逐步学习点券系统、支付系统和第三方支付公司的支付系统。这样你就能理解支付系统是如何遵循核心金融原理,一步一步从简单的几个组件发展到全面的系统架构了。
## 信息流与资金流分离
我们都知道,作为架构师,我们在做架构设计的时候,需要确保架构原理和业务原理一致。每一行都有自己独有的业务原理,支付业务也不例外。
那说到业务原理,在支付业务中最核心的概念是**信息流与资金流分离**。那什么是信息流和资金流呢?用一句话来概括,**信息流指的是想象中钱的流转过程,资金流指的是钱的实际流转过程。**
具体怎么理解呢?我给你举一个简单的例子。
假设你用户A和你的朋友用户B做生意。你的银行账户里有一块钱。白天的时候你给你朋友转了一块钱。但是你并没有把钱实际转给你朋友而是给你朋友一张字条上面记下了你转给你朋友一块钱。同样的你朋友过了一会儿也通过字条转回给了你一块钱。在白天你们俩就这么来回转来转去。
到了晚上你和你朋友对了一下白天所有的交易发现你一共要转给你朋友51元而你朋友一共需要转给你50元。
显然你们俩之间的这50元是可以互相抵消掉的。抵消之后你只需要给你朋友转一块钱就行。于是你通过银行将这一块钱转给了你朋友。过程示意图如下
![](https://static001.geekbang.org/resource/image/14/e5/14ba019a9b10c30e796d1cc9359bbce5.png)
我们分析一下上面这个过程。你账上的一块钱在白天的时候一直没动。这一块钱是真实的资金,你在白天的时候一直都有这一块钱的所有权。
但是在白天你和朋友通过纸条的形式将这一块钱来回转来转去,这个过程其实转移的是这一块钱的使用权。这种**资金使用权的转移过程就是信息流。**
只有晚上你们俩对完账,并通过银行转完账之后,这一块钱的所有权才真正属于你朋友。这种**资金所有权的转移过程就是资金流。**
顺便提一下,我们在前一节课介绍跨行转账时提到了清算中心和央行。这个例子中用字条转账的过程就是清算中心每天做的事情,最后通过银行转账的过程就是央行在做的事情。我在后面还会再讲一个类似的例子。
当然了,原理只是说信息流和资金流可以分离,通常这两者也是处在分离的状态。但是它们俩不一定需要分离,比如有个实时清算的概念,可以实时保证信息流和资金流一致。
现代支付系统中普遍采用了信息流和资金流分离的做法,这里的原因有很多。如果从系统架构的角度分析,我们会发现,实时清结算对软件系统的吞吐量和延时要求非常高,同时还要求所有参与的支付公司都具有实时清结算能力,任何一家达不到都不行。
这样一来,就需要整个国内和国际金融系统都重新设计系统底层的核心架构。短期来说,这么巨大的技术投资并没有相应规模的经济收益作为支撑。
所以,目前我们在支付系统架构设计中需要假设这两者是分离的。理解了这个概念,我们再来看看它会给架构设计带来哪些影响。主要有以下三点:
第一,支付环节的非银行参与者只能产生信息流,不能产生资金流。这是因为大多数金融机构并没有物理的现金,纸钞都放在了银行里。
所谓合久必分,分久必合。**虽然信息流和资金流分开了,但它们俩最终还是需要同步的**。同步的过程就需要再次和银行系统进行对接。这意味着支付系统需要**通过网关的形式与外部支付系统进行状态同步**。
第二,资金流和信息流分开之后,这两者将以不同速度在不同时间的不同主体分开流转。这意味着**支付系统从本质上是一个异步处理系统资金流和信息流的统一具有最终一致性Eventual Consistency**。这就是为什么在扫码支付状态拉取时,银行对接是异步消息处理的。这个我们上节课也提到了,你可以仔细体会一下。
第三,资金流和信息流最终需要同步,即需要一个**核算系统**来确认同步过程准确无误。
好了,讲到这里,你应该理解了支付系统架构的核心原理,就是**内部信息流系统与外部资金流系统的异步交互**。
那怎么把这个原理转化成技术架构呢?接下来我们先来看看最简单的点券系统架构是怎样的。
## 点券系统
**在点券系统里资金流和信息流是一致的**。这是金融业务最简单的情况,也是所有相关架构的基础。
顾名思义,点券系统就是管理点券的系统。因为重点是讲解架构原理,所以在这里对点券业务和系统做一些简化。
现在我们假设只有代金券这一种点券,而且你只能使用代金券来购买产品。
具体的购买流程是这样的。首先业务系统需要发起一笔交易订单用户A用10元的代金券从用户B购买一支笔。
交易订单接下来会变成支付订单。支付订单只记录了用户账号的变动关系,不包含物品交换的关系。简单来说,交易订单包括财产交换和物品交换两种信息,支付订单只包含财产交换的信息。
这笔支付订单会发给支付系统。支付系统在收到这笔支付订单后需要对用户A及用户B的代金券账号进行处理。
假设最开始用户A拥有100元代金券用户B拥有10元代金券。那么在购买后用户A的代金券账号需要减少10元的代金券同时用户B的代金券账号需要增加10元的代金券。
好了到目前为止我们可以看到支付过程至少需要3个系统
1.业务系统,负责生成交易订单和支付订单;
2.支付网关,负责处理支付订单;
3.账务系统,负责维护用户账户情况。
系统架构图如下:
![](https://static001.geekbang.org/resource/image/57/dd/57d4d3e05c2907d4670716030ec390dd.jpg)
点券支付到这里就结束了。但是作为一个完整的系统好像还缺了些什么功能。比如,在用代金券支付完成后,用户可能需要检查自己的代金券余额,以及与代金券相关的账单。所以我们还需要一个**查询系统**来完成相关的查询。
另外从产品体验角度看现在的系统还有一点不足用户B并不知道自己账户收到了点券。这时候及时通知用户B可能是一个更合适的产品设计。这时还需要一个账户变动的**通知系统**。通知系统通常采用异步通知的方式。
为了方便理解,我们假设所有和用户相关的系统都在业务系统内。更新之后的架构图如下所示(红色标注的是更新的节点):
![](https://static001.geekbang.org/resource/image/58/fc/5864c8cf80be5eff36141e55ebb229fc.jpg)
账务系统、查询系统以及消息系统处理的都是用户的点券数据。很显然,数据传输除了上图这种基于服务的实现方式外,还可以直接通过数据库。所以在实现的时候有两种不同选择,如下图所示:
![](https://static001.geekbang.org/resource/image/ed/18/ed1f9b5f6e586c38eebd94ba1e633f18.png)
## 支付系统
刚才我给你讲过了信息流和资金流一致的点券系统。但现实中,绝大多数支付业务场景是资金流和信息流不一致的情况。所以你必须知道,什么样的架构系统,才能处理好信息流与资金流不一致的情况。
接下来我们来看一个典型的例子——电商公司的支付系统。
电商公司一般没有第三方支付牌照,需要通过**支付系统**来对接第三方支付公司。支付系统负责的业务种类也非常多。我们讲讲最常用的业务,通过第三方支付完成的银行卡支付。
这个例子也和前面一样用户A用10元钱从用户B那里购买一支笔。区别是这次用户A用银行卡付款而不是用点券。
在推导系统架构之前,我们照例先做业务分析。银行卡是属于用户所有的资产,电商公司没有权力处理。所以银行卡这个资产只能通过第三方支付公司进行操作(其实是通过第三方公司背后的银行及卡组织)。
另外第三方公司提供的API接口都是异步的。异步接口除了常见的成功和失败两种状态外还有第三种状态那就是**不确定状态**。这就意味着点券系统到支付系统的架构演进其实是从同步系统到异步系统的演进。
我们还是按照业务流程逐步分析看看基础的4个系统之上还缺了哪些功能需要增加哪些组件。
和点券系统一样业务系统还是照例发起一笔支付订单给支付网关用户A将银行卡上的10元转给用户B。不同点在于支付网关在收到这笔支付订单后需要判断支付系统能否独立完成资产的转移。点券这种内部资产是可以内部解决的但是银行卡属于用户是外部资产支付系统不能自主解决。
所以**支付网关还需要实现路由能力**,将内部资产和外部资产两种操作,分发给不同的资产处理组件。因此,这里我们还需要增加内部和外部资产管理系统两个组件,如下图所示。
左边是前面介绍的点券系统的架构图,你可以对比看看:
![](https://static001.geekbang.org/resource/image/06/a4/0663181fd1bc906f68e88ba9c39ab9a4.png)
外部资产管理系统需要对接第三方支付公司来完成银行卡转账业务。这个对接任务通过**金融网关**来实现。金融网关主要是实现二进制协议的对接,比如证书签名、加解密、协议传输、数据校验等。
通常金融网关会对接多家第三方支付公司或者银行。这样当一家支付公司临时连接不上时可以切换到下一家,或者当一家支付公司费率相对较优时可以临时切换。选择哪一家支付公司来对接的过程也叫作**路由**,通过当前情况智能选择路由的过程叫**智能路由**。因此,架构图上需要再增加一个金融网关服务:
![](https://static001.geekbang.org/resource/image/23/84/2398ce23cc4ecd090a15ac57f9dbd384.png)
需要注意的是,金融网关和第三方支付公司之间走的是异步通讯协议。前面讲过,异步通讯有额外的不确定状态。那架构上应该如何处理呢?
不确定状态的处理方法分为两步。第一步是在规定时间内重复查询支付状态,一般把这种行为叫作**轮询**。我们在前一节课提到的用户App通过轮询来获取支付状态这是同一个道理。
规定时间内的轮询如果失败,支付过程并不一定失败,我们还有补救的机会。每天晚上电商公司会有一个与第三方机构进行对账的机会,在这个时候双方会对白天所有交互的明细进行对比,查漏补缺。
**这就是异步系统对接时的架构设计原则,需要将同步系统的一次调用拆分成三个步骤:异步调用、轮询和对账。**
我们在这里温习一下前面讲过的信息流与资金流的分离。在电商的场景下,电商支付系统的外部资产管理系统处理的是信息流,金融网关对接的第三方支付公司处理的是资金流。信息流和资金流分离之后,两者的状态就不再一致。
**所以从信息流系统角度来看,资金流系统会存在不确定的状态,这就是为什么除了成功和失败以外,会出现第三种状态的原因。信息流和资金流虽然分开了,最终它们还是需要同步,因此需要通过轮询和对账这两种方式来实现同步。**
**这就是由支付业务原理所推导出的系统架构设计原理。**
最后我们还需要把剩下的一些关键组件补充完整。你会发现上面的架构图无法保存信息流的相关信息,所以也无法处理和资金流的同步。
信息流是通过记账方式来保存的,因此我们还要加回账务系统。这个账务系统和点券系统的账务系统功能类似,但是覆盖面不同。更新后的架构图如下:
![](https://static001.geekbang.org/resource/image/1a/fe/1a149ebc5f1ba4ae13350fde3becaffe.png)
其实到这里还没有结束。我们在前面提到过如果轮询失败,需要在晚上与第三方支付公司进行对账。这个对账的任务一般是由**核算系统**来完成的。除了和第三方公司进行对账之外,核算系统还需要核对账务系统与业务系统之间的一致性关系。
添加了核算系统的架构图如下:
![](https://static001.geekbang.org/resource/image/7b/c6/7b160549yya22143b3acefcd5d39d6c6.png)
支付系统大的架构演进到这一步,就基本上能满足电商公司常用的支付需求了。
## 第三方支付系统
最后我们来重点讲讲第三方支付系统。第三方支付系统和电商公司的支付系统的核心组件都差不多,主要是因为它们俩都不能管理实际资金,因此都是信息流的处理系统。
电商公司会通过支付系统将信息流交给第三方支付系统处理。第三方支付系统会将这个信息流再转交给银行处理。在做跨境交易的时候我们甚至还能看到不同国家第三方支付公司之间的彼此合作。
那相同的地方我就不复述了。这里我重点讲三点不同,分别是流量支持、资金池和清算系统。
### 系统的流量支持
第三方支付公司有很多家客户,有可能会面临非常大的支付流量。举个例子,比如第三方支付公司负责代发工资或者代缴水电费,一到月底就会面临非常大的流量。
除了这些可以预测的高流量外,第三方支付公司还可能会面临电商促销这种非常突然的高支付流量。所以第三方支付公司需要有能力处理这种常见的互联网应用高并发问题。
这里就是金融系统架构和互联网架构结合得非常好的地方。应对高并发场景,互联网有非常成熟的解决方案。比如我们前面提到的异步消息处理,就能削峰填谷,降低峰值流量的压力。
如果流量再高,还可以选择熔断降流等手段来进行服务降级。如果存储能力支撑不了这么高流量,还可以使用各种不同的缓存技术降低查询操作对数据库的压力,或者使用分库分表的方式来进一步降低每个数据库上面的压力。
### 备付金资金池
第三方支付公司在调用银行接口的时候会产生费用。我接下来给你讲讲如何利用**备付金资金池**减少一些交易费用,同时还能提高用户体验。
**资金池**是一种常见的用户资金管理手段。资金池就是将属于用户的钱都放在一个大的池子里。池子里的钱不分你我,你是将资金池看作一个整体来操作的。但是你还留着一个账本,上面记载了每个人原来在资金池里放了多少钱。这样虽然钱是混在一起,但是账面上是清楚的。
资金池有很大的资金挪用风险,因此金融业对资金池的设立有很严格的监管。一般有了支付牌照之后,第三方公司才可以建立用户的备付金资金池。备付金资金池是一种新的金融产品,因此也需要新的系统组件来支持。下面举两个简单的例子。
你在用第三方支付公司App的时候应该见过一种叫作余额或者钱包的东西。你可以将银行卡里的钱转到余额账户。之后就可以直接使用余额里的钱。但是第三方支付公司并不一定会将你和我的余额分开存储很有可能是放在一个资金池里处理。
比如下图展示了一种资金池的管理方式。ABCD四个用户在第三方支付公司都有自己的余额账户。但是这4个余额账户并不是实际存在的只是4个虚拟账户而已。真正的钱其实还是存在第三方支付公司在银行的账号里。
![](https://static001.geekbang.org/resource/image/be/25/be88d0a71c6f72500091a641157e5b25.jpg)
第二个例子是第一个例子的升级版。我们在上一节课说过外汇市场是一个一个有层级的市场。资金池也一样,多个资金池也可以拼成一个更大的资金池。于是第三方支付公司可以在多家银行开设很多资金池账户,所有这些资金池账户的钱形成更大的资金池(监管机构正在逐步限制这种行为)。
当把资金池分散在多家银行之后,第三方支付公司就不再受制于单独某家银行。这样就可以利用不同银行的费率情况来进一步降低运营成本。
举个例子,比如跨行转账需要多家银行之间配合,还可能需要支付一定的跨行交易费用。但是如果第三方支付公司在每家银行都有资金池,就可以直接在两家银行内部完成用户资金和资金池资金之间的操作了。
利用资金池来优化跨行转账的例子也有升级版。在进行跨境贸易的时候也可以使用多个资金池来降低交易成本,但这不是主要原因。跨境转账一个不太友好的问题是时间非常久,需要好几天才能到账。这时候如果你在每家银行都有资金池账号,跨境转账问题就变成多个银行内部转账的问题了,这样就能实时到账,大幅提升用户体验。
备付金资金池要求账务系统有层级式的账户体系,并且有相应的账户和资金操作。升级版的资金池看起来是下图这个样子:
![](https://static001.geekbang.org/resource/image/31/c7/3164a667b2cebc2c1dfcd9a6fc3cd8c7.png)
### 清结算能力
清结算中心处理的是多家银行之间的跨行转账。当第三方支付公司有了多个资金池之后,这些资金池之间的转账关系其实和跨行转账一样。既然是一样的,那么第三方支付公司有没有可能做一些清算公司的事情,从而进一步降低交易成本呢?
的确如此。所以成熟的第三方支付公司内部都会有一个自己的清算中心。这个清算中心把自己当作一个外人,对资金池之间的转账交易进行清结算工作。这里要注意清算中心的**结算过程涉及到资金流操作**,需要通过内部支付网关来操作外部资金。
这样我们就把第三方支付公司最后一个组件补完了。现在的架构图如下:
![](https://static001.geekbang.org/resource/image/8a/96/8af65eca509df8c3e97171a0206ce096.png)
跨银行备付金和清算中心合在一起后,第三方支付机构就具备了跨行清算的能力。由于这种业务模式不容易监管,容易出现洗钱等非法行为,国家已经逐步取消了这种资金管理模式。
但是清算中心这个组件还是保留了下来。尽管不能再进行跨行清算,不过有了清算中心之后就有了清算的概念,这让一些常见的内部信息流和资金流处理的方式变得更加清晰。
这个例子告诉我们,由于监管条例在不断完善,支付业务和系统架构也要随之改变。比如你在欧洲从事第三方支付业务的时候,很有可能会碰到欧盟制定的“通用数据保护条例”,这就要求你对系统架构的信息存储做进一步的划分。因此我们在设计支付系统的时候,需要根据当时当地的监管条例合理选择架构。
## 总结
这节课我们一起梳理了支付业务逻辑最终推导出C端支付核心组件。
C端支付需要解决的**核心问题是信息流与资金流分离。**我们先分析了最简单的点券系统,这种系统信息流与资金流不分离。点券系统需要账务系统来对点券这种资产进行管理,用户需要通过支付网关来对接点券系统。
那资金流与信息流分离的系统又是啥样的呢?电商的支付系统就很有启发性。点券系统需要处理的同步消息,支付系统则需要处理异步消息。所以支付系统除了需要复用点券系统的核心组件外,还需要核算系统来保证异步消息的正确处理。
有了前面的基础,再去分析第三方支付系统的核心组件就很容易了。第三方支付在业务上需要用资金池来降低业务成本,因此在架构上需要有核心组件来对资金池进行操作,同时也需要用清算中心来简化资金池操作的优化管理。
这节课的知识点整体的结构图如下:
![](https://static001.geekbang.org/resource/image/f6/f4/f6d7505c9130494yyd60753cfcee4df4.jpg)
## 思考题
现在跨境电商越来越普遍了。通过跨境电商,一位中国买家可以购买一支在美国销售的铅笔,这时买家付的是人民币,但是卖家收到的却是美元。
假设支持外汇业务的第三方支付公司自己拥有大量的人民币和美元储备,可以在外汇支付过程中充当买家和买家共同的对手方,即买家的人民币支付给电商公司,随即电商公司把自己拥有的美元支付给卖家。
那么为了支持外汇业务,支付公司的架构应该怎么做调整呢?
欢迎留言和我分享你的想法,也欢迎你把这篇文章分享给你的朋友,一起交流和讨论支付系统的问题。