支付对账系统(Payment Reconciliation System)是一种金融系统,它用于对比和核对不同支付渠道和来源的交易数据,以确保交易的准确性和一致性。这个系统通常用于商业和金融机构,以管理大量的金融交易记录,包括但不限于信用卡交易、银行转账、电子支付、现金交易等等。
以下是支付对账系统的主要功能和目的:
- 交易核对:支付对账系统用于核对不同来源的交易记录,例如银行、支付处理器、商户和客户之间的交易数据。这有助于确保所有的交易都被准确地记录和处理,防止出现差错。
- 差异检测:系统会检测并报告交易数据之间的差异或不匹配,如双重扣款、错误的交易金额、未经授权的交易等等。这有助于及早发现潜在的问题并采取纠正措施。
- 数据调查和解决:一旦发现问题或差异,支付对账系统通常提供工具和报告,以便金融机构或企业进行调查和解决问题。这可以包括退款、调整交易记录或与客户进行沟通以解决问题。
- 合规性和审计:支付对账系统可以记录和存储所有的交易数据,以满足法规和合规性要求,并为审计目的提供透明度。
- 自动化:一些支付对账系统具备自动化功能,能够自动处理一些交易差异,减少手动干预的需要,提高效率。
- 报告生成:系统通常能够生成各种报告,包括交易统计、差异报告、账单和对账单等,以供内部和外部审查使用。
支付对账系统有助于金融机构和企业确保其金融交易的准确性、透明性和合规性。这对于管理大量交易记录、减少风险、防止欺诈和维护客户信任都至关重要。不同组织可能会根据其需求和规模实施不同类型和复杂程度的支付对账系统。
支付机构的信息流和资金流
我们使用的微信、支付宝都会在 APP 上提供账单查询的功能,有记账习惯的人每个月会查询自己的账单与实际消费有没有出入,这就是一个简单的人工对账的过程。支付机构承担管理消费者和商户资金的职责,对账是保证资金安全的最后一道屏障,所以对账也是支付机构需要解决的一个重要问题。要解决对账的问题需要先厘清订单的资金流转过程。一笔支付订单经过支付机构时信息流和资金流的流转过程如下图所示。
- 消费者在商户店铺进行消费,支付100元(信息流)
- 商户将交易信息上送到支付机构(信息流)
- 支付机构组装报文信息并上送到清算机构(银联或者网联)
- 清算机构请求发卡行扣除持卡人交易资金(信息流)
- 发卡行扣除持卡人交易资金100元(资金流)
- 将扣款结果按照发卡行→清算机构→支付机构→商户→持卡人依次向上通知(信息流)
- 清算机构会在清算日计算好手续费和需要清算给支付机构的资金,并发起清算(信息流)
- 央行清算系统接收到清算指令,从发卡行划拨资金到清算机构(清算机构账户 +100 元)(资金流)
- 清算机构划拨资金到支付机构备付金账户(备付金账户 +99.5元,剩下的 0.5元是清算机构的收入)(资金流)
- 支付机构清算商户资金,并通过清算机构把资金结算给商户(商户账户 +99.4元,剩下的 0.1元是支付机构的收入)(资金流)
支付机构在整个订单交易过程中负责把资金交易信息上送给清算机构,清算机构把资金结算给支付机构后,支付机构会把资金结算给商户。在第 3 步中清算机构会把每天的交易汇总起来在 D+1 日以文件的形式发送给支付机构,用以对账,我们称之为渠道对账。在第 12 步和第 13 步中备付金的动账明细会通过清算机构告知支付机构,备付金账户的资金流是否正确,也需要有核对的步骤,我们称之为银存核对,银存核对会将渠道的对账文件和备付金实际的动账明细进行核对,保证备付金账户资金流的正确性。
渠道对账和银存核对解决的事三方支付机构和外部交互的对账问题。支付机构内部系统之间资金是否一致,状态是否正确,状态是否正确,也需要核对。支付机构内部系统资金的流转过程如下图。
- C 端消费者通过商户发起 100 元的支付订单
- 支付机构收到支付指令之后,通过支付核心解析数据并落库,然后组装支付报文请求渠道系统
- 渠道系统请求清算机构获取支付结果并通知支付核心
- 支付核心收到结果之后会通知清结算系统落清算记录,并通知账务系统告知支付结果,账务系统内部户会增加一笔支付收入
- 一般在 T+1 日支付核心会发起结算,清结算系统收到结算指令之后会请求计费系统,根据配置的计费规则计算该笔交易的手续费
- 计算好手续费之后,清结算系统会请求账务系统进行记账,如果交易金额是 100 元,手续费是 1 元,那么商户的账户余额会入账 99 元,支付机构手续费账户余额会入账 1 元
由上图可以看出,支付机构内部系统之间资金的流转一点也不比外部资金流转的流程简单,保证资金在内部系统之间流转的安全性、高效性是支付机构的重要职责。如果内部系统之间资金出了问题,那么支付机构和外部交互的资金肯定也是有问题的。所以内部对账也是支付机构不可忽视的重要工作。
对账业务简介
了解资金在支付机构内部和外部的流转过程之后,可以很清晰地看出哪些环节可能会出现资金不平的问题。资金安全问题如果没有被及时发现并止损,很可能造成更大的资金损失。那么如何对账才能及时发现问题呢?对账分为单向对账和双向对账,单向对账又分为账账对账、账证对账和账实对账。此外,对账是轧账和平账的过程。轧账和平账的目的是进行交易核算,将账单对平,对于不能核对匹配的交易,进行补单或者退款等差账处理方式,最终实现账单对平。
作为支付产品经理,我们更关注的是将账单模块生成的系统支付通道流水与支付通道对账文件进行核对,也就是单向对账和账账对账的过程。如果账单对平会推送账单给财务系统,由财务人员校验凭证是否正确、款项是否无误,也就是账证对账和账实对账的过程。在对账的过程中,按照对明细账或者对总额的核账规则进行对账。如果账账核对完全对平,会将账单打包批次推送至财务模块进行后续流转;如果账账对账不能核对匹配,就会对账单中交易的长款、短款进行差错处理。
按照业务类型可以把对账分成四个模块:渠道对账、银存核对、实时核对(也称资损防控)和离线核对。
渠道对账和银存核对都是支付交易完成之后检测支付机构资金处理和外部资金处理是否一致的手段。除了和外部对账,支付机构内部系统之间也需要进行核对。支付机构内部的每个系统都有自己的存储和业务处理逻辑,中间任何一个环节有问题都可能造成资金不平,对商户、消费者和支付机构都是一种损失,所以要保证内部系统之间交互数据的一致性。我们可以搭建资损防控系统,实时对数据进行核对。内部账务的动账明细也需要与系统的交易明细进行核对,比如有些批量处理的场景不适合实时核对,因为批量处理的数据体量大,并且业务上实时性要求不高,使用实时核对很大程度上会浪费资源,所以可以实现内部系统之间的离线核对,实现T+1日、D+1日对数据进行核对。
对账时间
日切时间是指下一账单日的开始计算时间。定义了日切时间,就确定了一个账单日的开始时间和结束时间。
对于支付这样高频的交易,每一秒都会发生很多瞬时交易,在日切时间也不例外。由于瞬时交易和交易系统的交互存在时间差,会出现支付平台侧交易时间算在当天,但是通道侧算在下一账单日的情况,进而造成在对账时出现账对不平、长短账的问题。
我们知道账对不平,是要推送差账处理的,那么在这种情况下,应该如何处理呢?我们会为每个通道设定一个自动对账时间范围,比如48小时,也就是两个账单日。每份通道对账单会与对应日期的支付平台账单对账,如果有对不上的地方,会将无法匹配的订单留在对账交易列表中,等到下一日支付平台对账单生成时再进行比对。如果对上则为对平,依旧对不上的话,才会推送到差账模块进行处理。这样的对账我们称为连续对账、滚动对账。
对账的规则
对账基准
以哪方的账单为准对账基准有两个。
- 以对方的为准。支付中主要指以支付通道或者银行的为准。对方的对账文件每一条交易数据和金额对齐了,就可以打包批次,更新状态,表示对齐了。
- 以我方的为准。支付中指以支付平台根据日切时间和通道规则生成的账单为准。只有支付平台自身生成的账单每一条交易数据和金额都对齐了,才算对平账。
在实际应用中,我们一般以对方的账单流水为准。而自己如果有没对上的流水,后续会再进行差账处理,但对方账单的对账状态为已对平。原因在于,支付通道侧打款规则不管我方账单能否对平,都会根据支付通道侧的账单记录,给支付平台打款。为了不影响资金入账后账单与资金进行核对,也就是相关的账证对账、账实对账,需要在对方账单对平后就视为对平,可以打包批次。
对账内容
对账分为对明细账和对总账。
对明细账是将自身的账单与账单提供方提供的账单中每一条记录进行核对。在支付中,根据账单通道订单号或者支付流水号、交易类型、交易金额、交易日期、交易手续费进行比对。如果是外卡交易,会再加上交易币种、结算币种、结算汇率;如果收费条件不仅是商户折扣费率(MDR),那么需要再加上其他的手续费率,比如还有风控手续费用、货币转换费之类。
对总账是将自身记录与账单提供方汇总金额、笔数进行核对。在支付中,根据交易日期与结算日期核对总交易金额、交易笔数等,整体金额一致就算对上。
需要说明的是,交易类型是对账过程中很重要的因素,因为它有着双重含义,不仅代表自身具体的交易类型,如消费、预授权、退款,还代表了交易方向,退款代表负交易,消费代表正交易。计算总账时是要根据这些交易类型进行加加减减的。
核对体系
核对体系的业务架构如下图所示。
- 渠道对账:三方支付机构的交易都要通过银联/网联和银行进行交互,银联/网联和支付机构通常会搭建专线解决网络传输的问题,专线相比公网网络更加稳定,数据更加安全。但是跨地区、跨公司之间的数据传输并不能保证百分之百的数据一致,涉及资金的交易如果数据不一致,很可能产生资金异常的问题,所以需要通过对账来确保数据的一致性,主要核对金额和状态即可。银联/网联作为三方支付机构的下游,会提供对账单给支付机构,通常对账单会在D+1日给到,即当天的交易会在第二天汇总起来放在对账单中,统一给到支付机构。支付机构获取对账单之后会和支付机构内部系统的交易单进行核对,核对的维度有支付明细、退款明细、出金明细、手续费明细等。支付机构逐笔核对金额和状态,如果没有问题就认为交易是没有问题的,如果核对资金有问题,则会进行存疑处理、差错处理等操作。
- 银存核对:支付机构的实际资金流都是通过央行的备付金账户来操作的,清算机构(银联/网联)每日会把交易记录做好清算,应该结算给支付机构多少资金,手续费收取多少资金都会算清楚,然后发起结算把资金打到支付机构的备付金账户中,备付金账户的动账明细会通过银联/网联主动推送至三方支付机构。另外,三方支付机构也需要把资金结算给商户,银联提供了银联虚户映射备付金账户的资金,这个账户的资金变动也会推送给三方支付机构。三方支付机构有自己实际备付金资金账户的动账明细,也有清算机构(银联/网联)的信息流交易明细,可以把两者的数据进行核对,以验证备付金账户里资金的流入、流出是否正确,从而确保支付机构自身资金的安全性和准确性。动账明细通常是一笔或几笔明细,对账单的数据是比较零乱的,所以核对的时候需要把对账单里的明细做好轧差再和动账明细进行核对。
- 资损防控:支付机构内部会有很多系统处理支付交易,系统之间会有资金的流转,支付机构内部系统有支付核心、渠道系统、清结算系统、账务系统。等交易金额的一致性和状态的一致性,才能保证整体交易资金的安全性,所和系统个资损防控系统实时监测系统之间交易的一致性,通常监测的维度是上下游系较有间单笔金额、单笔状态的一致性。但是有的时候上下游系统针对同一笔支付订单,会有拆单的逻辑,所以需要做好轧差才能去做核对。
- 离线核对:支付机构内部系统之间会存在批量操作的情况,对核对结果的实时性要求不高,所以支付机构可以提供离线核对的功能,支持按天、周、月、年的维度来对账,并给财务人员提供总金额、总笔数这些维度的报表功能。离线核对弥补了资损防控的不足,和资损防控互为补充。离线核对对账的维度是支付机构内部信息流和资金流的核对,即交易信息记录和账务最终记账记录的核对,通常是将交易的订单明细和账务的动账明细进行核对,并且离线核对功能可以包装给商户使用。
对账架构设计
根据不同的业务核对需求,核对功能可以划分为渠道对账、银存核对、资损防控和离线核对四个模块,这四个模块组成支付机构的核对体系。业务模型划分清晰之后,就可以分析核对共性,抽象公共组件,设计出通用的核对体系架构。核对体系架构如图所示。
数据来源
不同的核对业务需要核对的数据来源也不一样,资损防控主要针对的是支付机构内部系统的数据,需要监听支付核心、渠道系统、账务系统、清结算系统等的 Binlog 消息来获取数据,进而对数据进行核对。离线核对分为两部分,一部分是针对支付机构内部的数据,弥补资损防控覆盖不了的批量业务。另一部分是商户提供的数据,需要商户上传对账文件进行核对。渠道对账核对的是清算机构和支付机构之间的信息流,一方的数据是支付机构内部的数据,另一方是清算机构提供的对账文件,有的对账文件会在固定的时间放在 SFTP 目录下,有的需要通过 HTTP 请求才能获取对账文件。银存核对依赖渠道对账的对账文件和备付金账户的动账明细,备付金账户的动账明细也是通过银联或网联推送给支付机构的。
数据清洗层
获取核对的数据之后,并不是所有的数据都需要参与核对,而是需要进行过滤筛选。获取的数据有监听 Binlog 消息得来的,有通过 SQL 查询业务系统的数据库得来的,有通过拉取对账文件得来的,不同获取数据的方式对应的解析数据的方式也不一样。Binlog 消息需要解析消息体进而获取需要的数据内容。通过查询数据库来获取数据时需要定义映射体,通过 SQL 查询拉取所需的数据,并把数据留存下来。不同渠道提供的对账文件也不一样,有的是 Excel 文件,有的是 CVS 文件,需要定义不同的解析文件工具类来解析文件。
数据解析完成之后要对数据进行清洗,获取需要的数据,过滤不需要的数据。需要对账的数据都是终态的数据,所以从内部系统监听 Binlog 得来的数据要过滤非终态的数据,并且根据配置的清洗规则过滤不需要的数据。比如渠道对账只需要根据订单号、交易金额、退款金额、手续费等关键字段进行核对,但是对账文件给到的字段有几十个,这时只取需要核对的字段并存储即可。又比如实时核对的核对规则是根据不同的业务进行配置的,但是同一张表中有多种业务数据,这时只清洗需要核对的业务数据,不需要核对的业务数据直接过滤即可。
数据清洗完成之后,需要把数据转化为配置核对规则时定义的标准核对模型的数据,以便后续核对流程更加简便。比如渠道对账,我们核对双方的数据一方是监听 Binlog 消息得来的,另一方是通过支付渠道的对账文件得来的,两方的数据根据交易单号进行关联,但是定义的字段名字不一样,在数据清洗这一步需要把字段名称统一。
核对的时候有的数据需要合并起来,比如银存核对,从渠道对账单得到的数据要做好轧差才能与动账明细的数据进行核对。又比如资损防控,两个系统存储的订单的笔数不一致,如支付核心没有手续费记录,而账务系统有手续费记录,这时就需要把账务系统的数据合并做好轧差才能与支付核心的数据进行核对,所以需要有数据聚合、汇总的操作。
数据清洗完成之后,最终需要存储起来,为后续的核对提供数据支撑。因为核对的数据量非常大,所以业务数据需要存储在大数据平台,但是触发核对的监测点、大数据平台查询数据的 Key 可以存储在关系型数据库中。
数据核对层
数据准备好之后就需要对数据进行核对,数据核对层根据不同的核对业务对应不同的核对方式,不同业务的核对规则也不一样,主要分为两个模块:核对业务管理和核对规则配置。
实时核对配置的核对规则需要设置相应的权限,避免配置规则的人员相互之间修改核对规则,并且实时核对要保证核对的时效性,基本是秒级实现核对,并且可以设置存疑时间,在存疑时间之内提供二次核对的能力,解决数据延迟造成的大量异常的问题。
离线核对针对支付机构内部的系统提供自动核对能力,通过配置的规则监听 Binlog 消息,实现自动核对。另外,离线核对也针对商户提供了手动核对能力,商户可以手动上传对账文件进行双方数据的核对。
渠道对账的核对规则相对比较简单,逐笔核对即可。需要注意的是,不同渠道提供的下载对账文件的方式不一样,需要根据渠道的要求配置不同的下载对账文件的方式,并且要根据对账文件提供的时间来定义核对的时间。因为离线核对和渠道对账是集中处理数据的,所以在大数据平台操作起来比较方便,采用 HiveSQL 编写核对规则。
银存核对使用渠道对账的对账单明细,做好轧差之后和备付金账户的动账明细进行核对。动账明细的数据量非常少,一天可能只有几笔,所以重点在于如何定义动账明细的计算逻辑。因为关系型数据库适合计算,所以会把数据存储在关系型数据库中,对账的时候把数据“拉出来”在内存中进行计算核对。
异常处理层
异常处理分三个模块:异常展示、异常处理、确定差错。
各个核对系统核对出的异常统一登记在一个地方,便于查询和处理。核对的异常会统一存放在关系型数据库中,并且根据核对业务、核对规则、核对场景区分不同的核对异常,同时根据异常的分类能够提供异常报表功能,统计出哪些系统出现的异常比较多,进而分析系统的稳定性等。
核对出的异常要及时处理,首先要发送告警消息通知相关业务及相关系统的负责人,相关负责人根据告警内容排查问题,有的问题可能是数据延迟产生的误报,有的问题可能是业务修改但是规则没有及时更新产生的误报,要把这些误报及时处理以免对实际有异常的告警产生干扰。实际有异常的告警会落入差错平台进行差错处理。
误报单排除之后,剩下的基本都是实际有问题的异常单,需要把异常单做好分类,即异常是渠道对账的异常还是内部核对状态不一致产生的异常,哪些需要调账,哪些不需要调账,做好差错分类之后,调用差错系统的接口,落成差错单进行差错处理。
差错处理层
处理差错时首先要把差错分类,渠道对账的差错分为长款、短款,长短款的差错都需要调账才能处理。内部业务的差错根据不同的业务有不同的差错类型,是支付的时候产生的异常,是结算的时候产生的异常,还是退款的时候产生的异常,不同的异常的处理方式也不一样。银存核对产生的差错主要是金额对不上,根据具体的场景具体处理。
划分差错类型之后,对需要调账的差错就请求相关的调账接口进行调账,不需要调账的差错进行相应的处理即可。一般调账需要请求账务系统调整商户的账户资金。内部核对异常状态不一致的差错需要请求支付核心提供的状态调整接口来调整相关的状态。
运营
核对规则、异常订单的展示都需要有对应的运营页面。核对体系也需要提供相应的运营界面,通过运营界面管理核对规则,通过运营界面直观地看到核对出的异常分类,通过运营界面分析异常报表进而确定下一阶段在核对能力上应该提高的地方。同时需要通过页面直观地看到调账的原因、金额等。
核对体系架构的优势:
- 抽象出数据清洗层,统一数据模型标准,解决了数据来源复杂、逻辑混乱带来的核对配置核对规则即可,基本没有开发量。
- 抽象出规则引擎层,实现核对规则可配置化,后续新接入的业务需要核对业务数据配置核对规则即可,基本没有开发量。
- 实现数据拉取、核对异步化,引入本地缓存、Redis缓存,支持高并发、大流量的实时核对。
- 提供运营报表能力,能够根据核对出的问题及时发现系统是否稳定,不稳定的点在什么地方,并督促业务方及时修复。
- 通过数据核对→异常处理→差错处理形成闭环能力,所有的异常都汇总到差错平台来处理,从异常登记到告警再到调账一个流程处理所有问题。
对账实现
渠道对账
渠道对账是支付机构核对体系里最核心的对账功能,每个三方支付机构都会实现渠道对账功能。支付机构会把每一笔交易都上送到清算机构进行实际资金的划转,清算机构是支付机构的下游。如果清算机构有支付成功的记录,而支付机构没有该记录,则需要支付机构清结算人员线下联系清算机构进行处理,把多扣的资金返回消费者账户。如果支付机构有支付成功的记录,而清算机构没有,则需要在支付机构内部做相应的调账处理。
渠道对账流程如下图所示。
1.1 清算机构每天定时把前一天的交易记录(包含支付记录、退款记录、手续费记录)以文件的形式存放到指定的地址。2.1 渠道对账系统实时监听内部系统的Binlog消息。
2.2 将监听到的 Binlog 消息解析并转化为需要的数据格式存放在数据库中。
3.1 定时任务驱动渠道对账到指定的地址拉取清算机构的对账文件。
3.2 支付机构到指定的地址拉取对账文件。
3.3 解析对账文件,并将数据转化后存储在数据库中。
4.1 定时任务驱动核对任务。
4.2~4.3 将从对账文件中获取的数据和监听 Binlog 消息获得的数据同步到 HBase 中。
4.4 执行核对规则,对双方的数据进行核对。
4.5 将核对出的异常记入异常表。
5.1 等待第二天账单到来,对异常表中的数据进行二次核对,如果二次核对没有异常就消除异常记录。
5.2 将没有被消除的异常记入差错系统,等待差错处理。
数据拉取
渠道对账实现了支付机构和清算机构交易的信息流之间的数据核对,核对的数据来源一方是清算机构的对账文件,另一方是支付机构内部的交易订单数据。清算机构一般会在 D+1 日将交易信息汇总起来,以文件的形式存放在指定的地址,通常是 SFTP 的方式。支付机构会在约定的时间去拉取对账文件,然后解析文件,并将数据存入数据库。
支付机构内部的数据会从渠道系统拉取,渠道系统请求清算机构的记录都会落库,数据库中的数据变更时会发送 Binlog 消息,渠道对账系统监听 Binlog 消息,然后进行解析、过滤、筛选,最终获取需要核对的数据并存入数据库。至此,核对双方的数据都获取了,接下来就可以进行核对了。
数据核对
获取数据之后,会有定时任务触发核对规则,对双方的数据进行核对。核对的方法有很多种,如果数据量不是很大,则可以在数据库中进行核对,通过编写 SQL 逐笔进行核对,能够精准核对出哪些数据有异常。
但在数据量大的情况下,单笔核对对数据库的压力非常大,可以在 MySQL 中对数据进行排序,然后每次捞取一批数据(比如前 500 笔交易数据)做哈希操作,对哈希操作的结果进行比对。比如假设清算机构账单的数据保存在表 A 中,内部数据保存在表 B 中,根据订单号对表 A 和表 B 中的数据进行排序,然后对表 A 中查出的数据做哈希处理得到哈希值,对表 B 中查出的数据做哈希处理得到哈希值。哈希值一致的就放过,如果不一致,则再单独对这 500 笔交易数据进行核对,找出有异常的订单。
如果数据量特别大,单日有百万、千万笔订单,因为性能的问题就不能依赖关系型数据库进行核对了。可以把 MySQL 的数据同步到大数据平台(HBase、Hive等),然后通过 HiveSQL 写核对规则进行核对。使用 HiveSQL 不仅能够减轻关系型数据库的压力,核对的效率也非常高,并且能实现逐笔核对,准确找出不一致的订单数据。
异常登记
核对出的异常订单会被登记下来,渠道对账单会涉及临界点的问题(0点的订单),有可能会放在下一个对账单中,所以当天核对出的异常并不一定是真的异常,可以先存疑,等待获取下一个对账单之后再次进行核对,如果还是有问题就进入差错系统进行差错处理。
银存核对
银存核对是统计每个清算日各个渠道应收到的或者应付的资金,与银行账户中实际收到的资金进行核对的过程。在银存核对之前,需要将每个渠道的业务明细状态进行核对,保证每笔应该清算的订单的状态一致且正常完结。这些操作现在由“渠道对账”完成。
清算机构在每个清算日会把资金做轧差后结算到支付机构的备付金账户中,轧差的公式为:
例如,一个支付渠道一天收到客户 A 和客户 B 的两笔交易,并且客户 A 有退款操作,清算机构最终给支付机构的结算金额的计算方式如图下所示。
支付金额 | 退款金额 | 渠道手续费 | |
---|---|---|---|
客户A | 100元 | 50元 | 0.5元 |
客户B | 100元 | 0.5元 | |
结算金额 | 100+100-50-0.5-0.5=249元 |
最终支付机构备付金账户会收到 249 元的打款。这笔钱与上送给清算机构的信息流是否一致也需要通过对账功能来核对。渠道的信息流与备付金账户动账的实际资金流之间的核对我们称之为银存核对。银存核对在渠道对账完成之后才可以执行,因为银存核对的一方数据来源是清算机构给的对账文件,需要将清算结构的业务明细状态进行核对,保证每笔应该清算的订单状态一致且正常完结。银存核对业务的流程如下图所示。
银存核对的数据来源一方是交易明细,即渠道对账单里的明细记录,根据接入的渠道不同会有多个对账单,通常有银联-银行卡对账单、银联-微信对账单、银联-支付宝对账单、网联-银行卡对账单、网联-微信对账单、网联-支付宝对账单等,并且每个渠道会有不同的渠道商户号,不同的渠道商户号又会区分不同的对账单。另一方是备付金账户的实际动账明细,包含备付金账户所在银行的动账明细、银联给三方支付机构开设的虚户的动账明细。
银存核对的处理流程如下图所示。
银存核对和渠道对账流程类似,对账的一方数据来源都是银联或网联的对账文件,不同点在于银存核对需要渠道对账结束之后才能执行,一来依赖渠道对账的数据,二来渠道对账如果不平,则银存核对没有意义。银存核对另一方的数据来源是备付金的动账明细,包含备付金实际动账明细,这部分明细会通过网联通知三方支付机构,还有银联虚户的动账明细,这部分明细银联会通知三方支付机构。获取数据之后对数据进行解析、存储、核对,核对出的异常也会经过存疑、二次核对、差错处理这些步骤。
- 1.1 银联/网联会把银联虚户、备付金账户的动账明细通知三方支付机构。
- 1.2 三方支付机构收到动账明细之后,对数据进行解析并存储。
- 2.1 清算机构每天定时把前一天的交易记录(包含支付记录、退款记录、手续费记录等)以文件的形式存放在指定的地址。
- 3.1 定时任务驱动渠道对账系统到指定的地址拉取清算机构的对账文件。
- 3.2 支付机构到指定的地址拉取对账文件。
- 3.3 解析对账文件,将数据转化后存储在数据库中。
- 4.1 定时任务驱动核对任务。
- 4.2~4.3 将渠道对账文件的数据和动账数据同步到 HBase 中。
- 4.4 执行核对规则,对双方的数据进行核对。
- 4.5 将核对出的异常登记到异常表中。
- 5.1 等待第二天账单到来后,对异常表中的异常单进行二次核对,如果二次核对正常就消除该笔异常单。
- 5.2 将没有被消除的异常单记入差错系统,等待差错处理。
银存核对能够核对出备付金实际动账明细和交易明细不匹配产生的资损问题,如果一个三方支付机构的备付金账户被黑客攻击,把资金直接转移,那么通过银存核对能够核对出是不是本机构正常的操作,及时发现资金漏洞。渠道对账和银存核对解决的都是外部资金安全的问题,三方支付机构内部资金安全也需要通过核对来保证。
实时核对
资金在支付机构内部的流转,一笔支付交易在支付机构内部需要经过支付核心到渠道系统实现 C 端消费者实际资金的扣除,支付核心收到支付结果之后,会通知清结算系统、账务系统进行相关的记账操作。在 T+1 日的时候支付核心会发起该笔支付的结算任务,清结算系统收到结算任务后通过计费系统计算好相关的手续费,然后请求账务系统进行内部账户资金的变更。这个流程是非常复杂的,如何保证系统之间金额、状态的一致性也是一个很重要的事情。如果出现资金和状态的不一致,那么如何及时发现问题就是防止资损的重要步骤,所以需要搭建一个实时监控支付数据的系统,防止系统之间的漏洞产生资损。
搭建实时核对系统(也称资损防控系统)的目的在于治理资损。分析发生的资损故障,发现大部分资损是因为系统的 Bug 引起的,主要表现在以下几个方面。
- 新发布项目,业务场景考虑不周全。
- 系统重复请求,下游系统没有做好幂等判断。
- 系统之间的金额不一致。
- 系统之间的状态不一致。
基于这些问题,需要有一个系统能自动、及时发现系统之间终态数据的不一致,进而发现系统的漏洞并及时修复。在这种情况下,资损防控系统就应运而生。资损防控系统的架构如下图所示。
数据清洗
资损防控的数据来源是各个支付业务系统的 Binlog 消息。
为什么监听 Binlog ?
- 数据库里的数据是最终的数据,监听 Binlog 数据的变更可以防止手工修改数据库造成的资损
- 业务数据有没有落库都可能被篡改,落在数据库中的数据被篡改的可能性要小得多,并且一旦被篡改也能第一时间监控到
- Binlog 消息是实时的,资损防对数据的实时性要求很高,需要及时发现资损问题
资损防控核对的业务数据是终态的数据,比如支付成功、退款成功、结算成功、退款失败等。非终态的数据不会被核对,因为没有到终态就无法判断数据的正确性,并且非终态持续的时间也非常短,没有必要核对。
数据的存储分成两个部分,一部分是业务数据,会存储在 HBase 中,因为如果使用关系型数据库,数据量非常大,对数据库的压力非常大,并且这些数据不是业务主链路的数据,不影响主链路的业务,所以对存储的准确性、实时性要求不高,可以存储在大数据平台。另一部分是监测点数据。什么是监测点?监测点是指触发检测规则的一个触发点,比如通过 Binlog 监听到的业务数据就可以作为一个检测点,然后通过定时任务扫描监测点,从而触发核对规则。这部分数据存储在关系型数据库中,并且会存储业务数据在 HBase 中的 Key。
规则管理
根据业务的不同,资损防控规则的复杂程度也不同,所以配置规则的方式也不同,通用规则基本能满足大多数核对的需求,定义好需要核对的字段即可。稍微复杂一点的核对规则可以使用 SpEL 表达式,再复杂的核对规则可以使用 Groovy 脚本。
规则的存储也分几个层级,因为规则是实时使用的,所以使用规则的时候会先在本地缓存里获取,如果获取不到再从 Redis 中获取,最后才从 DB 中获取,并且会把从 DB 中获取的规则同步到 Redis 和本地缓存中。
获取规则之后会执行规则,执行规则需要有数据的支撑,通常业务数据存储在HBase中,根据 Key 拉取数据即可。
任务管理
检测点落入数据库之后,会有定时任务触发检测规则来执行实际的业务检测,这个任务就是检测点任务。如果第一次检测失败,有可能是因为数据延迟导致的,可以过一段时间继续检测,所以可以创建一个异常重试的检测任务;检测成功的检测点可以及时清理以减轻对数据库存储的压力,所以需要创建一个数据清洗任务;有些核对规则需要异步核对,或者异步拉取数据,可以创建异步任务来完成;核对出有问题的异常点,有时可能是网络抖动的原因造成的,在数据量比较多的情况下会把实际有问题的异常淹没,可以创建一个二次核对的任务,对有检测异常的监测点进行隔天或者自定义时间的重新检测,进而把实际有问题的监测点筛选出来。
异常处理
异常处理分为异常告警和异常熔断两个模块。
异常告警很容易理解,一笔订单经过核对规则检测之后,如果订单的金额或者状态有异常,则需要及时通知业务、技术的相关负责人,让相关负责人采取相应的应急措施。告警也可以根据规则的不同分为不同的层级,如果一个规则是资金相关的,那么检测到异常就可能有资损,可以配置电话告警,引起相关责任人的重视。如果一个规则只是状态相关的,不涉及大的资金,则可以只设置短信告警或者工作软件告警。
异常熔断需要支付业务系统的支撑,熔断从策略上可以分为单笔熔断、业务熔断、出金熔断。单笔熔断是指在交易阶段核对出资损异常,比如重复支付,可以对第二笔支付进行熔断,从而中断该笔交易;业务熔断是指某时间段内发现某一种业务都出现资损问题,可以把该业务进行熔断,后续该业务都暂停交易,比如我们发现有大量的重复退款,那么可以针对退款业务进行熔断;出金熔断是指资金已经结算到商户的账户余额,但还没有提现到商户自己的银行卡,发现给商户重复结算资金,或者商户有风险,暂停商户的提现能力。
资损防控系统架构优点
- 实现规则可配置化,业务系统负责人可以根据业务自行在平台配置核对规则,充分发挥系统的平台性。如果业务有变更,那么只需要修改规则即可,无须修改资损防控系统。
- 支持高并发,数据收集和核对采用异步的方式,并且业务数据存储使用 HBase,针对核对规则这种常用的数据引入了三级缓存,优先使用本地缓存。对 Groovy 脚本使用编译后存储存值在本地的方式减少了编译的耗时。
- 监听 Binlog 消息而不是业务消息,通过检测底层的数据,能够及时发现数据库的数据是否被篡改,以及人为操作失误造成的资损等,并且支付业务系统没有任何接入成本。
资损防控技术流程
- 监听支付业务系统数据库变更的 Binlog 消息。
- 根据配置的数据清洗规则对数据进行清洗,清洗后的业务数据落入 HBase,并生成检测点落入 MySQL。
- 定时任务扫描数据库里的检测点,触发核对规则,根据 Key 从 HBase 中拉取数据并进行核对。
- 核对成功的数据,会有定时任务触发消洗规则删除数据库里的监测点,减轻数据库的存储压力。
- 核对异常的数据会根据配置的存疑时间判断是否继续核对,如果没有过存疑时间,则会在下次触发检测点任务中继续核对,直到过了存疑时间。
- 过了存疑时间且仍然核对异常的检测点会第一时间发送告警,通知相关的负责人排查并处理问题,如果判断交易需要熔断,则根据配置的熔断规则生成熔断点。
- 确认有异常的数据会落入差错系统,有专门的清结算人员进行差错处理。
解决资损问题需要经历三个步骤:发现问题—处理问题—及时止损,发现问题可以通过配置资损规则对数据进行核对来完成,发现的问题基本都能及时得到处理。如果是一类业务问题,单纯处理已发生的问题还可能出现大量的资损,可以把这一类问题及时熔断,暂停该类业务的交易,能够防止出现大的资损,这就是熔断的过程。熔断最核心的点在于及时终止交易,把资金留存在三方支付机构中或者不让交易扣除 C 端消费者银行卡的资金,以保证资金可控。
实时核对能够及时发现问题,发现问题之后需要及时止损,实现核对异常后根据业务进行熔断功能,支持手动熔断(人为配置熔断规则)、自动熔断(资损防控系统发现资损问题,自动生成熔断规则)两种熔断方式。手动熔断针对人为发现的一些异常,可以手工配置熔断规则,比如针对批量代发工资业务,暂时停止该业务的交易,支付核心收到代发工资业务的指令,暂时停止执行该业务,会把数据存储起来,过一段时间进行重试,判断是否熔断已经解除,如果解除了,那么业务继续执行。自动熔断需要建立在实时核对核对的异常非常准确的基础上,相据核对的异常自动生成熔断规则。
熔断的维度分为单笔交易熔断、业务类型熔断、商户出金熔断三种。单笔交易熔断针对的是单笔交易,这种熔断策略对实时性要求非常高,需要及时发现问题,只支持自动生成熔断规则。如果实时核对检测到一笔订单重复支付,则可以针对该笔订单生成熔断规则,在结算阶段暂停该笔订单的结算。业务类型熔断针对的是某个业务,一般会手工生成熔断规则,系统自动生成熔断规则的风险会比较大。商户出金熔断是及时止损的最后一道防线,针对商户生成熔断规则,暂停商户的出金,一般商户会在 T+1 日出金,所以尽量在这个时间段内处理核对出的异常,解除熔断,做到商户无感知。
熔断分两个阶段,第一阶段是生成熔断规则,第二阶段是根据熔断规则熔断交易。熔断规则的生成有手工生成和系统自动生成两种方式,熔断规则生成之后会存储在数据库中。熔断系统会提供API接口,支付业务系统做交易的时候会调用API接口判断该笔交易是否需要被熔断,如果需要被熔断就暂停交易,等待下次处理。接入熔断系统API接口的有支付核心、清结算系统、账务系统。
有熔断就需要解熔断,针对商户出金、单笔交易、业务类型的风险解除之后,需要解除熔断策略,解除熔断策略一般需要手工在运营界面操作。业务负责人确定风险解除之后对熔断规则进行解除,当支付业务系统重试任务调用熔断API接口的时候,会发现熔断已经解除,交易继续。
离线核对
离线核对和实时核对都是针对三方支付机构内部系统之间的核对,两者的区别在于实时核对是对支付交易单实时进行核对,对时效性的要求很高(在分钟级别甚至秒级别),需要快速发现资金的问题并予以处理。离线核对对时效性的要求没有那么高,一般是在 D+1 日核对。
读者可能会有疑问,有了实时核对为什么还需要离线核对?核心原因在于二者核对数据的维度不同,主要体现在以下四个方面。
第一,支付机构可能有批量操作的业务,比如批量代发工资,单位时间内产生的交易量非常大,实时核对要监控多个系统的数据,数据量是交易量的数倍,所以对实时核对系统的资源占用率会很高,有可能影响其他的核对业务。所以像这种批量操作可以采用离线核对。
第二,支付机构会收取相应的手续费,手续费的收入是支付机构最重要的收入来源,对数据的安全性要求也很高。可以使用离线核对对每天手续费的收入进行核对,这样既能够保证资金的正确性,又可以依据核对数据出具相关的报表。
第三,支付机构通常会开通金融业务功能,金融业务属于支付之外的系统,但是需要使用支付渠道完成资金相关的操作,比如分期付款等,开展金融业务也会有相关的收入,这部分做入也可以使用离线核对功能进行核对,并出具相关的报表。
第四,支付机构服务的对象是商户,商户也有对账需求,但是商户通常不具备开发能力,可能只能人为核对账目,不仅耗费资源,而且也不准确,在这种情况下,支付机构开发能力用核对功能,商户只需要上传需要核对的数据就可以实现核对功能,所以可以把高纯核对底层功能开放给商户使用。
离线核对的架构和实时核对的架构类似,主要分成四个模块:数据清洗、规则管理、任务管理和异常处理。不同点在于,资损防控对实时性要求很高,并且资损防控核对出异常之后有可能触发熔断策略,从而避免更大的资损。而离线核对本身核对的数据基本已经相隔一天的时间,所以对核对出的异常进行差错处理即可。
1.数据清洗
离线核对的数据来源主要有三个:支付内部系统、金融业务系统(或者其他业务系统)和商户(上送的对账文件)。
离线核对系统通过监听支付业务系统的 Binlog 消息来获取数据,和实时核对的区别在于实时核对需要核对资金流转的每一个支付系统(渠道系统、账务系统、支付核心、清结算系统等)。而离线核对只需要核对资金的入口和最终的动账即可,即只需要监听支付核心和账务系统的数据,离线核对不需要关注中间资金流转的过程。只要入口和最终的数据一致,就认为资金是没有问题的。
金融业务数据和支付业务数据类似,都是通过监听 Binlog 消息来获取的,因为都是支付机构内部的系统,所以数据清洗的方式也类似,基本都是核对终态的数据。
如果把核对功能开放给商户使用,那么商户对账一方的数据来源是对账单,另一方是支付机构内部的动账数据。支付机构内部的动账数据很容易获取,商户的对账文件需要手工上送,离线核对收到对账单之后对数据进行解析并落库,然后进行核对。不同的是,这部分核对出的异常数据不需要进入支付机构的差错系统,只需要告知商户即可。
离线核对核对的数据量通常不会很小,所以业务数据同样会存储在大数据平台,关键的核对点等数据会存储在关系型数据库中。
2. 规则管理
离线核对的规则同样支持通用规则、SpEL 表达式规则和 Groovy 脚本规则。其中提供给商户的对账功能只需要支持通用规则即可,因为商户不能编写 SpEL 表达式和 Groovy 脚本。离线核对给商户提供的核对功能也是相对简单的。离线核对对核对规则的存储同样采用三级存储。
3. 任务管理
离线核对的任务有监测点任务、异常重试任务、规则同步任务、数据清洗任务。监测点任务会根据配置的检测规则,定时执行检测规则,判断业务数据是否有异常,如果有异常就暂时落入存疑库。这个时候重试任务会触发存疑库里的检测机制,如果还是有问题就会记录异常单,落入差错系统。规则同步任务负责检索数据库中的规则是否与缓存中的规则同步,如果不同步,则修改缓存中的规则。
4. 异常处理
异常处理分为两个模块:异常告警和异常管理。
检测出的异常会通过告警系统第一时间发送告警消息给相关业务的负责人,不同的业务对接收告警信息的人会有不同的分组,并且会根据业务的重要程度区分告警的等级。
异常管理包括异常登记、异常分类、异常处理、异常结果展示等,异常登记是把核对出的异常信息存入库中并提供查询页面。核对出的异常根据业务的不同会有不同的分类,不同分类的异常处理的方式也不一样,在异常处理阶段会把分类后的异常落入差错系统,这部分数据基本可以确定需要调账处理,经过处理之后的异常也要及时更新状态避免重复处理。
对账闭环功能
闭环功能建设
对账的目的是“兜底”,及时发现系统漏洞带来的资金损失,并对已损失的资金进行处理(追款或者补偿)。渠道对账、银存核对、资损防控、离线核对 4 个核对功能解决了支付交易后发现平台,最终实现 数据核对→异常登记→熔断止损→异常处理→差错处理 的闭环,如下图所示。
1. 数据核对
渠道对账、实时核对、离线核对、银存核对都实现了数据核对的功能,数据核对分几个步骤:数据拉取→数据清洗→数据存储→数据核对。数据核对能够帮助我们实现自动异常发现功能,把有异常的交易单找出来。
2. 异常登记
在数据核对阶段核对出的异常要及时登记存档,以备后续处理异常时使用,异常订单通常否真的有异常,以及是否需要及时止损。存储在数据库中,通常数据量不会特别大,登记之后会对相关的数据再进行分析研究,判断是否真的有异常,以及是否需要及时止损。
3. 熔断止损
异常订单存储在数据库之后,会根据异常信息对订单数据进行相关的分析,是单笔异常、业务异常还是风险异常,不同的异常类型有不同的应对策略,最核心的点在于及时止损。如果是单笔异常,则对单笔交易进行熔断,如果是业务异常,则对业务进行熔断,避免更大的资金损失。
4. 异常处理
及时止损之后,就有充足的时间去处理系统的异常,是系统 Bug 还是人为操作,需要分析出根本的原因并进行处理。
5. 差错处理
对于异常产生的差错单要及时处理,对异常的数据要及时修复,比如重复支付,要进行退款操作,重复结算也要联系商户进行资金退回的操作。
差错处理
差错处理是把各个核对系统核对出的差错进行调账处理,以达到资金平衡的目的。对需要处理的差错从来源上划分,可以分为外部核对差错和内部核对差错。外部核对差错是支付机构和外部系统核对出的差错,由渠道对账、银存核对产生;内部核对差错是资损防控、离线核对针对三方支付机构内部系统核对出的差错。
要搞清楚外部差错,就需要弄明白什么是长款,什么是短款。
1. 长款
什么是长款?我们举个例子:客户消费了100元,支付渠道(银联、网联、微信、支付宝)的对账单里有该笔交易支付成功的记录,但由于网络或者其他原因三方支付机构没有收到支付成功反馈,所以该笔记录是支付中或者支付失败,像这种支付渠道有成功记录而三方支付机构没有成功记录的差错对于三方支付机构来说就称为长款。
2. 短款
短款和长款刚好相反,支付渠道里没有该笔订单支付成功的记录,而三方支付机构对于该笔订单的记录状态是支付成功,这样的差错对于三方支付机构来说就称为短款。
不管是内部产生的差错单还是外部产生的差错单,最终都会汇总到差错系统中统一处理。差错系统既要提供查询差错单的运营能力,也要提供处理差错单的处理能力。差错系统的架构如下:
从差错系统的架构图可以看到,差错系统分为数据来源层、差错分类层、差错处理层,并且提供差错数据处理的运营能力。
1. 数据来源
差错系统的数据来源是渠道对账、银存核对、资损防控、离线核对几个核对系统核对出的异常单,核对系统核对出的异常信息会经过一系列的筛选,最终落入差错系统。比如实时核对第一次核对出现异常,要等过了存疑期并且再经过二次核对之后才会落入差错系统。换句话说,就是进入差错系统的数据基本可以确定是有问题的。同样,渠道对账核对出的异常单也需要经过二次核对,过了存疑期才会落入差错系统。
2. 差错分类
不同的核对系统是按照不同的业务划分的,不同核对系统产生的差错类型也不一样,但是可以统一收拢在差错系统中处理。渠道对账会根据业务分为支付、退款类型的差错,支付、退款业务类型又包含长款、短款类型的差错。不同场景下处理差错的方式也不一样。
支付业务的差错单可以分为四种类型。
差错类型 | 差错原因 | 处理方式 |
---|---|---|
长款 | 渠道账单有该笔交易,三方支付机构没有该笔交易 | 1. 三方支付机构补单,然后可以对平。 2. 支付平台侧对所补订单进行退款。由于这一笔订单是多收了用户的,补单只是为了对平,对平后还是需要退款,将多收的钱退回给用户。 |
短款 | 三方支付机构有该笔交易,渠道账单没有该笔交易 | 由于支付通道侧比三方支付机构少订单,比如支付通道对账单有99条,我们有100条订单,最后三方支付机构账单是10 000元,对方因为少了1单订单记录,汇总是9900元。三方支付机构会认为自己少收了钱,此种情况我们称为“短款”。 短款的情况是支三方支付机构认为成功了,实际上银行并没有收到请求。 对于这种情况,处理方式如下: 第一步:短款追回或者短款坏账。处理的步骤如下。第一步,去“调单”,判断是不是通道侧失误,漏了。由于每笔交易在支付通道与支付平台之间都有报文存在,无论是发起交易请求还是交易结果回复,如果明确收到通道侧返回支付成功报文,可以去追责,要求支付通道侧补齐这个订单,认这个账。 第二步:如果支付通道侧不认或者无法界定责任,需要支付平台侧采取补偿机制,重新发起扣款,补扣款项,避免资损。如果是非快捷交易,可能无法重试,那么需要联系商家冻结订单或者联系用户重新支付。如果货已经发出且用户不愿意再支付,那么就是资损。从这个角度也能看到,免密支付或者快捷交易在支付里不仅能用于改善用户体验、提升支付成功率,也能用于事后代扣、避免资损。 需要说明的是,在免密支付的能力用于补扣款的场景中,一定要提前在用户进行绑卡的协议文案中说明得到用户授权,否则用户是可以联系发卡行拒付的。 |
金额不匹配 | 在对账过程中,三方支付机构账单金额和渠道账单金额不相等 | 两边账单明细都对得上,但是金额不一致。这种情况很少见,需要以一方为主进行差账处理,修改金额,使得两边账单一致。 |
状态不匹配 | 在对账过程中,三方支付机构账单状态和渠道账单状态不一致 |
退款业务的差错单也可以分为四种类型。
差错类型 | 差错原因 |
---|---|
长款 | 渠道账单有该笔退款交易,三方支付机构没有该笔退款交易 |
短款 | 三方支付机构有该笔退款交易,渠道账单没有该笔退款交易 |
金额不匹配 | 在对账过程中,账单金额和渠道账单金额不相等 |
状态不匹配 | 在对账过程中,账单状态和渠道账单状态不相等 |
内部对账差错分类:内部对账的差错分类比较简单,分为金额不一致和状态不一致两种情况。金额不一致是指两个系统都有该笔交易,但是总金额对不上。状态不一致包含两种情况,一种情况是单边账,即只有一个系统有该笔交易,另一个系统没有;另一种情况是两个系统存储的同一笔交易的状态不一致,比如一个系统存储该笔交易的状态是成功,另一个系统存储的状态是失败。
5. 差错处理
差错处理分为两个阶段:存疑阶段和处理阶段。
存疑阶段是对落入差错系统的数据有一个存疑期,这里的存疑期与对账的存疑期类似,比如渠道对账有日切的问题,交易记录有可能会在下一个账单中而不在当前账单中,所以需要等待下一个账单过来之后再次进行核对,如果还是有问题,才确认为差错。
存疑阶段过了之后,进入处理阶段的异常单基本可以确认都是有差错的,需要经过调账处理。如果是内部的差错,一般会调整账务系统把资金调平,如果是渠道对账的长短款,通常以渠道的对账文件为准来调整三方支付机构内部的资金。
6. 运营能力
差错单的展示、查询、筛选、处理都需要运营界面,通过运营界面能够清楚地看到一共产生多少笔差错,都是什么类型的差错,并且可以跟踪差错处理的过程。