作者:李艳鹏,现任蚂蚁金服高级技术专家,著有《分布式服务架构:原理、设计与实战》和《可伸缩服务架构:框架与中间件》,曾经在易宝支付、花旗银行、甲骨文、新浪微博、路透社等大型IT互联网公司担任技术负责人和首席架构师的工作,现专注于区块链平台的研发与推广,擅长大规模高并发的线上与线下相结合的第三方支付平台的架构规划与实施。
在金融支付行业,资金底线的打法是至关重要的,保证资金不发生损失是任何一家金融支付行业的第一要务,这也是最困难的一个任务之一,一家支付公司每天的支付流水就有几亿、十几亿,甚至几十亿到上百亿、上千亿都屡见不鲜,在这样大的资金流水面前,我们应该如何保证资金万无一失呢?
大家应该都听过骑士资本(Knight Capital)的故事,这家美国股市经纪商因为错误的交易头寸造成4.4亿美元的税前损失,后来骑士资本的股价下跌63%至2.58美元,使得其市值缩水至2.53亿美元,只有几天前的四分之一,随后股价再次下跌17%至2.14美元。而这一事件是由骑士资本一个小小的“技术问题”所引起,致使它向交易所发出了错误的股票交易指令。
因此,如果我们做的是金融的交易系统,保证资金安全是底线,保证了资金安全,我们才能谋取利润,谋取利润能够让我们的公司活下去,接下来要让我们的盈利模型进入批量模式,我们才能将公司做大、做强。
资金损失和资金底线
我们如何来定义资金损失呢?凡是从事金融支付的活动的过程中,由于人为或者系统导致的资金亏损,都叫做资金损失。例如,在一笔电商交易过程中,发生了平台单边,支付未成功,但是通知用户订单成功,并发货,这是一个典型的由于平台单边引起的资金损失。
采取的客观的和主观的方法来保证不发生资金损失,就是资金底线防火墙,我们把这些方法称为保证资金底线的方法。资金底线是一个非常专业化的非主流概念,从百科或者其他的渠道是找不到官方定义的,我们通过举例来说明帮助读者理解资金底线,例如,我们通过对比支付成功通知和原支付信息中的ID和金额来保证不发生单边,就是保证资金底线的一个典型案例。
在本文后面部分,我们会聚焦在第三方支付行业的资金损失的风险和资金底线防火墙的建设。
从支付业务划分资金底线风险
在第三方支付行业,通常通过资金的流向把业务分成收单和出款,这里我们分享可能存在的收单和出款的资金底线风险的场景。
收单的资金底线风险
收单业务是第三方支付的主要业务之一,由于收单业务可以结合多种交易场景,因此,也是最赚钱的一种业务,具有交易量大、风险性高的特点。
单边是收单业务中最典型的资金底线风险,单边这个词汇来自于财务行业,在收单的结算流程中,很容易出现一种“单边账”的情况,单边账:即一方的账目发生变化,而另一方没有,那么随之而来的问题就是,钱去哪儿了?
这个场景又进而分为长款和短款两个情况。
- 长款:上游给我的款项比我给下游的多。
- 短款:上游给我的款项比我给下游的少。
我们看到长款实际上是我们的资金比账目多了,实际上没有资金损失,单边账有百分之九十九点九九是长款,如果出现了短款情况,那就是灾难,也是最严重的资金底线风险,是我们应该要坚决杜绝的。那么我们在第三方支付平台上,所说的单边通常指的是财务行业里单边账的短款,也就是导致了我们有资金损失的那个情况,因为工作在第三方支付的小伙伴们都不是财务专业或者对财务不熟悉的,所以,大家都把单边账的短款成为单边,这里我们也按照这个习惯来讲解。
下面是一个典型的第三方支付收单的示意图。
第三方支付的系统上接商户系统,下接银行系统。由于其处在承上启下的位置,因此,是最容易产生收单单边的资金底线风险。
简单的来说,产生收单单边资金底线风险的情况都是下游系统失败了,但是由于某种原因,典型的就是系统bug,返回给上游系统成功,如果上游系统是商户的电商系统,有可能已经发货了,这就导致了资金损失。
我们从系统层次上将单边分成以下3种类型。
- 第三方支付的系统与银行之间的单边。
这种单边发生在第三方支付系统与银行之间,由于某种原因银行系统支付失败,但是第三方支付系统支付成功。
- 第三方支付的系统内部的单边。
这种单边发生在第三方支付内部的系统之间,由于某种原因第三方支付的底层系统支付失败,但是上层系统支付成功。
- 第三方支付的系统与商户之间的单边。
这种单边发生在第三方支付与商户系统之间,由于某种原因第三方支付的系统支付失败,但是商户得到了支付成功的通知。
对于以上3种情况,都是我们要坚决避免,或者及时发现进行止损的。
另外,还有两种特殊的单边场景,一个叫做金额单边,一个叫做订单号重复单边。
- 金额单边
订单在银行实际支付金额小于第三方支付的订单金额。
- 订单号重复单边
上层交易系统的多个订单对应银行子系统同一个订单。
出款的资金底线风险
出款业务也是第三方支付的重要业务之一,具有体量大、单笔交易额高的特点,出款业务更容易产生资金底线风险,如果不加以防控,发生重复出款、多出款、出错款也是家常便饭。
具体的资金损失的场景如下。
- 重复出款
一笔订单出款多次,造成了成倍的资金损失。
- 多出款
一笔订单总共出款金额大于订单金额,大于部分的资金就是资金损失。
- 出错款
一笔订单出款给其他商户。
- 未扣账出款
没有从商户账户扣账,资金直接从备付金账户扣除并转出给商户账户或者对公银行卡。
从时间上划分避免资金底线风险的方法
我们从发生资金底线的时序上总结避免资金底线的风险的方法,这些方法放在一起构成了资金底线防火墙。
事前避免
根据经验,分析发生资金底线的风险的场景,阻断场景发生的必要条件,避免这种场景的发生。这种方案是最好的方案,也是最难实现的一种,一般都是通过总结历史线上事故,找出发生的典型的资金风险场景,针对场景的特点设计避免方案。
例如:在一笔支付做完后,将资金入账,入账的时候通过渠道查询支付是否成功,如果不成功,讲拒绝入账。
事中拦截
事中拦截是一个非常重要的避免资金损失的方案,就是在支付过程中,通过支付的特点来识别是否发生了资金底线风险,如果识别到了,则可以及时拦截,不让事情进一步恶化。
例如:渠道在收到银行返回的支付成功通知的时候,会检查返回通知里面的成功支付金额是否与支付订单一致,如果一致再向上通知。
事后止损
对于某些场景,我们通常没有办法完全事前避免和事中拦截,在这种情况下,我们通常通过对账、监控等手段发现问题,并且事前预设止损的运营功能,一旦发现问题即使止损。
例如:我们通过监控手段得知某个渠道的成功率偏低或者偏高,然后进行报警,通过运营决策可以关掉某个渠道。
主观方面避免资金损失
很多时候一次比较大的资金底线事故都是人为因素导致的,经常是用人来把关的多个阶段都被忽略了才导致最终的“惨案”,这也难怪,我们是人,不是神,每天都收到生活、家庭、工资、心受伤的程度等各种因素的影响,偶尔开个小差是不可避免的。
主观方面避免资金损失主要是通过对人的分析和采取策略,来避免资金损失。在笔者工作的几年里,一直负责资金底线风险的任务,笔者通过两个重要的主管上的方案来避免资金损失。
- 定期的对小伙伴宣讲资金底线保护的重要性
笔者多次对新员工、小伙伴们进行资金底线的培训,一方面汇报资金底线项目的进展,之前发生的资金底线的事故的案例分析,并提醒小伙伴在设计中首要考虑资金底线的事情,我常常对小伙伴说:一个业务或者功能上线,可以不好用,可以不赚钱,但是不能损失钱。
- 设计评审中要增加一项资金底线的评审项
笔者在过去的几年里一直评审支付平台的架构设计,凡事经过笔者评审的方案,笔者都会引导小伙伴来思考是否有资金风险,对可能的资金风险怎么应对,经过笔者评审的方案,鲜有有资金风险发生。
客观方面避免资金损失
尽管我们可以通过主观方面的培训、设计评审提醒大家要有资金底线保护的意识,但是,由于我们每个人员包括测试人员每天的状态不一样,情绪不一样,那么表现也不一样,因此,我们不能完全仰仗人来保证资金底线,我们应该寻找能搞保障资金底线的客观规律,把这些客观规律做到系统中,这样就能保证系统的资金是无法撼动的。
我们总结有一下多种方法。
- 支付、渠道和账务的三角校验
前面提到一个案例,在一笔支付做完后,将资金入账,入账的时候通过渠道查询支付是否成功,如果不成功,讲拒绝入账,通过这样的一个客观的支付、账务、渠道三个系统的三角闭环校验可以避免资金损失。
三角校验如下图所示。
- 通知和渠道的首尾核对
第三方支付系统与商户交互的系统是通知系统,与银行交互的系统是渠道,通知和渠道是系统上下的两个边界,把控住两个边界不产生单边是非常重要的任务,这可以通过首尾核对来保障。
首尾核对的示意图如下。
- 渠道与银行的核对
支付成功银行通知第三方支付后,第三方支付的渠道系统实时反查银行比对状态和金额的查询。有些银行由于设计问题不支持实时查询,则可以退而求其次,增加一个分钟级异步核对与银行之间的核查机制。
- 渠道成功率监控
对于渠道的成功率太高或者太低的情况进行监控,能够防止系统bug导致的不该成功的支付都被认为成功了的情况,这个监控也是至关重要的。
- 自动化的底线防火墙
人总是受到各种环境的影响,完全靠人来保证代码质量并不是万无一失的,所以,我们应该寻求自动化测试方案,实际上第三方支付的产品形态主要是API产品,非常适合进行自动化测试,因此,我们要寻求两个方面的自动化,一个是测试用例要自动化管理,不断的积累测试用例,对测试用例进行分级,哪些是业务测试用例,哪些是资金底线测试用例,资金底线测试用例要在上生产环境之前的内侧环境进行测试,而且应该由系统自动触发,最好集成在devops的上线流程中,不可跳过,如果这部分的自动化的资金底线测试失败,不允许上线。
下图中,我们看到内侧环境我们构建了一个自动化的底线测试防火墙。
- 渠道的试运营
通常资金底线风险放生在渠道系统,因为渠道系统总是要对接新的银行渠道,常在河边走,哪有不湿鞋,因此,在新渠道上线的过程中,一定要保证有试运营的阶段,是运营要认真观察支付的结果,并且要有足够的时间,至少要到第二天看到银行的清算文件和对账文件,与真实发起的交易一致,才能认为新渠道上线是成功的。
- 万无一失的资金对账
资金对账是第三方支付必不可少的一个保证资金安全的方式,主要是通过第三方支付的信息与银行之间的对账,通常银行回提供清算文件和对账文件,清算文件记录的是第三方支付做过的所有交易名气,对账文件是银行提供的备付金账户资金的日初和日末的账户余额,通过这两个对账文件,一个代表信息流,一个代表资金流,就可以讲所有的资金对清楚。
- 具体到责任人的底线验收
对于重要功能上线,一定要制定负责人,负责人要对资金底线负责,功能上线之前要验收,这里一定要秉着负责到底的原则,不要大家都负责,结果大家都不负责,除了问题大家都帅锅,谁负责,谁做底线验收,上线成功谁获得最高的回报,只有这样才能保持一个良性循环,才能激励大家对事情的负责态度。
- 系统间一致性核对
在第三方支付系统中,由于业务复杂,通常会使用分布式架构或者微服务架构来实现系统,一个流程依据功能被分散在多个系统中来实现,那么每个系统中都有自己的支付状态,各个系统之间如何协调一致呢?这就需要系统间一致性核对,也就是系统内的任何两个相邻的系统都需要进行核对支付订单状态。
执行资金底线保护任务的方法论
如果你足够幸运在你所在的支付公司里负责资金底线保护的任务,那么恭喜你,只有关键核心的人才能做这份工作,但是,还有另外一个说法,这个工作其实是费力不讨好的,做好了是应该做的,做不好那都是你的责任,不管怎么样,事情还是要做好。
如果你接到了这个任务,感觉无从下手,那么请看下面的方法论。
- 回顾以前发生的所有资金风险的案例。
- 梳理可能发生资金风险的所有场景。
- 根据发生资金风险的案例和场景,形成避免、拦截和止损的方案。
- 做计划和跟进方案的实施。
原文地址:http://blog.51cto.com/robertleepeak/2095023