支付业务与技术架构学习总结(4)——对账相关业务知识及对账系统总结

前言

在互联网行业中只要涉及到支付,必然就会有对账的需求,几乎所有互联网公司的业务中多多少少的都会涉及到支付,大一点的公司甚至都标配有了自己的第三方支付公司,因此对账具有普遍性。对账系统是支付体系中最重要的一环,也是保证交易、资金安全的最后一道防线。在大多数的互联网公司中,一般都会有独立的对账系统来处理,比如:电商平台、互联网金融、第三方支付公司等。对账是支付系统中的一环,因此在对账前我们先了解一下相关的业务知识。

一、业务知识

1、什么是对账

传统的对账(核对账目):在会计核算中,为保证账簿记录正确可靠,对账簿中的有关数据进行检查和核对的工作。在银行或者第三方支付中,对账其实是对一定周期内的交易进行双方确认的过程,一般都是在第二天银行或者第三方支付公司对前一日交易进行清分,生成对账单供平台商户下载,并将应结算款结算给平台商户。在往下一层,在互联网金融行业或者电商行业中,对账其实就是确认在固定周期内和支付提供方(银行和第反方支付)的交易、资金的正确性,保证双方的交易、资金一致正确。

广义的对账:所有跨应用的数据交互,理论上都应该进行对账。所以对账也可以分为信息流对账,资金流对账。信息流对账也一般用在自己内部系统的对账,比如支付系统的支付数据和业务系统的业务数据进行对账,保证资金交易和业务交易的一致性。资金流对账也就是支付系统和银行或者第三方支付系统之间的资金交易对账。

2、对账方式:

单向对账:一般拿第三方支付机构或银行流水,与自己系统进行对账,防止出现掉单问题;

双向对账:两个应用间的流水进行双向核对,如订单与财务系统,既要保证财务系统支付成功的记录,订单系统也是成功的;也要确保订单系统记录成功的记录,财务系统也成功。我们一般采用双向对账的方式进行对账。

对账常见问题:(1)不同系统日切点不一致问题:滚动对账;(2)差错处理:补账,补偿(退款)

3、相关概念

轧帐和平帐:每一笔交易,都要做到各参与者的记录能够吻合,没有偏差。对账系统的工作,是发现有差异的记录,即轧帐;然后通过人工或者自动的方式,解决这些差异,即平帐

长款和漏单:在以平台交易为基准的情况下和银行对账,发现周期内的交易,平台有此订单而第三方支付中没有订单,成为平台长款。平台长款一般是由于用户在支付的时候跨天的情况,比如用户在23:58分创建了订单,在第二天的凌晨00:03分进行了支付。在以银行交易为基准的情况下对账,银行有此订单而平台无此订单,即为平台漏单。平台漏单很少见,一般直接转人工处理。

账户体系在一般的支付体系中会分为登录账户和支付账户,支付账户指用户在支付系统中用于交易的资金所有者权益的凭证登录账号指用户在系统中登录的凭证和个人信息。一个用户可以有多个登录账户,一个登录账户可以有多个支付账户,比如零钱账户、储值卡账户等。一般来说,支付账户不会在多个登录账户之间共用。对账的交易一般都是支付账户参与交易。

交易与账户账户设置,一般是从交易开始的。 交易的实现必须有账户的支持,账户是交易的基本构成元素。 从支付系统的角度,交易中涉及到的资金流是资金从一个账户流向另一个账户。 发起交易的一方,被称之为交易主体,他可以是一个人,也可以是一个机构。

清算和结算清算主要是指不同银行间的货币收付,可以认为是结算进行之前,发起行和接收行对支付指令的发送、接收、核对确认,其结果是全面交换结算工具和支付信息,并建立最终结算头寸。结算是指将清算过程产生的待结算头寸分别在发起行、接收行进行相应的会计处理,完成资金转移,并通知收付双方的过程。当前,大多数银行结算业务的完成主要通过两类账户:一是银行间互相开立的代理账户,二是开立在央行、独立金融机构如银联、或者第三方支付机构的账户。清算:计算各方应收应付钱款的时间与金额。结算:根据清算的结果在指定的时间对各方进行实际的资金转移操作。

资金池用户备付资金(如充值)统一放在企业的银行账户中,企业可以随意支配这些资金,即为资金池。与之对应的是第三方托管,用户备付资金是放在企业在第三方支付机构为用户开设的虚拟账户中,企业无法随意取出这些资金。现在互联网金融全面要求接入银行存管,就是银行会为每个用户创建一个资金账户来保护用户的资金,互联金融公司不能随意划拨这些资金账户中的金额。

二、对账系统

1、对账设计

支付业务与技术架构学习总结(4)——对账相关业务知识及对账系统总结_第1张图片

 

对账系统的设计阶段,将对账系统分为四个模块,每个模块的负责自己的职能。

  • 文件获取模块:下载或者读取各渠道对账文件
  • 文件解析模块:创建不同的解析模板,根据渠道和文件类型获取对应的解析模板进行解析
  • 对账处理模块:对账的业务逻辑处理
  • 差错处理模块:处理差错池中的订单

