可以说,对账是支付系统组合头疼的事情。每一笔交易,都要做到冤有头债有主。
对电商系统来说,每一笔交易,在所有相关主体侧都要能对得上:
- 交易主体侧,如果发起人是个人,必须能够从个人交易历史记录中找到这笔交易。但一般来说,个人不会保留电子记录,所以一般是提供可以下载的账单或交易记录,让用户自己对去。
- 交易对手侧,一般是商户。商户侧对账处理同用户侧,一般也仅提供对账单。
- 交易渠道侧,这是对账的重点,一是核实交易流水,二是几圈交易佣金,毕竟是租用人家通道做结算的。
对账处理流程
一般来说,对账流程涉及到如下步骤: 渠道对账单下载、本地交易记录准备、轧账、平账。
渠道对账单下载
银行,第三方支付,银联等,一般都会提供对账单下载的功能。不过也有少数工作做不到位或者太到位的银行,只提供账单查询后台,不提供对账单下载功能。 对开发人员来说,这里有几个坑:
-
对账单格式不一。文本,XML,cvs的都有。为了后续能够统一处理,在账单下载完成后,需要进行标准化处理。
-
下载方式不一,HTTP,HTTPS,FTP的,都有。下载程序需要按照渠道的协议来处理。
-
下载时间不一,一般是凌晨1点后,到中午12才能用的也有。如果在预定的时间取不到数据,需要注意重试读取。
-
稳定性差。FTP服务器出问题那是常有的事。渠道侧解决方案往往就是重启。所以重试机制是必要的。
看一下第三方支付的对账单情况:
| 渠道 | 对账周期 | 账单提供方式 | 账单文件格式 |
|---|---|---|---|
| 支付宝 | 每天 2:10 | HTTPS | XML |
| 支付宝退款 | 每天3:10 | HTTPS | XML |
| 百付宝 | 每天7:00 | FTP | TXT |
| 百付宝退款 | 每天7:00 | FTP | TXT |
| 微信支付 | 每天10:30 | HTTPS | TXT |
| 微信退款 | 每天10:30 | HTTPS | TXT |
找个例子大家看看, 比如微信的对账单,他是csv格式的,包括如下信息:
-
交易时间:这是在微信侧的支付完成的时间。 这个时间会成为一个陷阱。
-
公众账号ID,商户号,子商户号,设备号: 这些信息需要做验证,确保是自己的单子,不要让微信把老王家的单子也给发过来了;
-
微信订单号,商户订单号: 这两个是对单的核心。前者是微信侧产生的订单号,在微信支付接口返回值中有。但是万一收不到这个返回值,那可能就空了。 后者是我们发送给微信的订单号,一般用这个来做对单标准。两边的数据中一般都会有这个值。
-
用户标识,交易类型,交易状态,付款银行,货币种类,总金额,企业红包金额: 这几个就是对单的核心字段,必须确保双方是一致的。
-
商品名称,商户数据包,手续费,费率:这些是可选验证。
而某宝的对账单,是文本格式的,用空格隔开。他们家的就简单很多,只有商户订单号,交易流水号,交易时间,支付时间,付款方,交易金额,交易类型,交易状态这些字段。
渠道对账单标准化
由于每个渠道的账单格式都不尽相同, 在得到账单后,下一步是对账单做标准化处理,这样轧帐以及后续工作就可以统一处理了。 标准化后的账单数据可以放在文件系统或者数据库中。这取决于交易数据量。每天百万以上的量,还是使用文件系统,比较合适。数据库操作相对比较慢,也浪费资源。 基于文件系统的标准化涉及如下内容:
文件格式标准化 统一使用cvs或者json或者xml格式。如果是使用hadoop或者spark来对账,使用cvs是个不错的选择。
文件存储统一化 文件目录,文件名都需要遵循统一命名规范。
当然,为了加快处理速度,使用hdfs作为文件系统,有利于后续的对账。
本地交易记录准备
本地交易记录的准备,总的来说有如下方法:
-
啥都不做,直接用原始数据。鉴于大部分系统使用的是mysql,这也意味着在MySQL上做对账。对账时需要大量的数据查找工作,必然会影响线上业务。在数据规模较大,比如超过100万时,就不太合适了。
-
当然,还有一个选择是使用备库来执行对账,这样既简单,也不影响线上业务。这是典型的空间换时间的做法。
-
如果业务大到需要分表分库才能处理,那对账数据准备也不一样。使用分库也不现实,因为分库一般是按照主体id,而不是渠道id,来分库,这样对账就需要在多个库上进行,效率反而降低了。而对分表分库建立从库也非常耗费资源。这种情况下,需要同步一份数据到(hdfs)文件系统中,或者NOSQL数据库上。
轧帐
我们推荐采用mapreduce来轧帐,这有个优势,可以按照订单号将渠道提供的记录和本地记录shuffle到同一个reduce处理上,这样就可以很容易进行数据比对。 轧帐中最大的坑,莫过于切分点的问题。比如以整0点为切分点,那存在一个问题,本地23:59发起的交易,到了渠道侧,可能会在00:01处理,这一笔交易变成第二天的帐了。实际处理中,一笔交易在渠道侧处理,花上几分钟都有可能。 对于切分点附近无法确认的帐,做一个时间窗,在时间窗内的数据,留待第二天对账时继续处理。
平帐
发现两边不一致的数据,那应该如何处理?数据量不大时,记录起来,人工甄别就行。但如果数据量很大,每天上千条,人工处理就成本太高了。但这个没有统一的处理方法,需要根据有问题的数据,做个分析,然后做自动处理。
总之,对账工作,即复杂也不复杂。需要细心,对业务要有深入的了解,并选择合适的架构。
头条的同学们,记得帮忙点赞啊。
感谢您对本文的关注,如需要及时收到凤凰牌老熊的最新作品,请扫码关注“凤凰牌老熊”的微信公众号,谢谢。