可以说,对账是支付系统中最头疼的事情。对于每笔交易,所有参与者的记录必须匹配无偏差。对账系统的工作是发现记录中的差异,即关闭账户;然后手动或自动解决这些差异,即平衡账户。对于电子商务系统,每笔交易都必须兼容所有相关方:交易主体,如果发起者是个人,必须能够从个人交易历史中找到这笔交易。但是,大多数人并没有保存电子记录,所以一般会提供账单或交易记录,供用户下载,供用户自行查阅。交易对手一般是商家。商户端对账流程与用户端相同,仅提供对账单。在交易渠道方面,这是对账的重点。一是验证交易流程,二是验证交易佣金。毕竟渠道是租来结算的。哪些记录需要核对?目前主要有两种:一是交易记录;另一个是退款记录。这里以交易记录的处理为例,退款记录也可以类似处理。1.对账流程一般来说,对账流程包括以下几个步骤:渠道对账单下载、本地交易记录准备、账户滚动、账户余额。1.1渠道对账单下载银行、第三方支付、银联等,基本都提供对账单下载功能。但是,也有少数银行做的不够或者做的太好。他们只提供账单查询后台,不提供报表下载功能。对于开发人员来说,这里有几个陷阱:语句有不同的格式。文本、XML和csv都可用。为了以后统一处理,需要在票据下载后进行标准化处理。有不同的下载方式,包括HTTP、HTTPS和FTP。下载器需要根据通道的协议进行处理。下载时间不一,一般在凌晨1:00以后,有的要到中午12点才能使用。如果无法在预定时间获取到数据,需要注意重试读取。稳定性差。FTP服务器出现问题很常见。通道端解决方案经常重启。所以需要重试机制。看一下第三方支付的对账单:银行直连的对账单1.2渠道对账单标准化找个例子给大家看看,比如微信的对账单,是csv格式的,包括以下信息:交易时间:这是微信端支付完成的时间。这一次可能是一个陷阱。公众号ID、商户号、子商户号、设备号:这些信息需要核实,确保是自己下的单,不要让微信发老王的单;微信订单号、商户订单号:这两个是订单的核心。前者是微信端生成的订单号,包含在微信支付接口的返回值中。但如果没有收到返回值,则本地记录中可能为空。后者是我们发给微信的订单号,一般作为下单的依据。该值将出现在两侧的数据中。用户ID、交易类型、交易状态、支付银行、货币类型、总金额、企业红包金额:这些是订单的核心字段,必须保证双方一致。产品名称、商户数据包、手续费、费率:这些是可选的验证。某宝声明为文本格式,以空格分隔。他们的就简单多了,只有商户订单号、交易流水号、交易时间、付款时间、付款人、交易金额、交易类型、交易状态等字段。由于每个渠道的账单格式不同,在拿到账单后,下一步就是对账单进行标准化,以便统一处理滚动和后续工作。规范化的计费数据可以放在文件系统或数据库中。这取决于交易数据量。如果每天的量超过一百万,用文件系统比较合适。数据库操作比较慢,浪费资源。基于文件系统的标准化涉及以下内容:文件格式标准化,统一使用csv或json或xml格式。如果你使用hadoop或者spark来协调,使用csv是一个不错的选择。统一文件存储文件目录和文件名需要遵循统一的命名规范。为了加快处理速度,我们使用hdfs作为文件系统,有利于对账的后续处理。1.3本地交易记录的准备本地交易记录的准备一般有以下几种方法:什么都不做,直接使用原始数据。由于大多数系统使用mysql,这也意味着在MySQL上进行协调。对账需要大量的数据查找工作,这势必会影响线上业务。当数据量很大时,比如超过100万,就不适合了。当然,还有一种方案是使用备库进行对账,简单又不影响线上业务。这是典型的以空间换时间的做法。如果业务很大,需要分表分库处理,对账数据的准备也不同。使用分库也不现实,因为分库一般是按照entityid来划分的,而不是channelid。这样就需要在多个数据库上进行对账,降低了效率。分表分库建立从库也是非常耗费资源的。在这种情况下,需要将一份数据同步到(hdfs)文件系统或NOSQL数据库中。由于交易记录是支付系统的核心数据,因此有大量的应用,如征信、风控等,都需要交易记录数据。这些应用对交易记录的要求并不完全一致。为了提高性能,事务记录将使用异步方法向用户传递数据。当交易记录入库时,消息被传递到消息系统。用户监听这条消息,一旦收到新的消息,就去交易记录库中查询数据,获取数据并更新到库中。关于这种数据同步的文章很多,这里就不详细介绍了。1.4排序是根据客户订单号,比较本地交易记录与渠道交易记录是否一致。从算法的角度来说,就是计算两个数组的差值。在单机上运行时,可以使用的算法有很多,这里不再详细介绍。我们建议使用mapreduce来滚动帐户。这样做的好处是可以将通道提供的记录和本地记录按照订单号show到同一个reduce进程中,方便进行数据比对。滚动账户最大的坑就是分段点的问题。比如0:00作为切点,就有问题了。本地23:59发起的交易可能在通道侧00:01处理,这笔交易成为次日的账户。在实际处理中,一笔交易是在通道端处理的,可能需要几分钟的时间。对于在分界点附近无法确认的科目,制作一个时间窗口,时间窗口内的数据留待次日对账时进一步处理。1.5如何处理发现双方账户余额数据不一致?当数据量不大时,记录下来,手动筛选。但是如果数据量很大,每天几千条,人工处理成本太高。对此没有统一的处理方法。需要根据有问题的数据进行分析,然后自动处理。对于交易记录的对账处理,主要有以下几种情况:长支付:不是在本地支付,而是通过支付渠道支付。这主要是本地没有正确接收到通道发送的异步通知导致的。一般处理是修改本地状态为已付款,并做响应的后续处理,如通知业务方等短付款:本地已付款,但付款通道无记录;或者本地没有记录,但是支付渠道有记录。除了排除跨日因素外,这种情况非常少见,需要了解具体原因后再处理。金额不一致:本地支付已支付,支付通道已支付,但金额不同。这需要人工验证。对于退款的对账处理,主要有以下几种情况:如果本地没有退款,但是支付渠道已经退款,则以支付渠道为准,修改本地状态为已退款,开始后续处理。已在本地或通过支付渠道进行退款,但金额不同,需要人工验证;已在当地退款,但没有支付渠道记录;或者有支付渠道的记录,但是本地没有。除了排除跨日因素外,这种情况非常少见,需要了解具体原因后再进行处理。2.对账架构基于微服务的对账系统实现参考架构如下:2.1报表下载报表下载组件每天定时触发,从支付通道服务器下载报表。目前下载语句主要有HTTP(S)和FTP两种方式。在技??术选择上,HTTP(S)可以使用apachehttpclient实现连接池和断??点续传,FTP也可以使用ApacheCommonsNetAPI。不管是哪一种,都需要设置重试次数和连接超时时间。在设置重试次数和间隔时需要小心。如果重试太频繁,很容易把服务器挂掉。如果时间间隔过大,会阻塞后续的处理步骤。5到10分钟是合适的重试间隔。链接超时是指当服务器出现问题时,如果在规定的时间内无法获取到数据,连接将自动断开。这个很容易被忽视。我们曾经遇到过系统问题。通道端的FTP在假死后重启,导致我们的客户端挂起等待重连。另外需要注意的是,有些语句下载是支持分页下载的。2.2语句转换将语句转换为标准格式,为执行Mapreduce任务提供对账支持。每个通道的语句格式不同,需要单独开发转换程序。转换程序主要有两个操作:解析源文件,转换成标准格式并输出。2.3滚账MR如前所述,滚账MapReduce程序运行在Hadoop上,以交易号为key,检查通道订单与本地交易记录的差异,输出差异记录。***将差异记录导入差异表。总之,对账工作不复杂也不繁琐。需要细心,深入了解业务,选择合适的架构。【本文为专栏作者《凤凰牌老熊》原创稿件,转载请微信联系作者公众号《凤凰牌老熊》转载】点此阅读作者更多好文
