目录
一 支付系统历史与演进
二 支付系统基本概念
三 支付系统简介
四 订单与支付
五 总结
支付是指为清偿商品交换和劳务活动所引起的债权债务,货币债权从付款人向收付人的转移的过程。支付能力是电商产品的核心能力之一,作为订单同学,有必要了解关联域支付的流程以及基本概念,同时支付领域的很多设计思路与资损防控经验对订单域的系统设计也很有借鉴意义。本文将从支付系统的历史、基本概念、系统设计、资损防控与订单与支付交互等方面予以介绍。
支付的历史演进可以追溯到现金交易的起源。随着时间的推移和科技的不断进步,支付系统经历了多个阶段和变革。
起源:票号与钱庄
票号是应埠际汇兑需求而开设的金融专营机构,主要经营存款、汇款、汇兑三大基本业务,是现代银行的雏形。客户在票号交了银子之后,票号就开出汇票给客户。客户可以随身携带汇票而不用携带大量的银子,只要凭票就可以到全国各地的分号兑出银子。分号给客户兑换之后先内部记账,各分号间定期会当面进行对账。镖局就专为票号来运送银子、为商人运送票据。在这种模式下,汇票+账本(手工记账)是票号在支付环节的信息载体,解决了信息流问题;镖局替票号运送资金,解决了资金流的问题。
第一阶段:手工联行(1989前)
早期,国内的金融环境没有达到让央行推行全国统一结算制度的客观条件。于是央行当时提出商业银行要“自成联行系统,跨行直接通汇,相互发报移卡,及时清算资金”。同一家银行的总行及分支机构称为“联行系统”。同一联行内的资金结算,由联行总行自己做。跨行业务可以由央行清算,也可以由商业银行自己清算。在这种模式下,各银行需要告知其他行的交易信息构成了特定的公文,加盖印鉴后在银行间传送。这种公文叫做联行信件,而当时的邮电局则承担了收发联行信件的重要业务。
联行信件整个过程基本都是手工处理,与明清时期的票号相比,并没有太大的改进。虽然运行成本较低,但容易出现差错,且资金汇划效率依旧不高,导致占压在途结算资金较多,如异地间资金的汇划,少则 10 多天、多则半年才能完成资金到账。
第二阶段:电子联行(1989~2005)
1990 年,中国人民银行清算中心建成,专门为金融机构提供支付清算服务。清算中心包括 NPC(National Process Center,国家金融清算总中心)和 CCPC(City Clearing Processing Center,城市处理中心)。1991 年 4 月 1 日,全国电子联行系统(EIS)开始试运行。EIS 是基于金融卫星通讯网的,它是人民银行专门用于处理异地(包括跨行和行内)资金清算和资金划拨的系统。它连接了商业银行、央行、NPC 和 CCPC。以一位上海招行银行卡的用户要给持有北京工行银行卡的朋友进行汇款,使用 EIS 完成一次支付清算的案例如下图所示:
借助全国电子联行系统,传票和凭证已变为加密后的电文,与纸质联行相比,进步巨大。客户的资金在途时间缩短到了一两天,大大提高了资金清算的效率,可以说是一个重要的里程碑。
第三阶段:现代化支付系统(2005~至今)
中国人民银行支付清算系统(China National Automatic Payment System)是为我国金融机构之间以及金融机构与人民银行之间的支付业务提供最终资金清算的重要核心业务系统,整体架构如下图所示:
简单介绍下该系统的几个核心子系统:
在现代化支付系统投产之前,即使是电子联行系统也需要一到两天才能能够到账,而现代化支付系统将支付后实时到账变为可能,极大的提高了支付效率,提升了消费者的支付体验。技术变革往往会带来新的商业机会和变革,推动企业进行创新。国内的主流电子商务与电子支付平台起也从 2003 年开始兴起,这里现代化支付系统的投产时间(2002年、2005年)非常接近,很难说两者之间毫无联系。
核心概念
支付系统一般指提供支付清算服务、实现支付指令传送及资金清算的系统,由有支付牌照的支付公司提供。支付系统是连接消费者、商户(或平台)和金融机构的桥梁,实现了支付、资金清算、查询统计等功能。这里系统的解释一下涉及到的相关名词,便于我们后文展开详细介绍。
常用支付形式
平台支付
用户提前注册并登录到第三方支付平台,并且已经在该平台上完成绑卡等操作后,通过第三方支付平台进行支付。
网银支付
用户在完成必要的银行网银开通手续后,可以通过银行的网银系统进行在线支付和转账。在进行网银支付时,用户需要登录银行网银系统,输入相应的支付信息并进行身份验证,然后可以完成在线支付交易,移动互联网时代较为少用。
快捷支付
一种简化了支付流程的支付方式。通常情况下,用户在首次支付时需要绑定银行卡或者进行一次认证,之后就可以使用该支付方式来完成交易,无需重复输入银行卡信息或进行繁琐的身份验证。在后续的支付过程中,用户只需进行简单的确认操作或者输入支付密码,就能够快速完成交易。
协议支付
协议支付也称代收或者代扣,代收指渠道授权商户可以从用户的银行账户中扣款,一般用于定期扣款,如水电煤气、有线电视费、包月/包年会员费等。
虚拟货币支付
不少公司会有自己的虚拟币,这些虚币也可以作为一种支付方式。一般会有一些金额、品类的限制,如虚拟支付不得超过每笔订单结算金额的 50%。
余额支付
为用户建立本地账户并使用账户来完成支付,账户支持充值、提现等操作。
信用支付
指使用信用账户进行透支,类似信用卡支付。需要较强的风控能力。
整体架构
在了解了支付系统相关演进与基本概念后,我们再来看一下支付系统的整体架构。对于订单同学来说,在实际支付业务的接入过程中,可以接触到两类支付系统:
第三方支付系统:即订单同学理解里的“支付渠道”。比如我们作为商户直接对接到微信、支付宝的支付系统中,从而具备支付收款能力。整个系统中的“核心系统”功能往往是大家最为熟悉的部分,它概括了我们平时各种消费支付场景。我们平时进行的电商交易、红包转账等都是“支付应用”的体现形式。
实践中,三方支付系统往往可以拆分为网关、金融交换、收单域、支付域以及账务域、会员域、营销域等多个领域。
聚合支付系统:即订单同学通常理解里的“支付”。主要功能为屏蔽各种第三方支付系统的差异性,提供统一的接入方式和支付产品,比如得物的汇金系统。
一个比较典型的电商平台的支付架构
支付流程
用户支付流程
从流量角度来看,对于一次用户发起的支付行为,请求首先达到支付网关,经过必要的安全验证和流量限制后,被转发给对应的支付服务模块。随后用户跳转收银台页面选择支付方式后确认支付,由支付系统对接银行/第三方支付机构的支付接口进行后续的支付。
支付接口
以业内某支付产品为例,其提供了多种集成支付能力的方式,其中「手机网页支付」适用于商户无独立 App,通过移动端 H5 网站进行传播的方式。我们以一次手机网页支付为例,了解支付的核心接口。
如上图所示,可以从交易支付的几个环节进行分析。
支付接口
在商户的 H5 网站下单并确认支付。
商户系统生成订单信息并构造支付请求发送到该支付产品系统。
系统校验通过后拼装本次支付所需参数返回给商户前端。
商户前端将页面跳转至该支付产品官方中间页,如果用户手机上安装了该支付产品 App,则自动唤起 App;如果未安装,则继续在当前页面进入官方 H5 收银台。
用户完成密码输入并支付。
系统内部完成本次支付单处理流程。
处理完成后,以异步消息形式通知商户后台 Notify_URL,确认此次交易成功。
处理完成后,从官方中间页跳转商户自定义支付结果页 Return_URL,展示支付结果。
完成本次支付。
交易关闭接口
针对需要的业务场景,支持主动取消订单(针对未支付订单,已支付单可走退款流程)。
用户发起/商户后台管理员发起订单取消申请。
商户系统向该支付产品系统发起关闭订单请求。
后台判断处理后返回取消结果。
交易查询接口
商户后台发起交易查询请求。
系统判断交易单存在,并返回交易结果。
退款接口
用户/商户发起退款请求
商户系统审核处理退款申请是否合法。
合法情况下,商户系统向该支付产品系统发起退款请求。
系统处理并返回结果。
相关渠道将资金返回(有一定时间延迟)。
退款查询接口
用户/商户发起退款查询请求。
系统处理后返回结果。
下载对账单接口
商户系统根据业务对账需要,发起对账申请,查询最新的对账单下载地址。
系统返回对账单下载地址。
商户系统根据对账单下载地址下载对账文件。
系统返回对账单文件。
资金流与信息流
央行在 2017 年 8 月发布《关于将非银行支付机构网络支付业务由直连模式迁移至网联平台处理的通知》,规定了非金融支付机构受理涉及银行账户的网络支付业务全部通过网联处理。目前业内采用的都是“间连”模式提供网络收单服务。这里以一次银行卡网络收单支付交易流程为例,整体资金流与信息流如下:
【信息流】步骤 1 用户通过电商支付收银台下单并支付,电商支付处理支付业务数据,并将支付请求发到第三方支付渠道。
【信息流】步骤 2 第三方支付将请求转发至网联。
【信息流】步骤 3 网联将支付扣款请求转发到发卡行。
【资金流】步骤 4 发卡行从用户银行卡扣款,用户银行卡金额减少,返回支付成功给网联。
【信息流】步骤 5 网联记录支付成功数据,返回支付成功给三方支付。
【信息流】步骤 6 三方支付回调电商支付系统,更新支付状态和记录支付信息。电商支付回调订单系统,更新订单状态,给用户返回下单成功。
【资金流】步骤 7 网联周期性对三方支付业务做清结算,通过央行清算系统做资金清算划拨到三方支付机构备付金托管所在银行。
【信息流】步骤 8 三方清结算服务对货款商户支付交易记录做清算和结算,具体细节如下:
清算服务根据交易要素对商户主体交易按照约定的计费规则进行清算,记录商户主体因为商业交易而产生的债务债权,周期性生成对应的结算凭证。
结算服务按照约定结算周期和方式对商户主体产生的债权债务进行清偿,请求网联结算打款。
【资金流】步骤 9 网联通过周期性清结算方式形式做资金划拨到商户收款所在银行。
【信息流】步骤 10 商户结算收款银行账户显示货款到账。
从上图看,步骤 1 到步骤 6 体现了付款方付一笔钱的流程,表示了三方支付一笔收单业务的信息流和资金流,其中步骤 4 中付款方的银行卡余额会被实时扣减,发卡行侧记应付未付。步骤 5 网联记录支付交易相关数据作为跨行清结算业务的依据。步骤 6 三方支付侧更新支付交易结果并逐层通知至订单系统,同时把支付成功消息同步给三方的清结算,清结算依据交易支付的结算要素做清分分录,记录商户应结资金和应收手续费。步骤 7 属于资金流。由网联负责跨行周期清算,网联通过央行清算系统完成资金划拨后资金到了三方备付金账户。步骤 8 属于资金流。三方支付完成周期性结算凭证生成后通过网联发起结算打款,最终资金到账时间依赖于网联清算+资金划拨的时间。自此,一笔电商交易经过用户银行卡扣款、网联清结算、三方支付清结算,最终实现钱货两清。
资金结算
清结算是对交易支付数据进行全面整理、计算、汇总、检查核对和最终结算的过程,可拆分为清算和结算两个子域。清算域服务根据交易推送的信息,按照约定的计费规则进行清分、汇总,记录主体因商业交易而产生的债务债权,并定期生成相应的结算凭证。结算域根据约定的结算周期和方式,对商户主体产生的债权债务进行清偿。清结算确保了金融交易的安全性和准确性,保障各方权益。
抽象的来看,支付涉及业务主要可分为收、付、退、提、转、充等 6 大类(对于订单同学来说更关心的是收、付、退三大功能,对应订单的购买、履约、售后三个子域)。资金结算一般分实时结算与定期结算,我们以定期结算为例,分析整体资金结算的简版流程。
计费
计费为通过对应的计费规则将业务流水消息转换为清结算的资金语言,生成对应的结算资金明细。
匹配 以交易业务的流水信息路由匹配到相应的计费规则。
清分 根据计费规则,将资金划分给交易中的不同角色,生成对应的计费结果与资金分摊明细。简单来说就是算清楚哪个费用项,多少钱,谁给谁。
分录 落地计费明细与结算明细变更。
汇总
根据清算明细,按照资金指令以及时间段进行汇总操作。
校验
主要是对整个结算的模型、指令以及单据、任务的完整性校验,以及账务资金核对检查等,确保最终结算前的数据无误。
结算
生成账单并执行相应的资金指令,完成最终的资金转移。
资金安全
支付业务的资金安全主要可以从准确、合规两个方面理解:
准确
信息准确:即信息不错不漏不重。应对思路为流程上的容错机制以及核对来实现。
时机准确:即不早不晚,应对思路为核对以及监控预警。
合规
二清合规
流程容错
正如某些订单域内部的多种单据间存在关联关系一样,支付设计上也有单据间关联的设计。例如从流程上来说所有的逆向过程都必须持有正向的单据,因此退款必须要关联到原来的支付,退款支付单要关联到原支付单。单据之间的关联只要有以下用途:
状态一致性:正如订单域中的订单单据如果成功,则订单关联的营销单、支付单一定成功一样。支付场景的各个单据的状态也存在关联关系,例如创建退款支付单的前提是所关联的原支付单必须成功。
金额一致性:金额控制是退款的一个核心问题,控制不好很容易产生资损。由于支持多次部分退款,金额必须防止退超,这里包含两个维度,一个是总金额不能退超,一个是各个维度的资金组成组成不能退超。具体的做法是,每一笔退款的金额,都会在原单上累加记录到已退金额,记录已退款的总金额,校验不可超。
幂等
通过唯一键实现幂等是较为常见的实现方式。例如订单侧常见的重复支付退款是以订单号关联 PaymentNo 做重复支付校验的唯一键,支付侧交易单以外部单号 + 商户号为唯一键,支付单以交易单号 + 操作码作为唯一键。幂等可以有效的防止操作不重复,这里需要额外注意的是,幂等的可重入问题:例如对于一笔整单退的请求,上游请求退款 200 元,支付域已经处理成功,上游由于超时基于同一笔支付单号进行进行退款重试,此时应该返回成功而非业务校验异常。
最大努力通知是支付领域常见的流程容错手段,分布式环境下,网络抖动、服务暂时不可用等都会造成业务流程处理异常,常见的策略为将请求放入 MQ 进行异步重试,重试间隔逐次拉长,重试如果成功,则回调交易,如果失败或者处理中,则继续重试(所以接口幂等支持可重入很重要,对重试更友好)。
例如订单收到支付成功回调后,开始处理订单流程。如果在下单阶段仅锁定库存、营销等资源,需要在支付回调流程真正扣减资源的话,这里需要对超时等场景进行重试(调用下游需要做好幂等),如资源扣减失败则关单退款
重试指定次数如业务单据仍未到达终态,则将订单信息持久到数据库中,通知人工进行处理。
例如用户卡注销,会员销户等问题导致退款退不出去,重试一定次数后支付单只能置为失败。等待产运联系用户后,在支付层重新生成退款支付单进行退款。
核对
核对是保障资金安全的重要机制。从时效角度来看,主要有(准)实时核对与离线核对(如 T+1 核对),实时核对的准确性不如离线核对,且需要相应的实时核对平台建设(例如得物的 DCheck 平台)。离线核对主要的问题是发现问题的时机较为后置,部分场景会影响系统的时效性。例如清结算与账务侧的每日资金核对失败会影响结算时效性。
从核对维度来看,主要可以有如下几种核对方式:
资金在从业务端起点(数据由业务产生)到财务端终点(最终流入财务系统)中,在链路中的各个系统/表中都留有相应的凭证。例如交易一笔订单的实付金额对应着支付的一笔支付单的支付金额,商户一笔收单或支付退款会在对应的商户待结算户发生一笔动账,对应在清结算会做一笔有资金方向的清分分录。对这些金额我们可以建设相应的一致性核对任务进行核对验证。
一致性核对包括双向一致性核对和单向一致性核对两种,单向一致性核对无法发现单边数据缺失问题。
在特定的业务场景下,业务有自身的业务规则,可以针对这些业务规则进行校验。常见有以下四种方式:
一般正确性校验:例如某些支付业务只能用于特定的商品类型,则可以通过自定义SQL校验规则来进行校验。
总分校验:各个子金额汇总应当等于总金额。
顺序性核对:业务流程中有依次执行的处理流程,则可以校验是否有流程缺失。
幂等性核对:校验是否有业务被异常的重复处理,如重复退款等。
主要核对时效相关,如未支付的支付单在超时后是否及时关闭,结算时机是否满足时效要求等。
对一些可能有高风险的关键配置与金额相关额度进行校验,如分账比例 <=30%、不能负佣、总营销金额不能超过每日上限等。
总的来说,对实时性较高的任务采用实时核对,而日终检查等采用离线核对,通过对支付全过程的监控预警以及失败 case 产研及时介入处理,从而保证了资金安全的准确性。
资损攻防
也就是我们业内常说的混沌工程,通过注入故障可以有效的验证我们的系统是否足够健壮以及监控核对是否及时有效,常见的实现方式有:
通过模拟核心依赖超时等异常场景,验证容错重试流程是否可以正常工作。
模拟资损核心字段落库异常的场景,验证监控核对是否可以及时发现。当然也可以通过旁路攻击的方式,如修改数据库的binlog字段而非直接修改数据来查看是否触发告警,这样对线上业务的影响会更小一些。
二清
对订单同学来说,二清就是在下单时查询商户对应的支付二级商户信息并传递到支付与结算。那么什么是二清?二清合规问题是如何解决的?
首先我们通过几个案例来了解下什么是二清。
二清问题实际上可以分为“资金二清”与“信息二清”:
资金二清:指无证机构通过平台或大商户模式截留沉淀了应直接结算给二级商户的资金,再通过其他方式完成二次清算,实质性的控制整体结算资金。
信息二清:信息二清层面,监管不仅要求平台不能进行“资金二清”,同样也要求其提供的交易信息真实可追溯,且分账信息是商户真实意愿。
信息二清主要为了避免平台使用了合规的三方支付机构,虽然不触碰具体的资金结算,但掌握了原始的交易订单数据、分润信息和商户资金结算的入账规则,使银行或支付机构根据其提供的分账规则、指令为商户入账,实质上通过平台分账指令传输主导了结算资金的方向。
电商公司早期求生存是更主要的问题,在整体支付系统演进过程中,往往都采用二清的模式。这里面用于公司统一收款的账号我们称之为“大账户”。资金通过用户流向公司的大账户,在通过结算最终流向卖家。这里存在一定的合规风险:
资金挪用风险:平台代为几种收款,有擅自挪用的风险
资金监管风险:无证机构向平台入驻的商家结算资金,游离于监管体系之外
交易信息风险:无法保证平台提供交易信息的真实性,有伪造的风险
近些年随着监管越发成熟,电商公司因为支付不合规被责令整改的新闻屡见不鲜,随着公司业务规模的发展,二清合规问题也愈发迫切的需要得到解决。
对于二清问题,通常有两种解决方式:
通过申请或收购的方式获得支付牌照,使平台获得合法的资金清算能力(牌照较昂贵,成本较高)。
接入三方支付公司的二清解决方案(聚合支付系统需配合接入改造)。
目前得物采用的是第二种方案,我们以某宝的二清解决方案为例,简单介绍得物是如何通过某宝的互联网平台直付通产品解决二清问题。简单来说,得物平台上的二级商户需要入驻某宝成为某宝的商家,买家在得物的订单支付成功(支持多个商家的订单合并支付)后,某宝记录对应商家待结算资金,待平台确认可结算时,某宝将资金直接结算至商家指定的收款账号。同时支持平台按订单灵活抽取佣金(也就是我们常说的分账)。
这里面有几个核心的概念:
分账抽佣:可根据实际业务场景将交易资金分账到其他业务参与方的支付产品账号(例如:平台抽取佣金、其他方服务费等)。目前支持单个平台最多 20000 个参与方的分账,单笔交易订单 最高分账比例 30%。
结算:买家确认收货后,得物通过资金确认结算功能,将整笔订单结算给二级商户收款账号,最长账期支持 365 天,超过 365 天订单自动结算。
营销补差:平台举行平台出资的营销活动,如跨店满减、全场通用券等营销手段,资金结算后,平台向该支付产品发起补差指令,将营销资金补到二级商户的账号。
简版流程:
买家支付订单,订单触发分账,将钱转入卖家待结算户,此账户金额对卖家不可见
用户确认收款,得物平台发起结算指令,该支付产品将卖家待结算户的钱按照事先在该产品后台配置的分成规则进行分账。分别流入得物的该支付产品账户与二级商家已结算户,此时卖家就可以看到自己的账户余额增加了。
卖家将二级商家已结算账户的钱提现等操作。
当然这里还有一些撤销分账、补差等细节流程,这里就不做过多的展开了,感兴趣的同学可以阅读三方支付公司的二清解决方案相关文档。
得物订单与支付交互
由于监管 KYC 的要求,一笔支付单不仅需要支付相关信息的如支付方式、支付金额、支付有效时间等,也需要订单的买家信息、卖家信息、商品信息等等。这些信息客户端无法全部给到,且基于安全的角度,也不能由客户端通过公网传参的方式传递,需要订单域与支付域进行交互传递相关信息。目前得物支付提供了下单模式(业务方调用支付系统创建支付单)和反查模式(业务方实现 PayInfo SPI,支付系统反查业务方获取支付信息)两种模式,目前订单是按照反查模式与支付交互。
订单开发中常见支付相关问题
0 元订单
微信/支付宝等常见三方支付文档里有说明,支付金额 Total_amount 字段取值最小为 1(1 分钱)。因此如果 0 元订单还创建预支付单的话会失败。之前有订单域通过注册定时回调任务,伪装成一个收银台支付回调的方式来实现 0 元单回调,实践下来会踩坑(与实际业务流程不符,伪装的回调需要不停适配支付回调的改动)。正确做法是对于 0 元订单,只走创建商户订单的流程,并直接更新订单状态,不走支付回调流程。
支付订单过期时间设计
在电商交易系统中有两个过期时间的概念:订单过期时间和支付单过期时间。这两个时间会产生时间差的原因在于:用户在「确认订单页」点击「提交订单」就会创建订单并跳转至收银台,此时开始锁定库存并计时;而用户在收银台停留的时间是不确定的,这部分不确定时间造成了时间差。具体来讲,如果用户点击「去支付」创建预支付单时传递的过期时间是个固定值,那么就有可能会出现一种情况:在订单系统该订单已经过期失效了,但用户在支付平台内还能支付该笔订单(而此时支付成功回调订单系统,订单已取消,系统是不会进行后续发货流程的)。因此,支付单的过期时间要结合支付单创建当前时间和订单创建时间一起动态计算得出,保持一致,从而给平台用户提供更好的消费体验。
总的来看,了解支付系统有助于订单交易方向的同学理清上下游,更加全面理解电子商务四流中的资金流。同时支付系统在资金核对、流程容错方面有着非常经典的设计,值得我们去学习借鉴。