支付核心:
一、支付核心和清算核心职责
首先要明确一个概念:一个完整的支付清算系统结构内,各种特定业务所涵盖的支付服务、清算服务,是相互独立的。
其独立性,体现在具体的产品研发过程,以及后期维护等各项工作中:
- 这种现状导致了业务产品开发复杂化、风险性提高;
- 支付与清算的相关规则各自为政,彼此独立,加大管理难度;
- 在开放平台的大背景下,也不能提供给大量外部业务系统所需要的基础支付服务;
- 若清算服务部署于在后台管理系统,各类清算细则繁冗复杂,对运营部门造成很大不便性。
在设计支付清算系统时建议:
将支付核心和清算核心设计为两层,分为两个独立子系统。
- 支付核心提供适应各类产品使用的基础支付服务;
- 清算核心则将所有机构所能提供的底层清算服务归集,专门负责与银行的各类清算接口对接。
支付层则对外提供各类经过包装的支付服务,涵盖清算服务、账务服务、客户相关服务等,实现对基础支付服务的编排。
二、提现协议系统业务流程分析
前提:以同步/异步的维度划分提现支付协议,得出两类提现支付协议的处理流程。
维度:会员层、提现产品层、支付层、财务核心、清算层、银行。
(1)同步提现支付协议处理流程图
会员提交提现申请后,进入提现产品层申请同步提现支付协议,然后进入支付层请求扣款提现金额。此时进入财务核心执行扣款,同时报送清算请求指令进入清算层,报送银行处理,然后进入银行执行扣款并返回清算结果。
此时做一个判断,若清算成功则回执处理结果,并回到提现产品层进行业务处理并通知用户提现处理结束。若清算失败则进入财务核心,进行回充。
(2)异步提现支付协议处理流程图
会员层提交 T 日申请提现需求后,进入提现产品层申请异步提现协议,然后进入支付层:首先请求冻结提现金额,并进入财务核心进行冻结;在 T + N 日请求扣款冻结金额,并进入财务核心层进行扣款,同时报送清算请求指令,进入清算层进行清算指令的记录并生成清算报文(文件),再进入银行层执行清算。
在 T + N 日,运营平台层执行回导清算结果/文件,进入清算层勾兑清算指令并回执处理结果,进入支付层进行判断。若清算成功则回执处理结果,并回到提现产品层进行业务处理并通知用户提现处理结果,若清算失败则回到清算层进行回充。
(3)退票支付协议的处理流程
这部分内容比较容易理解,这里就不做详解了。
如图,将支付与交易分开,主要是为了体现出支付服务机构的核心支付服务功能。
核心支付服务能够为会员提供丰富个性的支付服务:充值、提现、内/外转型支付、支付侧营销等内容。
若将交易产品中包装的相关支付服务,交由支付服务层与清算服务层协作完成,并将交易以及其他产品释放出来,则产生的整体系统框架图如下:
三、提现支付协议领域模型
模型总览:
通过对提现支付协议、提现支付指令的归纳抽取,得到本模型图。其中,操作指令部分不对外暴露。
就提现支付协议本身,分为同步/异步两种处理方式:前者将提现支付协议的申请过程、处理过程打包处理;后者则是分阶段处理。
提现支付指令里包含了收款方-银行卡,付款方-支付账户的各自支付工具,依据此可拆分出相应的账务类操作指令与清算类操作指令。
作为提现支付协议的一种,退票支付协议也将退票单的申请与处理过程打包。
- 每 1 提现支付协议,拥有 1 到多个明细项;提支付协议本身和明细项信息,是产品在使用支付协议时,各专用申请单据转化而来,由原始业务单据数据经过简单加工后得出。
- 每 1 提现支付协议,拥有 1 到多个提现支付指令;支付指令是在协议和协议明细项基础之上加工得出,其具备了进行后续操作处理的全部要素信息,除原始单据中请求要素外,经过支付层的一系列诸如补全、拆分、检查之后产生。部分没有业务数据的提现产品,如:正常提现和卡通提现,都是以支付指令作为其产品数据。
- 每 1 提现支付指令,拥有 1 到多个提现操作指令;提现操作指令是真正可被系统处理的,运行时得出的具体操作步骤。具体表现为账务相关、清算相关,以及其他底层公共服务的处理单元。
- 为了简化提现支付指令与提现支付协议的从属关系,可以直接认为每 1 提现支付协议拥有1到多个提现支付指令。
核心业务逻辑:
以在线用户发起的正常提现申请为例,整体的交互时序图如下:
支付层内部处理的交互时序图
提现支付指令作为提现支付协议的流水数据,其处理生命周期的状态迁转如图所示。
异步提现支付协议下的提现支付指令状态图
提现退票支付协议下的提现支付指令状态图
同步提现支付协议下的提现支付指令状态图
四、提现业务边界分析
首先,提现业务边界分析可以拆分为两大部分:业务用例边界以及系统用例边界。
这里着重讲一下系统用例边界,分为:
- 异步提现支付协议申请;
- 异步提现支付协议推进处理;
- 接受清算处理结果回执;
- 统一协议处理结果回执;
- 同步提现支付协议申请;
- 同步提现支付协议推进/恢复处理;
- 提现退票支付协议;
- 打款机构;
- 支付能力;
- 分布式任务;
- 公共查询类服务:协议授权查询服务、机构信息查询服务;
- 提现查询类服务:银行卡段检查服务、对公账户联行号检查服务、支行列表查询服务、清算通道支付限额查询服务;
- 管理服务:协议授权管理服务、打款机构管理服务、支付能力管理服务、缓存刷新服务。
1. 业务用例边界
支付层作为提供基础支付服务的核心系统,所承担的职责围绕着以下主要业务功能点:
以协议方式提供适用于各类产品使用的支付服务:
如图所示,可分为同步提现支付申请协议、异步提现支付申请协议以及单笔退票支付申请协议。
承担包装清算层所公布的各类底层公共查询服务,以及独立提供给产品层的各类公共查询服务:
以提供公共查询服务为职责,则分为协议授权查询、提现统计查询、银行卡段检查、对公账户联行号查询、机构信息查询以及清算通道支付限额查询。
作为协议使用的辅助手段,提供不同协议的干预处理服务:
可提供四种不同的干预处理服务:异步提现支付协议推进、异步提现支付协议取消、同步提现支付协议推进、统一提现支付协议回执。
可供灵活编辑的各种核心处理规则配置机制,以及提供配套的规则管理服务:
如图所示,三种不同的管理服务内含不同的核心处理规则配置机制:协议授权管理服务、打款机构配置管理服务、提现支付能力管理服务。
2. 系统用例边界
支付服务层的主要作用:与产品层对接,暴露各类支付协议以供产品使用,并囊括各协议的账务处理、清算处理、客户相关检查等部分;释放产品层与清算服务层的链接,使得后者不受限于具体产品业务逻辑,专注于与金融机构的清算过程。对于产品层来说,同样也无需关注具体的清算过程。更方便、更简洁。
假设目前公司的产品层尚未成型,那么现有的各类提现相关产品是分散在各个子系统中的,在这种情况下:
通过对提现产品的提炼,可抽取三种提现支付模式:异步提现模式、同步提现模式以及批量提现模式。其中批量提现模式,是对前两者的再组装、复用的过程。因此,在支付服务层对提现支付协议的划分可根据同步、异步两种方式即可得出。
此图要点:
- 支付服务层暴露提现支付协议给产品使用,贯穿提现业务的整体生命周期,提供提现支付协议申请、推进执行、取消、查询等服务;其中提现支付协议的推进执行入口,主要包括针对同步提现支付协议的推进处理,和异步提现支付协议的推进处理(例如:生僻字复核)。
- 产品希望得到提现支付协议的处理结果,支付层需要以统一透明的方式,将提现支付协议处理结果,回执给特定产品。在产品层需要有统一的接受支付层处理回执服务,在接受到支付层的回执之后,此服务将自行分发至各特定提现产品进行处理。
- 支付服务层报送账务请求至账务核心,请求账务处理,包括充值、提现、支付以及冻结、解冻等。
- 支付服务层请求清算服务层执行清算过程,与产品层同理,支付服务层需要得到清算指令的处理结果来决定其下一步业务处理。对于差评层需要取消提现支付协议的,支付服务层需要得到清算服务层允许后方可决定是否取消。所以支付服务层与清算服务层的交互有发送清算指令,接受清算结果,查询清算指令,取消清算指令以及问询清算指令是否可絮叨等。
- 退票作为提现支付协议的方向处理过程,支付服务层提供给管理平台退票申请入口,将退票作为提现支付协议的一种特殊类型即退票支付协议看待,与提现支付协议简历关联。辅以退票支付指令,进行会员账务回充等处理。
- 支付服务层需要将内部各类规则配置释放给管理平台,以便后续可支持灵活的规则组合,以达到各类支付协议业务敏捷的目的。
(1)异步提现支付协议申请
作为提现支付协议中最为基础的一种,异步提现支付协议适用于现有各类非实时处理的提现产品,如:正常提现、认证提现、委托提现等。
参照提现支付协议认领模型设计,产品层可将异步提现支付协议的使用分为:申请、推进处理两个阶段,以及特殊情况下的取消操作。
本文重点描述异步提现支付协议,在申请过程中支付层的体系结构以及处理流程。
需要重点指出的是,支付层所提供的协议申请使用嵌套分布式事物,在此将申请过程分为两个阶段处理:
阶段一:
调用者开启分布式事务,在事务块内请求异步提现支付协议申请:
- 整合现有各类非实时处理类提现产品要素,设计专用的申请单据对象;异步提现支付协议支持每次申请单笔或批量明细项;
- 通过内部的业务接入层将专用单据转换成统一的内部领域模型对象;
- 对领域模型对象加工,包括补全、拆分、检查等;
- 启动嵌套分布式任务,执行预授权处理,即冻结提现款;
- 组装处理结果并返回。
阶段二:
调用者根据支付层协议申请的返回结果,决定提交或回滚分布式事务。
这个调用是隐式的,与调用账务核心服务接口方向一致,即调用者本地事务提交,则分布式失误提交,同时支付层调用账务核心的嵌套式分布式任务也提交,否则本次申请做回滚处理。
异步提现支付协议推进处理:
异步提现支付协议在申请阶段只是将提现额做了冻结,后续处理是通过支付层的调度任务根据优先级以及可执行时间按顺序处理,包括对支付指令的账务解冻、扣款、报送清算指令等步骤。
对于正常提现或认证提现,某些需要审核生僻字的提现申请。产品层调用者在请求支付层申请处理,如果指定了不允许支付层自行处理的,则支付层不会自行通过调度任务方式推进处理,而是等待产品层通知才进行处理。
支付层自行调度的推进处理:
- 加载协议数据,激活领域模型对象;
- 执行结算处理,包括账务解冻与扣款;
- 执行报清算处理,通过确保达到的ESB消息通知清算层执行清算。
产品层通知方式的推进处理:
- 加载协议数据,激活领域模型对象;
- 记录协议的相关审核人以及类似于生僻字审核所需要的银行开户名等信息;
- 执行结算处理,包括账务解冻与扣款;
- 执行报清算处理,通过确保达到的ESB消息通知清算层执行清算。
1)异步提现支付协议取消/接受清算处理结果回执
异步提现支付协议取消:
- 这里提到的协议取消不是对整个协议的取消,支付层只允许对单笔支付指令的取消行为;
- 对于大多数协议支付指令为单笔的提现支付协议,如果该笔支付指令取消成功,则协议也相应进入处理结束状态;
- 取消支付指令由于涉及账务处理,所以继续使用嵌套分布式事务解决。
需要注意的是:
- 只有处于已预授权状态的支付指令才可以被取消,如果已经扣款或者已报清算,则不允许在支付层发起取消。产品可以通过致使清算指令失败的方式令支付指令失败,达到取消的效果。
- 请求账务执行解冻处理。
- 通知产品层代理者本提现流水已取消。
接受清算处理结果回执:
在经历了上述两个处理过程后,清算层根据自有的业务规则进行清算处理。最终的清算结果需要确保通知到支付层,此处继续选用高可靠性的ESB确保到达。
需要注意的是:
- 对于清算成功的支付指令,将该笔置为成功状态;
- 对于清算失败的支付指令,请求账务进行失败回充处理,并将该笔置为失败状态;
- 对于清算成功的支付指令,更新其实付金额为应付金额;对于清算失败的支付指令,更新其实付金额为0;
- 成功或失败状态的支付指令都代表处理结束;如果申请的异步提现支付协议只有所有支付指令均处理结束,则需要将协议也置为处理结束状态;同时累加其所属支付指令的实付金额作为协议的实付金额;
- 所有处理结束的支付指令,均需要回执给产品层,由其进行具体业务处理。
全局系统中有多处业务场景使用提现取消服务,如风控的申请后拒绝行为,客服的提现失败任务,以及后台冻结账户等,都需要取消指定的提现申请记录。
请求者(系统)使用分布式事务,来要求支付层保证整体业务的原子性,也就是说支付层所提供的取消服务,在分布式事务第一阶段执行成功后,如账务解冻成功后,需要将协议重新置为系统状态,等待请求者提交分布式事务。
相应的,如果请求者发生异常而回滚分布式事务,支付层必须确保协议整体模型数据恢复至取消前状态(包括金额等关键数据要素),而不能与其他基于分布式事务的申请服务一样,将数据删除。
同时,支付层必须确保在请求者提交分布式事务后,才能发送回执消息给产品层代理者。不允许在业务处理内部发送回执消息,否则一旦请求者回滚事务,此消息无法删除。
2)统一协议处理结果回执/同步提现支付协议申请
统一协议处理结果回执:
- 除了上述的支付指令处理成功/失败已经提现取消作为处理结束状态,需要回执给产品层外,对于退票情况,也需要回执给产品层;
- 产品层目前也是通过前置来统一处理的,所以支付层在回执产品层提现处理结果时需要一并报送该笔支付指令的产品码、子协议代码以及备注信息、操作员等;
- 这里回执给产品层的处理结果,也是采用高可靠性的ESB确保到达。
(2)同步提现支付协议申请
对于需要同步支付并清算的提现产品,使用本协议。同异步提现支付协议,本协议也可以使用嵌套分布式事务。
不同的是本协议的使用需要三阶段处理模式:
阶段一:
调用者开启分布式事务,在事务块内请求异步提现支付协议申请。
- 快捷提现都是通过快捷协议号,即收款方信息较为简单,为此设计专用的申请单据对象,只支持每次申请单笔明细项。
- 通过内部的业务接入层,将专用单据转换成统一的内部领域模型对象。
- 对领域模型对象加工,包括补全、拆分、检查等。
- 开启嵌套分布式事务,执行结算处理,直接进行扣款。
- 组装处理结果并返回。
阶段二:
调用者根据支付层协议申请的返回结果,决定提交或回滚分布式事务。这个调用是隐式的,与调用账务核心服务接口方式一致——即调用者本地事务提交,则分布式事务提交,同时支付层调用账务核心的嵌套分布式事务也提交,否则本次申请做回滚处理。
阶段三:
调用者分布式事务提交后,采用主动调用同步提现支付协议的推进处理服务,通知进行后续处理。
1)同步提现支付协议推进/恢复处理
- 之所以没有在同步提现支付协议申请过程中进行清算,原因是清算层无分布式事务支持。而同步提现支付协议的清算是需要同步请求清算层的,为了保证前期处理过程的一致性。支付层在申请阶段确保账务扣款成功,这个是由嵌套分布式事务框架来确保的。
- 而此时并未进行实时清算,产品层需要显示的调用本推进处理服务来通知支付层进行后续清算处理。这个通知是不需要确保的,原因是经过前期的申请处理,支付层的协议处理已提交。而产品层显示调用支付层进行推进只是为了实时的拿到最终处理结果,从而回显给会员。
- 而支付层内部则简单的请求清算层进行同步清算即可。
- 如果发生掉单的情况,支付层内部的恢复程序会不断的尝试恢复,直至清算处理结束为止。这里就需要清算层对于支付层,同一支付指令的多次清算请求,做忽略处理,并返回当前的处理状态。
- 支付层同步请求清算,清算层的返回结果中有三种清算状态:
如果支付层在请求同步清算时出现了严重异常,如清算层异常宕机或清算返回丢失,则仍然返回产品处理中结果,支付层内部回复程序会继续尝试回复。
2)提现退票支付协议
提现退票支付协议作为本讲引入的协议之一,通过申请支付层的协议,由支付层负责账务与业务推进处理。在本协议下,退票流水将作为支付指令存在,与被退票的支付指令平级,不会去对已经处理成功的原支付流水做任何改动。
由于不需要进行清算,支付层内部只需要处理账务充值部分即可。所以本协议也是同步的,即申请成功则全部处理完毕,使用嵌套分布式事务。
- 只有处理成功的支付指令才可以被退票;
- 每一笔支付指令最多只能被退票一次;
- 退票金额为原支付指令的实付金额;
- 新产生的(退票)支付指令建立起与原支付指令的关联关系;
- 对于退票申请处理中,如果请求账务失败,则本次申请失败。
3)打款机构/支付能力/分布式任务
打款机构:
任何一笔提现申请,最终目的都是从某一支付账户提现至指定的银行卡上,这个银行卡就是提现支付协议中指定的收款方信息。
由于银行卡信息中的开户行种类繁多,比如:各类非直接打款银行,对于这些开户行的提现申请,实际会通过跨行的方式进行提现。具体说来就是根据开户行,提现的额度范围,账户的对公对私属性等,来决定最优的提现方式。
产品层不知道本次提现的实际打款机构,而支付层对每笔支付指令进行账务处理时需要知道具体的打款机构,这样才能请求账务进行扣款或者回充处理,所以打款机构的规则就需要支付层进行维护。
- 根据既定的打款机构配置方式,按照开户行、提现的额度范围、账户的对公对私属性以及产品码来补全支付指令的打款机构;
- 对于同步提现支付协议,其打款机构与开户行相同。
分布式任务:
支付层的大量调度任务,如:异步提现支付协议的推进、同步提现支付协议的掉单恢复等,将来会有更多的调度任务加入。
考虑到线上环境是多服务器并发处理任务的,对于这种分布式任务需要解决两个问题:
- 防止重复处理:由于各服务器程序代码都是一样的,这样就很容易造成彼此处理的数据相同,造成资源的浪费,并且可能带来严重的资损风险。
- 最大限度的并发:在解决了重复处理的问题后,还必须让集群服务器发挥效能,真正实现多服务器并发的处理,在保证安全的情况下最大程度的提高处理效率。
支付能力:
作为支付协议最重要的处理规则,支付层对外提供可供快速定制的各种内部处理打包方案,这些打包方案里配置了一些极为关键的规则要素:
- 支付处理优先级:决定其在支付层处理的优先级别,值越大的越优先处理;
- 支付处理延时时间:以此推出每笔支付指令的具体可执行时间;
- 清算优先级:报送的清算指令,在清算层内部的处理优先级别;
- 内部渠道:内部渠道的划分,如线下、快捷等,以此决定清算通道;
- 账务子交易代码:执行账务扣款的子交易代码;
- 失败回充账务子交易代码:执行账务失败回充的子交易代码。
除此之外,每个支付能力拥有以下要素:
- 子协议代码:一个支付能力可以被多个支付协议使用,这里就是可以使用这个支付能力的子协议代码。
- 是否是默认能力:每个支付协议都有且只有一个默认的支付能力。
- 作为初始数据,支付层配置了若干支付能力,正式由于这些支付能力的存在,支付层能够做到灵活的发布新的支付服务。而这种打包方案的发布,无需代码改动成本、无发布成本,只需简单配置即可工作。
- 产品与可使用的支付协议之间是多对多的关系,支付协议与可使用的支付能力之间也是多对多的关系。
- 不同的产品,使用不同的支付协议,实际上是在使用不同的支付能力。
- 不同的产品,使用相同的支付协议,也可以使用不同的支付能力。
- 相同的产品,使用相同的支付协议,仍然可以使用不同的支付能力。
4)其他服务类
公共查询类服务:
- 协议授权查询服务:此服务由支付层自行提供,所有使用支付协议的产品,必须得到支付层的使用授权。这里提供了根据产品码、子协议代码检查是否可用的查询服务。
- 机构信息查询服务:此服务由清算层提供,支付层代为封装,查询所有系统支持的机构信息列表,每个机构信息包括机构ID、机构名称等基本要素。通过机构ID查询机构信息服务;通过机构名称查询机构信息服务;检查指定的机构ID与机构名称是否匹配服务。
提现查询类服务:
- 银行卡段检查服务:此服务由清算层提供,支付层代为封装。会员在设置银行卡信息时,产品通过此服务检查会员设定的银行卡信息的有效性。同时在发起提现申请时,支付层内部也需要通过该服务再次请求清算层检查,以确保报送的清算指令数据合法性。
- 对公账户联行号检查服务:此服务由清算层提供,支付层代为封装,产品层在检查设置了对公银行账户有效性时使用。
- 清算通道支付限额查询服务:此服务由清算层提供,支付层代为封装,某些特定场景下,产品层希望提前得到清算层,所设定的某个清算通道支付上限金额。
- 提现统计查询服务:此服务由支付层自行提供,统计会员在某时间段内的所有统计信息,包括提现成功、失败、取消、退票以及处理中的总比数、总金额等。
管理服务:
- 协议授权管理服务:提供产品的协议使用授权开通、关闭服务。
- 打款机构管理服务:提供打款机构规则的配置、取消服务。
- 支付能力管理服务:提供支付能力的配置、取消服务。
- 缓存刷新服务:前文提到的支付层内置本地缓存机制,一旦某些清算层的配置规则或支付层自有配置规则发生变化,需要刷新这些缓存。支付层提供管理平台使用的本地缓存刷新服务,支持全部缓存刷新和对指定的某个缓存刷新。这里需要考虑由于线上是集群服务器环境,要做到所有服务器均可刷新。此外,对于支付层自由配置规则的调整,内部会自动进行刷新本次调整所对应的缓存内容。
本地缓存:
由于支付层代理了清算层的一些底层查询服务,并且这些服务频繁的被产品层使用,而且支付层内部处理也需要用到这些底层服务。为了降低远程查询的系统开销,支付层需要建立起本地缓存机制,将适合的清算层查询结果缓存在本地。
- 机构信息查询结果;
- 清算通道支付限额查询结果;
- 支行列表查询结果。
除此之外,支付层自有的配置规则也可以考虑使用缓存的模式,减少数据库读取频率:
- 协议授权关系列表;打款机构规则列表;
- 支付能力列表。
五、充值系统业务流程分析
充值协议处理主体流程图(充值遵守的系统处理原则:先清算,后结算):
充值协议处理主体流程图(充退遵循的系统处理原则:先结算,后清算):
后结算处理的充值协议,如阿里国际站的小额担保交易的使用场景,其处理流程如下:
六、充值协议系统级架构和领域模型
系统整体架构
我们从多个视角来快速浏览支付层的整体系统架构:
模型总览
这里需要指出的是,充值协议不存在支付层处理的时限性,全部都是实时报送清算层完成的。引入的异步处理类充值协议并不是非实时报送清算层,而是由于金融机构回执给清算层的清算结果是异步的,今儿演变为清算回执异步通知至支付层。
充值协议需要支持各类场景下的充值行为,如:网银、快捷等,这些充值场景分表代表的是付款方支付工具的接入方式。当加工处理为充值指令内部的清算单据时,仅作为此清算通道所必须的清算要素而存在,它们最终成为报送清算层的各类充值清算操作指令。对于充值协议本身不同的支付工具决定了支付、清算系统交互的细微差异,如:快捷与网汇E,需要实时响应服务使用者协议处理结果,而网银则被动接受金融机构的异步通知。
充值不再采用提现协议中协议、协议明细、指令三者间的1:N:M关系,而是简化为协议与指令间1:N关系,在不进行定期支付的场景下,协议明细项作用不大。
每1充值协议,拥有1到多个充值指令,充退指令是在各充值协议单据要素基础之上加工得出,其具备了进行后续操作处理的全部要素信息,如需要报送清算层的清算单据和与账务进行交互的账务单据。
每1充值指令,拥有1到多个充值操作指令,充值操作指令是真正可被系统处理的、运行时得出的具体操作步骤,具体表现为清算。
核心业务逻辑
用户进入统一收银台界面,选择了充值渠道以及充值金额,收银台经过规则检查(如安全、渠道等)后,向支付层发起充值协议申请:
清算层在处理完金融机构的清算结果通知后,回执给支付层:
重要的规则、约束、平衡检查如下:
- 产品所使用的充值协议必须经过授权,处于开通状态;
- 必须指定支付渠道API;
- 原则上受理的充值额度区间为:0<额<= 无限大;目前的充值申请均由统一收银台发起,相关特定渠道的充值限额已由收银台进行控制,支付层不对充值额度再次检查;
- 账务充值动作,必须在清算层明确回执银行清算成功后方可进行,实际充值金额以清算层回执金额为准。
充值指令的状态迁转
如图所示:
- 其中已预授权与已预清算状态均为中间状态,为B2B网银支付和Migs网银支付所设计。实际情况下已预清算状态不会迁转至清算失败状态,但是在系统设计中我们认为这样的状态迁转有效。
- 绝大多数的充值指令,均是从已报送清算状态,直接迁转为清算成功或清算失败状态。
七、充退协议领域模型
模型总览
充退协议的处理过程与提现协议极其类似,唯一的差别在于提现协议可以指定收款方的支付工具,如客户指定收款的银行卡信息。而充退则依照“由哪里来,回哪里去”的原则,即客户不能指定收款方信息。
充退必须要关联到一笔充值指令,金融机构依据充值清算过程中的付款方,作为本次充退的收款方,而支付层则无需关心收款方信息,并且也无法得知此信息。
允许对一笔充值指令流水号进行多次充退,只要充退金额满足系统限制即可发起,所以充值指令与充退指令间存在这样的关系:
另外异步后结算充退协议是专门为外卡这样的充值渠道退款而开设的,我们都知道充退与提现的资金流向相同,在处理此类业务时,支付层必须确保先做完账务结算,才能报送清算指令。
而后结算充退协议则用于非常特殊的场景:在报送清算层时支付层无法完成账务处理,如外币充退。在支付层不做任何账务处理的情况下,报送充退清算指令,最终清算完成后再进行账务结算处理。支付层不保证此类充退的账务结算顺利完成,由此带来的结算失败风险由业务产品承担。
由于金融机构与清算层的交互使用充值指令流水号,而不是以支付层所产生的充退指令流水号作为交互依据,并且存在着一笔充值指令流水号多次、且同金额的充退指令。这样对于后续账务、会计系统以及对账中心的资金清算对账都带来了麻烦。
原则上,我们希望同一笔充值指令流水号只能存在一笔处于活动中的充退指令,当这笔充退指令全部处理结束时,才能发起对该充值流水号的再次充退。
在某些特定商业背景下(如机票平台大客户的充退需求)必须大客户一次性对一笔充值指令的连续多次充退请求,有如下两种实现方式:
- 方式一:需要清算层在报送银行端时进行恰当的处理,如将支付层报送过来的充退清算指令进行合并,或采取延迟报送银行等手段加以实现;
- 方式二:产品层加强此类合并充退的组织力度,即支付层、账务/会计、清算层以及对账中心都不为此类业务进行内部业务合并,而是交由产品进行合并,请求支付层的充退已经是合并后的单据。这样的整体代价较小,并且提高了核心系统的业务处理稳定性。
统一的充退申请代理除了上述的完成对充退申请合并工作外,该代理将作为所有充退产品申请入口,一个很重要的职责是识别产品所发起的充退申请合法性。由于充退申请存在资损风险点,且发起场景非常复杂、难以统一控制,所以将这些申请进入支付层的安全性检查统一由代理者进行识别,支付层本身的充退协议做到最底层的合法性检查即可。
另外,支付层分流器以异步消息通知的方式完成回执,交易或缴费类产品在自身业务推进处理失败时,统一报送可疑事件至此代理,由其来识别各类可充退规则配置,决定是否向支付层发起充退协议申请。
鉴于此,支付层提供的充退协议遵循一笔充值指令,最多只能有一笔处于活动状态充退指令的约束。同样的原因,充退协议也不再引入协议明细项,直接建立协议与指令的关系;
- 每1充退协议,拥有1到多个充退指令,充退指令是在各充退协议单据要素基础之上加工得出,其具备了进行后续操作处理的全部要素信息,如需要报送清算层的清算单据和与账务进行交互的账务单据。
- 每1充退指令,拥有1到多个充退操作指令,充退操作指令是真正可被系统处理的、运行时得出的具体操作步骤,具体表现为清算操作指令、账务操作指令以及其他底层公共服务的处理单元。
核心业务逻辑
前文中提到充退协议与提现协议的处理方式极其类似,除了收款方信息用户无法指定外,其余部分与提现的现有做法一致,所以此处不再赘述。充退协议存在时限性,我们继续沿用支付能力可配置的做法,将充退产品与充退协议实现松耦合绑定关系。
注:对于后结算充退协议,指令状态直接迁转为已报送清算状态,在等待清算回执后再做账务结算。
重要的规则、约束、平衡检查等包括以下各点:
- 每笔充值指令最多只拥有一笔处于活动中状态的充退指令。
- (每笔充值指令下所有处于活动状态的充退指令金额总额)ART <= (该笔充值指令实付金额)DT – (所有该笔充值指令下已充退成功的金额总额)SRT。
- 预结算充退协议申请单据中指定的主事务号不得重复,全局唯一。
- 产品所使用的提现支付协议必须经过授权,处于开通状态。
- 必须有可匹配的支付能力。
充值协议领域模型VS充退协议领域模型:
与提现和退票的关系类似,充退也是建立在充值基础之上的特殊协议,都是完成了正向协议的反向资金处理过程。
在前面讲述中将提现协议与退票协议进行合并,反映在模型本身、处理流程以及数据存储等各方面都保持一致,
而本期充值协议与充退协议则是分开建设的,原因有以下几点:
- 提现无多次退票场景,每笔提现指令与退票指令存在唯一对应关系,而充值与充退则存在1:N的对应关系。
- 将退票与提现合并,在数据格式上要求严格的统一,即拷贝原有的提现数据,生成退票数据。提现、退票的数据量小,开销少,对于独立的查询、统计均比较方便。而充值与充退的数据量相差太大,二者进行合并必然带来各自处理以及查询统计的巨大消耗,尤其以充退为甚。
- 充退流水要素构成比较简单,只需记录所关联的充值指令流水号即可完成后续的清算退回过程,没有必要拷贝充值数据。
八、充值业务边界分析
业务用例边界:
充值业务在支付层设计的业务用例主要包括以下若干模块:
- 以协议方式提供适用于收银台或其他业务产品使用的充值服务 ;
- 以协议方式提供适用于各类业务产品使用的充退服务;
- 建立对支付渠道的统一管理;
- 基于通用性而设计的统一业务分流组件;提供相应的注册(推进)服务;
- 作为协议使用的辅助手段,提供不同协议的干预处理服务;
- 承担包装清算层所公布的各类底层公共查询服务,以及独立提供给产品层的各类查询统计服务;
- 可供灵活编辑的各种核心处理规则配置机制,以及提供配套的规则管理服务。
系统用例边界:
网银充值协议申请:
- 用户选择网银渠道,如B2C或B2B以及VISA等,收银台组装本充值协议申请单据,请求支付层处理;
- 如申请单据中包含业务分流回执信息,则需要完成对回执上下文的注册工作,这里交由监听器处理;
- 报送清算指令清算层,并将可供收银台实现页面跳转的地址或html串响应给收银台。
基本流程示意图:
- 协议申请单据一旦经过合法性检查,必须先存储,同时发送协议申请事件,以期分流任务注册完成。
- 同步报送清算指令,如果此时请求失败或超时,直接返回调用者申请失败即可,清算层完成指令落地工作并返回跳转表单对象。
- 会产生一定的废单数据,如会员在网银页面后直接关闭。
- 结算行为必须在得到清算层明确的清算成功回执之后,以实付金额为准进行账务结算,下同。这里的清算回执是异步的,所以不在此图中显示,见后续充值清算回执说明。
代金卡(充值码)充值协议申请:
网银充值协议申请后所返回的跳转表单对象,供收银台跳转至金融机构。而代金卡的充值处理中收银台,无需获取跳转表单对象。这里有可能是代金卡独立业务系统,已明确了跳转表单对象,所以这个充值协议的处理过程,仅是将支付流水与清算流水记录即可,等待外部(百联)系统对清算层的回执发生后发起结算行为。
代金卡充值协议需要收取手续费,在报送的协议申请单据中需要指定待冻结的金额,支付层充值领域服务完成充值后,即发起对充值账户的冻结处理。
快捷充值协议申请:
不同于网银充值,快捷不需要会员在金融机构再次确认,收银台、支付层、清算层以及金融机构之间全部实时交互完成。当然,对于支付层与清算层之间掉单的数据,需要恢复补偿措施。
接受充值清算回执:
- 对于网银充值需要用户进行操作的,清算层异步通知支付层金融机构的清算结算;
- 快捷充值或网汇E类无需确认的,考虑到清算层实时通知支付层有可能出现掉单,此处也作为业务恢复点。
- 必须以清算回执的实际清算金额为准进行账务充值处理;
- 发送协议推进处理事件必须在结算行为事务块之内完成,即确保结算完成,且分流任务被启动。
无清算充值协议申请:
以上介绍的各类充值协议其处理过程,都遵循了支付层先记录单据,待清算层完成清算后再由支付层进行结算的处理原则,也就是意味着当清算层回执支付层具体的清算结果时,支付层一定是有相应的单据的。而由于COD业务模式的特殊性,物流收到货款后即才支付机构发出通知,以物流订单号作为充值订单号,要求完成此次充值行为。
COD是支付机构内系统最先获知此充值请求的,由它来通知支付层创建充值协议并立即完成结算行为,在此之前支付层并无任何单据信息。
为此,支付层需要为COD模式的业务开设专用的充值协议,即所有单据据要素已由调用者收集完毕,并使用此协议完成充值,注意支付层此时的处理仅结算即可,无需再次与清算层发生关系。
这个时候可以把COD当成是业务产品在使用此充值协议,由于金额机构系统不会再次通知COD,当它们完成自身业务处理后,使用高质量确保的异步消息通知支付层形式,来完成本次充值。
支付层要严格控制消息的幂等性,不能为中间账户多次充值!
充值后通知事件:
所有成功完成的充值协议,都需要以异步消息方式通知CTU及积分核心系统本充值事件。
支付与清算系统掉单恢复:
对于实时完成支付、清算过程的充值协议,需要辅以定时调度任务恢复系统响应超时的掉单充值指令。扫描2小时内处于报送清算状态的充值指令,使用清算层提供的指令查询接口问询当前处理进度。对于清算明确解释指令处于未知状态的,则无需再做处理,等待其处理结束后主动发起通知。
充值协议查询:
用以解释当前充值订单处理状态,当清算层push相关信息至收银台后,收银台使用此服务获知处理结果并显示用户。
此服务不限于仅在此场景下被使用:
- 处理成功状态:充值成功,业务分流后产品处理成功;
- 充值成功状态:仅充值成功,业务分流后产品处理失败或未知状态;
- 充值失败状态:充值失败,无论业务分流是何结果。
预结算充退协议申请:
- 同提现协议处理方式,使用此协议的请求者(产品)必须经过授权,通过指定具体支付能力的方式达到不同的处理时限以及有差异性的结算、清算过程。
- 以原充值指令号及该笔充值指令的支付渠道API请求清算层,获得新的退回API及充退流水号。
- 使用嵌套分布式事务,保证账务冻结的处理成功,当满足处理时限要求后,依序进行账务结算以及报清算处理,见下文关于异步充退推进调度所述。
- 当前协议下每笔待充退的充值指令,不允许存在活动中状态的充退指令。
后结算充退协议申请:
- 针对诸如Migs的渠道,支付层提供了后结算充退协议供使用,与预结算充退协议不同处在于,完全依赖清算层的回执才进行账务扣款,并且不存在冻结、解冻以及失败回充的动作。仅在清算层明确回执清算成功后,以实际清算金额(RMB)为准进行账务扣款。
- 由于没有事先结算,理论上清算完成后进行账务扣款有可能失败,如:账户余额不足。对于此类场景,系统要不断重试,直到能够扣款成功为止。
异步充退推进调度:
使用分布式任务组件,作为异步充退推进处理的调度策略,这里要完成:
- 结算:解冻、扣款,注意如果是后结算充退协议则不需要进行此类账务处理。
- 清算:报送清算指令。
调度任务中只负责识别出当前待推进处理的指令集合,交由独立门面服务进行上述处理。此门面服务需要对外开放,如系统约定对于大客户充退申请的处理时限,业务部门可能对其进行临时干预,要求立即完成清算,把这个服务释放出去,供管理平台调用。
重要:待推进处理的指令集,所对应的通道API必须处于可用状态,如大客户所申请的标准卡通类充退,我们不希望在其通道已关闭的情况仍对其进行扣款、报清算处理。
异步充退超时调度:
- 处于结算成本以及客户引导的原因,结算人员对客户发起某些金融机构下的充退是不给予处理的。同时某些充退在申请时其通道是可用的,而推进处理时则发现通道已关闭,此类充退指令则一直处于待推进状态。
- 为此类申请设置超时时间,如7日内仍处于申请状态的,则将其充退冻结款项进行解冻处理。
接收充退清算回执:
当清算层与金额机构清算完毕,业务对账完成后,清算层将清算结果回执给支付层,支付层进行后续处理。
- 结算:当清算失败则进行回充;注意如果是后结算充退协议则仅在清算成功的状态下发起扣款,清算失败不做账务处理;
- 业务分流:发送协议推进处理事件。
单笔充退指令取消:
允许异步充值指令的取消行为,所遵循的处理原则有:
- 外部系统请求支付层取消某一笔充退指令,如果是预结算的,只有该支付指令处于预授权状态放可进行取消。对于后结算充退指令,只要该笔充退指令没有报送至清算层均可被取消。
- 预结算充退指令取消要完成账务解冻处理。
- 如果当前状态不允许进行取消,则外部系统需要请求清算层进行取消。复核清算层的取消规则后,清算层会以清算失败的状态异步回执支付层,则支付层进行失败回充。
人工充退指令推进:
见上述异步充退推进调度中所使用的独立门面服务,完成结算以及报清算处理过程。
充退汇总查询:
独立的门面服务,支付层内部以及外部系统均可使用此服务,用以解释指定的充值指令所对应的所有充退指令集合,包括每笔充退指令的金额、状态等。
服务使用者可通过此服务的结果输出,决定是否继续接受针对本充值指令的充退请求,如:支付层收到产品的充退协议申请,自我完成对“一笔充值指令最多只能存在一笔活动中状态的充退指令”约束规则检查。
可充退额度统计:
用以统计每笔充值指令当前可充退金额,如前台会员自助充退则需要获得此统计金额进行控制。
计算规则如下:
当前可充退金额=充值指令总额 — (所有此充值指令下充退指令成功金额总和+ 所有此充值指令下充退指令处于活动状态的金额总和)
此服务接口可接受批量充值指令的可充退额度统计。
充退高可用性的渠道配置:
对于业务部门希望一定要将其处理掉的充退申请,比如:某些渠道下的充值指令在发起充退申请时,线下文件方式退款失败了,那么业务部门可能选择柜面提交的方式再次处理;对于支付层的要求是识别出这些高可用性的充退申请,在报送清算指令时为其指明此参数项。
目前的识别规则分三个维度:产品、商户(客户)、渠道,实际上充退产品在申请充退协议时从产品和商户的角度来决定,比如:强制充退产品发起的充退申请,或者由BD签约商户发起的充退都是属于高可用性的充退申请。
而渠道的识别规则的充值指令,其充退必然属于高可用性,渠道的识别规则我们不希望产品进行管辖,那么识别的规则需要产品层与支付层共同协作完成。
产品申请的充退协议中如果已指定了高可用性,则无需再次检查;产品申请的充退协议中未指定高可用性,支付层内置渠道规则生效。
各类规则配置管理服务:
简单的介绍一下引入的各类配置规则包括:
- 支付渠道配置管理;
- 与收银台相关的过滤配置管理;
- 统一的支付能力配置管理;
- 支付能力与协议配置管理;
- 分流目标管理;
- 充值后冻结渠道配置管理。
以上各类规则配置,支付层均需开设相应的管理服务供管理平台使用。
业务回执分流器:
本讲说的支付层重要的基础设施之一,负责完成与支付业务处理无关的业务回执分流工作,作为支付层与其他产品系统的通讯支撑。
分流器需要解决如下几个问题:
(1)Target
回执的目标,即需要将支付结果通知给谁,通过预定义的分流目标配置数据,我们将各类产品的接收支付层回执服务地址、通讯方式、通讯质量等记录起来,作为初始的回执目标。新产品上线,辅以管理平台的功能菜单,达到回执目标数据可灵活配置。
(2)Context
回执给目标的信息,当请求支付层的支付协议如充值协议,在充值转支付场景下,交易系统需要得到支付层的响应:充值是否成功、充值金额等。
context有两种注册方式:一种是包含在协议申请单据中,一种是无任何充值背景的、纯利用此组件进行业务回执,如线下网点等。
支付层回执给产品的context包含两部分:请求者注册信息与支付层自有处理结果信息。
示例:url①+(回执者单据号② [金额,状态,支付渠道…..]③) + (接收者单据号④[买家,卖家,交易金额,商品名称]⑤)
其中:
- 可以在注册请求中指定该url,也可以由支付层通过配置获取,以请求中指定优先;
- 必选,代表着希望告诉对方系统处理结果的唯一单据号;
- 可选,解释该单据号的关联要素信息;
- 必选,代表中接收者唯一可识别的业务单据号;
- 可选,解释该单据号的关联要素信息。
(3)Strategy
每个回执上下文的处理状态可分为:
- 未通知:尚未回执至产品层;
- 已通知:已回执产品层,但未得到应答;
- 成功:已回执产品层,得到应答,并且后续处理成功如充退申请成功,终结状态;
- 失败:已达到最大尝试次数,不再进行再次尝试的终结状态。
分流器与与业务逻辑互不侵入,仅仅充当通讯工具的角色,原则上分流器不会自我发起业务回执,需要第三者来通知分流器执行回执。但分流器本身也拥有一定的处理抉择权,如已通知的任务实例。
分流器只对这种场景下的回执行为进行再次尝试,直到满足所指定的最大回执次数为止,分流器只关心系统间通讯状态。
本讲说的回执通讯方式选型为基于ESB的异步通知方式。
业务回执分流注册:
本讲有充值/充退背景的业务回执行为,在组装申请单据至支付层时即设置了回执上下文。而其他子系统也可以直接使用业务回执分流器完成回执,可仅注册回执上下文信息。
统一支付能力:
设计提现、充值、充退领域服务可配置的支付能力,保证后续的支付等都可以配置各类协议所使用的差异性支付能力。
领域服务监听器:
这里将分流器建设成与支付协议无关的系统间共用通讯通道,从而确保分流器本身的稳定性;另一方面,各类支付协议如充值协议的核心领域服务需要建设的更加坚固、稳定,现在需要另外一个角色来将两者连接起来——领域服务监听器,由其来决定是否该通知分流器进行回执。
如上图,通过监听领域服务处理结果,来识别是否需要发起对产品的回执,这样就让核心领域服务层与分流器做到隔离。
这里会设置一些识别规则,如预定义网银充值B2B特定支付渠道,对于交易产品来说,关心B2B支付的预授权以及清算完成状态。实际上这不是交易产品的约束,而是渠道自身所固有的。
当充值协议申请单据中指定了回执目标及回执上下文时,此处依据所配置的规则,识别出来当指令状态迁转为预授权或清算成功/失败时,需要通知分流器进行分流,此时即完成分流任务的注册工作。
当充值领域服务接收到清算层的回执如清算成功后,领域服务完成账务充值等业务逻辑,通知本监听器,包括当前充值指令的状态、金额等信息。由此后领域服务不再关心监听器,以及分流器的实际处理过程,监听器要识别出当前指令状态是否需要回执产品,满足条件则通知分流器进行回执。
业务回执分流器恢复调度:
即前文中所提到的分流器默认调度策略:接收到监听器通知但并未执行的,或者采取同步回执通讯方式的,对方应答丢失的两种场景下需要进行再次尝试,当回执次数超过指定的上限后即不再尝试。
业务回执分流器恢复调度:
如图,支付层将对所有的支付渠道进行管理,支付渠道包含了与金融机构交互的清算通道、以及无需清算类的通道,如余额等,所以支付渠道的范围是大于等于清算通道范围的。
- 清算层负责管理各类清算通道的可用性维护,理论上支付渠道中所包含的清算通道部分没有必要一定要与清算层的保持一致,如:状态、API的命名等。但某个清算通道的关闭/开启,我们希望能够直接反映至前台,基于用户体验而考虑,在清算通道发生关闭/开启事件后,需要以异步消息通知至支付层。
- 支付层负责同步更新该通道的可用状态,以此反映至收银台的可供选择渠道列表。不考虑对清算层新开通的清算通道数据做同步,此处需要人工介入。