一般会设计一个定时任务,每天固定的时间点触发,定时驱动调度类分别调用四个模块来处理对账。也有的银行会主动的推送对账单,再通过http回调来触发对账流程。

2、对账算法

一、流程:

1、从上游渠道(银行、银联等金融机构)获取对账文件,程序逐行解析入库;
2、在程序处理中,以上游对账文件的表为基准,程序逐行读取并与我们系统的交易记录对比账务记录(有账务系统情况下,合理方案应该是于账务记录)对比,查找出差异记录;
3、以我们系统的交易记录对比账务记录为基准,程序逐行读取与上游对账文件对比,查找出差异记录。

二、缺陷:

1、对账过程中查询相关数据,如果数据量巨大,对数据库性能影响较大,而且对账逻辑扩展极为麻烦;
2、逐行比对算法效率较低,但算法上并无好的优化余地。如果采用数据库INTERSECT、MINUS对数据库压力也高;
3、在业务量大的情况下(例如有上百家上游渠道需要对,每一家都有几十万条交易记录),对账服务器及数据库服务器负荷较高。即便采用读写分离,对账时候使用读库,压力一样很大;
4、导入批量文件,逐行入库效率较为低下(每一次都需要建立网络连接、关闭连接)。

三、改进:

1、涉及网络传输的,尽量采用批量方式操作,减少网络消耗及时间消耗;
2、使用Redis等NOSQL数据库,降低数据库服务器的压力。同时在扩展上也容易,一台Redis服务器不够,可以无限制增加用于对账用的服务器;
3、使用Redis的set集合的sdiff功能,利用Redis sdiff算法的高性能,比对上游记录和我方记录的差异。

3、对账流程

支付业务与技术架构学习总结(4)——对账相关业务知识及对账系统总结_第2张图片

(1)、下载对账单

银行,第三方支付,银联等,基本都会提供对账单下载的功能。不过也有少数工作做不到位或者太到位的银行,只提供账单查询后台,不提供对账单下载功能。对开发人员来说,这里有几个坑:

  • 对账单格式不一。文本,XML,csv的都有。为了后续能够统一处理,在账单下载完成后,需要进行标准化处理。
  • 下载方式不一,HTTP,HTTPS,FTP的,都有。下载程序需要按照渠道的协议来处理。
  • 下载时间不一,一般是凌晨1点后,到中午12才能用的也有。如果在预定的时间取不到数据,需要注意重试读取。
  • 稳定性差。FTP服务器出问题那是常有的事。渠道侧解决方案往往就是重启。所以重试机制是必要的。

看一下第三方支付的对账单情况:

支付业务与技术架构学习总结(4)——对账相关业务知识及对账系统总结_第3张图片

银行直连的对账情况:

支付业务与技术架构学习总结(4)——对账相关业务知识及对账系统总结_第4张图片

技术选型上,HTTP(S)用apache httpclient即可实现链接池和断点续传, FTP也可以使用Apache Commons Net API。 但不管是哪一个,都需要设置重试次数和链接超时间。重试次数和间隔的设置需要小心,重试太频繁,容易把服务器打死.;时间间隔太大,又会阻塞后续处理步骤。5~10分钟是一个合适的重试间隔区间。链接超时指在服务器出现问题时,连接在指定时间内获取不到数据即自动断开。这个很容易被忽略。我们有一次系统出问题,是渠道侧的FTP假死后重启,导致我们的客户端挂住,一直在等待重新链接。

渠道对账单标准化:找个例子大家看看, 比如微信的对账单,他是csv格式的,包括如下信息:

  1. 交易时间:这是在微信侧的支付完成的时间。 这个时间会成为一个陷阱。
  2. 公众账号ID,商户号,子商户号,设备号: 这些信息需要做验证,确保是自己的单子,不要让微信把老王家的单子也给发过来了;
  3. 微信订单号,商户订单号: 这两个是对单的核心。前者是微信侧产生的订单号,在微信支付接口返回值中有。但是万一收不到这个返回值,那在本地记录中可能就空了。 后者是我们发送给微信的订单号,一般用这个来做对单依据。两边的数据中都会有这个值。
  4. 用户标识,交易类型,交易状态,付款银行,货币种类,总金额,企业红包金额: 这几个就是对单的核心字段,必须确保双方是一致的。
  5. 商品名称,商户数据包,手续费,费率:这些是可选验证。

而某宝的对账单,是文本格式的,用空格隔开。他们家的就简单很多,只有商户订单号,交易流水号,交易时间,支付时间,付款方,交易金额,交易类型,交易状态这些字段。

支付业务与技术架构学习总结(4)——对账相关业务知识及对账系统总结_第5张图片

由于每个渠道的账单格式都不尽相同, 在得到账单后,下一步是对账单做标准化处理,这样轧帐以及后续工作就可以统一处理了。 标准化后的账单数据可以放在文件系统或者数据库中。这取决于交易数据量。每天百万以上的量,还是使用文件系统,比较合适。数据库操作相对比较慢,也浪费资源。基于文件系统的标准化涉及如下内容:

  • 文件格式标准化:统一使用csv或者json或者xml格式。如果是使用hadoop或者spark来对账,使用csv是个不错的选择。
  • 文件存储统一化:文件目录,文件名都需要遵循统一命名规范。

