典型支付架构
-支撑层: 用来支持核心系统的基础软件包和基础设施, 包括运维监控系统、日志分析系统等。
-核心层: 支付系统的核心模块,内部又分为两个部分: 支付核心模块以及支付服务模块。
-产品层: 通过核心层提供的服务组合起来,对最终用户、商户、运营管理人员提供的系统。
支付应用:指提供给用户在特定场景下使用的产品,比如收银台、二维码支付、转账、打赏、众筹、POS支付、手机充值等。是建立在支付产品的基础之上,直接面向用户提供服务。
支付网关:对支付请求进行一些通用的处理,比如身份验证、验签等,然后根据支付请求的场景,调用对应的支付产品。
支付产品:由支付系统对支付渠道进行封装,根据其支付能力为业务方提供不同的功能,比如网银支付(封装银行提供的网银支付来实现)、快捷支付(封装银行或者第三方支付平台提供的快捷支付接口或者代付接口来实现)、账户支付、平台支付等。一般支付产品需要提供签约、解约、支付、撤销、退款、对账、查单、短信验证等功能。
下图为支付产品需提供的功能
支付路由:支付产品通过支付路由将支付方式根据渠道费率、接口稳定性等因素选择合适的支付渠道来落地支付。(目标:省钱、支持营销、降低运营成本、提升支付产品的QOS)。
支付渠道:对支付接口的一个封装,通过调用银行、第三方支付等渠道提供的接口来执行支付操作,最终落地资金转移。渠道方有两个接口,分别是同步接口和异步接口,同步接口仅检查参数是否正确、签名是否无误等,返回结果为调用结果。异步接口返回扣款结果。
账户账务:外围业务系统的账户系统,主要记录每一条财务交易流水,采用单式记账法。
会计:日切、会计分录流水,采用复式记账法。
核算:对账、归档。
支付宝架构
支付宝的架构有两个优点,一是账务处理,分为内外两个子系统,外部子系统是单边账,满足线上需求;内部子系统是复式记账,满足财务需求。二是柔性事务处理,利用消息机制来实现跨系统的事务处理,避免数据库锁导致的性能问题。
其他系统组成
账户账务系统
账户分为登录账户和支付账户,一个用户可以有多个登录账户,一个登录账户可以有多个支付账户。
账务负责记录每笔交易的交易收付记录。
-登录账户:用户在系统中登录的凭证和个人信息。
-支付账户:用户在支付系统中用于交易的资金所有者权益的凭证,比如零钱账户、储值卡账户。支付账户一般要包含以下设计需求:
交易的需求:比如检查账户是否被锁定、余额是否足够、是否有效等。
记账的需求:按照公司会计需求记录账户上的所有行为,包括支出、充值、转账等。
对账的需求:包括支付渠道、商户、个人的对账需求,核对交易和账户余额是否正确。(主要是交易记录和退款记录)
风控的需求:如反洗钱、反欺诈等,都需要依赖于账户体系来提供核心数据。
信用的需求:对用户、资产、商户等主体进行信用评估时,也需要依赖账户体系来提供的核心数据。
订单系统
支付订单详情和状态。
会计系统
按照企业会计分录流水记账,记账采用复式记账法。
(账户系统是提供对外客户的账户支持,客户的查询余额,账务明细均来自于此;会计系统是为了内部核算管理的需要而设立的,所有的银行资金清算与结转都需要会计系统的支撑,内部户与外部户的资金核算管理也需要会计系统,两个系统相互依赖,账户系统是会计系统的前置。)
清结算系统
交易清分:算出给每个账户打多少钱,同时从每个账户收多少钱;
交易结算出款:调用银行/通道代付接口,自动出款。
对账:核算通道与支付系统的应收应付。
通知系统
通知账户系统支付结果、订单系统修改订单状态、账户账务系统产生一条账户流水记录(明细账)(账户账务系统记账完毕后,定是以批量文件的方式发给会计系统,会计系统产生会计分录流水。)
1, 商户通过后台调用第三方支付的接入层进行下单,第三方支付返回预下单id给到商户后台系统,商户后台系统在前端调起支付应用(收银台),用户输入授权信息后,调用核心支付系统。
2, 核心支付系统根据用户选择的支付方式(支付账户或者银行卡)选择不同的支付路径。
3, 如果是选择支付账户支付,则调用账户系统对用户的账户进行扣款。
4, 如果是银行卡支付,则调用对应的支付产品来执行支付;支付路由根据支付工具、渠道费率、接口稳定性等因素选择合适的支付渠道来落地支付;支付渠道调用银行、第三方支付等渠道提供的接口来执行支付操作,最终落地资金转移。
5, 无论是3或者4,成功完成用户扣款后,对商户结算账户进行入账操作。
6, 核心支付系统根据商户下单传递的回调地址,调用商户通知系统;
7, 商户通知系统对支付结果进行签名,调用回调地址进行回调通知商户,若商户返回失败或者超时,则商户通知系统会按照一定的时间节奏进行后续补偿通知。
业务流程
背景是用户在电商系统购买东西。
信息流:
(1)用户提交订单到交易系统,交易系统确认无误后交给支付系统。
(2)支付系统提供支付应用,用户选择支付方式。
(3)支付网关验签,无误后调用相应的支付产品。
(4)支付产品通过支付路由选择合适的支付渠道来执行支付操作,并将返回的结果通过支付网关给交易系统。
资金流:
当支付请求到支付系统时,就会触发资金流。
(1)若是同行且支付系统有对接该银行,则银行会把资金从用户个人账户上转移到电商公司的账户,并收取手续费。
(2)若支付系统没有对接该银行,则对接银联或第三方支付:
a. 若对接银联且同行,则银联发报文给该行,该行使用内部系统完成两个账户之间的转账。
b. 若对接银联且不同行,则银联发指令给A行和B行,分别完成各自账户上资金余额的增减。银联会在做清结算后处理这笔资金。
c. 若对接第三方支付且不同行,则因为第三方支付在A行和B行一般会有落地的托管资金,发生交易后一般不会跨行资金流动。用户在A行的前会被结算到第三方支付在浦发行的托管账户,而B行的钱,由第三方支付在B行的账户达到电商公司的账户上。
可能出现的问题及解决方式
重复支付
1、支付接口判重
第三方支付在接收到支付请求后,根据与商家约定的判定重复支付的参数组合对支付请求进行校验及判重,如果为重复订单,则不继续后续流程。
由于涉及每一次支付请求都需要查询交易数据,影响系统性能;且由于不同商家的判重标准不尽相同,一般都需要要对接口做定制,因此除非是大商户,一般都不提供此功能。
而且此种方案,并不能杜绝重复支付的问题,例如:用户开了两个窗口,都已经跳转到银行网银页面上,此时侯第三方支付已经无法控制用户支付行为了。
2、重复支付+退款接口
如果重复支付的订单尚未与第三方支付平台结算,则:
在用户支付成功后,商户系统是可以判断是否为重复支付,商户系统可以自动调用退款接口,对判定为重复支付的订单发起退款请求(商户平台订单号+支付平台支付流水号)。也可以由商户运营人员在运营后台发起退款请求(本质上也是调用退款接口)。
3、批量代付退款
如果重复支付的订单已经与第三方支付平台已经结算(第三方支付与银行也完成对账、结算),则:对在线支付,一般采用批量代付的方案,将重复支付订单退款与提现、转账等业务以批量文件方式提交给代付渠道代付出去。
如果是POS收单,可以采用冲正、消费撤销、退货等命令,对重复支付的订单进行反向交易。在线支付一般较少采用冲正方式。
另外在商户端,为避免对于重复支付,在业务逻辑上也可以做一些处理,包括:
1、保证交易订单号的唯一性。很多商户系统开发能力有限,经常出现交易订单号不唯一的情况。
2、在发起支付请求后,更改订单状态,避免用户再次发起支付请求。(慎用,只不过在一些业务场合会也会采用此种方案)。
3、对因掉单等原因引起的订单状态未知的情况,先调用第三方支付接口的查询接口确认订单的支付状态。
返回结果超时
悲观的异步调度策略:每次成功都写MQ消息,商户系统可以得到多次的补偿通知,在比较及时的情况下实现订单的状态扭转,不足是如果支付量很大,在一定的极端情况下,商户回调处理服务可能收到大量的重复请求,给系统带来压力,浪费了计算资源,甚至处理不好导致雪崩。
乐观的异步调度策略+自动补偿机制:失败才写MQ消息,只针对失败才写MQ消息,意味着对MQ的存储量和请求量相比悲观策略降低了99倍,这个时候MQ发生阻塞和雪崩的可能性会大大的降低,而补偿服务不会定时进行补偿,只有收到了MQ的通知失败消息,才进行补偿操作。但如果出现了MQ消息丢失,由于补偿服务这个时候不会自动进行补偿,商户是无法收到主动的回调通知的,对这种情况,商户可以选择主动反查订单进行补偿。
根据不同的场景:并发数,可靠性,机器资源,及时性等要求选择不同的策略,我们认为在商业支付中,悲观的回调策略可能更合适,一个是并发数突发性较少,另外对支付的可靠性和及时性也有更多的及时补偿;而对类红包的社交支付等突发性很高的情况,乐观的回调策略可能是更好的选择。