为了加快处理速度,我们使用hdfs作为文件系统,有利于后续的对账的处理。

本地交易记录准备:

本地交易记录的准备,总的来说有如下方法: – 啥都不做,直接用原始数据。鉴于大部分系统使用的是mysql,这也意味着在MySQL上做对账。对账时需要大量的数据查找工作,必然会影响线上业务。在数据规模较大,比如超过100万时,就不太合适了。

  • 当然,还有一个选择是使用备库来执行对账,这样既简单,也不影响线上业务。这是典型的空间换时间的做法。
  • 如果业务大到需要分表分库才能处理,那对账数据准备也不一样。使用分库也不现实,因为分库一般是按照主体id,而不是渠道id,来分库,这样对账就需要在多个库上进行,效率反而降低了。而对分表分库建立从库也非常耗费资源。这种情况下,需要同步一份数据到(hdfs)文件系统中,或者NOSQL数据库上。

由于交易记录是支付系统核心数据,有大量的应用,如信用、风控等,都需要交易记录数据。这些应用对交易记录的需求还不完全一致,为了提升性能, 交易记录会使用异步的方式来将数据投递给使用方。 交易记录在入库时,投递消息到消息系统中。使用方监听这个消息,一旦收到新消息,则从交易记录库中查询数据,获取数据并更新到库中。

(2)、创建批次:创建批次一方面是为了防止重复对账,另一方面需要在对账结束的时候将对账的结果信息存储到批次中。

(3)、解析文件:解析文件主要是将下载的对账文件解析成我们可以对账的数据类型并且入库。解析的文件不同渠道有不同的类型,因此也可以设计成不同的解析模板,使用工厂模式将不同格式的文件解析成可以对账的统一数据类型。解析的文件类型一般包括:json、text、cvs、excle等,另外部分银行会对账单做加密或者提供zip打包的格式,这里就需要额外开发zip工具类和加解密工具类进行处理。对账文件中包含的主要信息有:商户订单号、交易流水号、交易时间、支付时间、付款方、交易金额、交易类型、交易状态这些字段。

4、对账处理

(1)对账处理的核心逻辑步骤

  • 查询平台所有交易成功的订单
  • 查询平台所有的交易订单
  • 查询平台缓存池中的数据
  • 查询银行交易成功的订单
  • 开始以平台的数据为准对账,平台长款记入缓冲池
  • 开始以银行通道的数据为准对账

(2)以平台订单为基准对账逻辑

以平台所有交易成功的订单为基准,遍历银行订单的所有数据,找出订单号相同的订单,对比订单的金额、手续费是否一致。如果一致跳过;如果不一致,平台订单进入差错池;如果在银行订单中没有找到此笔交易,订单进入缓存池,记录平台长款。同时统计对账相关金额和订单数。

(3)以银行订单为基准对账逻辑

以银行的交易数据为基准,遍历所有平台的交易(包括未成功的订单),找出订单号相同但支付状态不一致的订单,在进行对比金额存入差错池。如果没有在平台的交易中找到此订单,再从缓存池中遍历查找,找到对应的平台订单验证金额是否一致,不一致进入差错池。如果在缓存池汇中依然没有找到对应的订单,直接进入差错池,记录平台漏单。同时统计对账相关金额和订单数。

5、对账统计

根据对账处理中,统计的相关信息包括:对账完成时间、对账是否成功、平账的金额和订单数、差错的金额和订单数、缓存池金额和订单数等。

6、差错处理

发现两边不一致的数据,那应该如何处理?数据量不大时,记录起来,人工甄别就行。但如果数据量很大,每天上千条,人工处理就成本太高了。这个没有统一的处理方法,需要根据有问题的数据,做个分析,然后做自动处理。 针对交易记录的对账的处理,主要有如下情况:

  • 本地未支付,支付渠道已支付。这主要是本地未正确接收到渠道下发的异步通知导致。 一般处理是将本地状态修改为已支付,并做响应的后续处理,比如通知业务方等。
  • 本地已支付,支付渠道已支付,但是金额不同,这个需要人工核查。
  • 本地已支付,但是支付渠道中无记录;或者本地无记录,支付渠道有记录。在排除跨日因素外,这种情况非常少见,需要了解具体原因后做处理。

针对退款的对账处理,主要有如下情况:

  • 本地未退款,支付渠道已退款,则以支付渠道为准,修改本地为已退款状态,并触发后续处理。
  • 本地已退款、支付渠道已退款,但是金额不同,需要人工核查;
  • 本地已退款,但是支付渠道无记录;或者支付渠道有记录,但是本地没有。 在排除跨日因素外, 这种情况非常少见,需要了解具体原因后做处理。

你可能感兴趣的:(支付业务与技术架构学习总结,支付系统)