随着业务开展,财务平台上积攒了大量的交易数据,特别是为了资金安全和交易免受风控,引入了多渠道与多收款主体,这对财务的资金核对作业提出很大的挑战,为了减低财务工作量,及时核对资金,所以就有了下面这个对账系统,也是在不断的完善。本文只是抛砖引玉,记录版本迭代过程中遇到的问题与产品设计解决思路,仅供参考。
什么是对账系统
想必大家从【对账】字面的意思就能略知一二是什么意思,“对”=核对,“账”=账目,旨在保证账簿记录的真实性、完整性和准确性。核对的维度包括但不限于交易时间,内容,金额,手续费...。
账目核算是财务工作的核心之一,一般的小企业, 流水较少的时候可以手工或者加上借助excle工具完成对账动作,但是随着企业交易线上化,流水体量越来越大,渠道丰富化了之后,对财务的工作量也会带来很大的挑战。这时候对账系统就显得尤为重要,对账系统基于交易的信息流水与渠道提供的资金流水,可以做到批量的,规范对账,并提供轧差表,差错处理能力。所以,一个对账系统应该具备以下的能力:
- 存储有原生的平台数据,三方数据
- 可以对数据或者文件进行加工
- 可以配置核对规则
- 可以对差异进行管理和处理
- ...
核对模式
概况来说就是“账证实”,“账”就是账目,“证”就是凭证,“实”就是企业实际持有的资产,如现金、库存商品、固定资产等,所以三种模式是:账证核对,账账核对,账实核对。
- 账证核对(Accounting and Voucher Reconciliation)
账证核对是指将会计账簿中的记录与相应的原始凭证进行比对,确保账簿记录的每一笔交易都有相应的凭证支持,并且金额、日期等信息一致。
例子:作为一个商家,你卖出了一件商品,比如一台手机。买家支付了2000元。你会收到一个支付宝或淘宝的支付通知,这是一种电子销售凭证。你需要核对这个电子凭证上显示的支付金额(2000元)是否与你的财务管理软件或账簿上记录的销售收入相匹配。同时,你还要确认这笔收入是否正确地分类到了“在线销售”收入账户中。
- 账账核对(Inter-account Reconciliation)
账账核对是指将会计账簿中的相关账户之间进行比对,确保相关联的账户之间的记录相互协调一致。
例子:在一天结束时,你需要核对所有的销售记录。假设你当天卖出了10台手机,每台2000元,总收入应该是20000元。你需要确认这20000元的收入是否已经在你的财务记录中正确反映,并且与你的支付宝账户或银行账户中的实际收款金额相吻合。如果你的“销售收入”账户显示的是20000元,那么你的支付宝账户余额也应该相应增加了20000元。
- 账实核对(Accounting and Physical Verification)
账实核对是指将会计账簿中的记录与实际的资产、负债等实物或实际情况进行比对,确保账簿记录的信息反映了实际情况。
例子:每隔一段时间,你需要对实际的商品库存进行盘点,以确保库存数量与会计记录一致。例如,你的会计记录显示还有50台手机库存,但当你进行实际盘点时,发现只有48台。这表明可能存在记录错误、货物损坏或丢失等情况。你需要调查这两台手机的差异,并在必要时调整会计记录,以确保账面数据准确反映实际库存。的会计账簿显示库存商品的成本为50万元。在账实核对过程中,会计人员需要进行实际的库存盘点,核实实际库存的商品数量和成本是否与账簿中记录的50万元相符。如果实际库存商品的成本是48万元,那么会计人员需要调查产生这2万元差异的原因,并进行相应的会计调整。
常见对账模型
- 交易对账:一对一,业务方的一次支付行为(唤起一次收银台动作)对应渠道方一笔交易流水
- 资金对账:一对多,一次交易可能对应1或n笔资金流水,(举个栗子:收款1块钱,资金账户A1元,手续费账户记0.1(外扣))
- 分账对账:一对一
- 账户对账:一对一,账户交易包括:企业账户充值、企业账户转账、企业账户提现、企业付款
可以参考开发者平台提供的对账单的种类,算是行业中比较齐全的:
系统设计
对账的的流程可以概括为:拉取系统与渠道的交易信息,信息经过数据清洗筛选和整理后输出标准的对账参数,把这些参数放进在对账逻辑中,最终得到轧差表信息
1、拉取交易流水
方式可以有以下这几种:
- mq
- sql
- 文件
- api接口
- etl工具
选择那种方案,主要取决于组织架构或者网络、数据安全,业务架构等原因。假如你在组织上比较强势,拥有话语权,可以要求其他的业务小组按照你的标准推送数据到对账中心,这样还能省掉数据清洗的工作,毕竟难的工作最好的做法就是自己不要做。假如你像我这样卑微,只能去了解人家业务系统的业务逻辑,手撸sql去取数了,这种方案也是我极其不推荐的,也出现过不少的问题,说到这,需要看下我们一开始的业务架构简图,了解一下背景
系统按照业务划分,每个服务都直接经由对外网关对接渠道,导致交易数据散落在各个服务中,而且这些数据都夹杂了较多的业务逻辑,理解成本较大。除此之外,还需要和业务服务的成员有较好的沟通桥梁,一旦业务服务增加了某种交易状态或者类型而没有同步通知到对账服务,交易数据就会缺失或者错误。
后来我们的业务架构继续演进,做成下面这样简图:
在产品层下面加了一个渠道服务,由渠道服务统一承载系统与渠道的流水,这个渠道服务的职责包含了(支付,管理,计费,路由),这样就统一了数据的来源,而且数据都是较为纯净无业务逻辑的数据,理解起来也简单。当然,这只是我们权衡之下的做法,毕竟现在产品层的服务还是太重,还可以拆分出支付服务,计费服务等等。这里就不展开了,有兴趣的可以看看三方支付架构是怎么做的,借鉴一下。
2、拉取对账单
三方的对账单的拉取一般都是以下两种方式
- 渠道提供接口下载对账单文件
- 提供ftp服务器地址
在对账系统中,根据每个渠道生成文件的时间不同,每个渠道需要下载的文件和方式也不同,可以把这些动作抽象为一个任务:a时间b商户去c渠道从d上下载账单e,记在对账任务表,用定时任务扫描执行。
各种各样取数方式,各种各样的文件,怎么管理好这些原始的文件是相当重要的,毕竟清洗的过程可能会出错,甚至因为渠道的原因,1号申请下载的对账单和2号申请的对账单都会不一样,源文件会是排查问题的源头。保存的方式不外乎把源文件保存在自己的文件服务上,像oss,或者把文件解析,把字段逐一保存在数据库里面,方式上各有优劣,保存在oss上,每次对账都需要从oss下载再解析一遍,当文件多,大的时候,对机器的压力也较大;保存在数据库,每个渠道,每个文件都是不一样的,代表着需要管理多张表,所以有些公司的产品设计,针对这块还会开发解析文件功能,通过配置化,达到快速接入,管理的目的。
上传到自己的oss服务器上,则新增一张文件表,绑定文件与商户的编号,字段如下:
商编 | 渠道 | 账单类型 | 文件名 | 地址 | 对账日 |
---|---|---|---|---|---|
001 | 微信 | 资金账单 | 20200101_001_wechat_fundbill.csv | xx/xx/xx/20200101_001_wechat_fundbill.csv | 20200101 |
001 | 支付宝 | 交易账单 | 20200101_001_alipay_fundbill.csv | xx/xx/xx/20200101_001_alipay_fundbill.csv | 20200101 |
3、原数据清洗
原数据保存好后,下一步就是清洗数据,系统的交易数据包括了收款,付款,退款,分账,充值等类型的数据,同样的,渠道的对账单文件也包含多种业务类型,这一步的主要就是根据对账项目,分别解析系统的交易数据和渠道的交易数据文件后筛选出所需的参数并存入数据库中,为后续的对账动作准备数据。举个例子,收款方式有一种叫做记账簿收款,可以理解为商户在银行开了一个虚拟账户,客户往账户转钱并备注订单信息,成功后就是完成了收款操作;对业务系统来说是收款,对渠道(对账文件)来说业务类型是充值。
清洗可以通过sql,或者代码,如果数据量大的时候,我们可以考虑使用一些ETL工具,像搭建私有kettle环境,因为我们的环境数据都在阿里上,所以用的是dataworks,使用etl工具,可以大大减轻实例的使用压力,etl还有较好的可视化流程,支持各种格式的数据源,也是很大的优点。
4、对账
本地的数据和渠道的数据都准备好了,按定义好对比逻辑,取相同含义的字段的值,核对是否一致,找出差异并记录起来。
常见并主要就是核对单笔交易金额(账账核对),日终账户金额总额核对(账账核对)。按照业务分类,可能是收款,付款,分账,充值...等等业务场景。在代码的实现过程中,我们一般使用策略模式,为每种业务场景单独实现逻辑。随着业务变化,主要是上面说到的沟通等问题,我们需要更加灵活的配置化才能跟上业务的变化。我们可以考虑从产品层面上,开发配置功能,简化(可以优化成全下拉选择字段,并增加逻辑判断,像navicat的筛选功能)如下:
5、差错处理
交易对账的结果会有两种:
- 对平
- 单边(长款/短款)
存在单边记录,一般都是需要人工介入处理,核实差错的的原因。可以预设一些规则去处理这些差错,比如滚动下个对账日再对,补单等等,以便在处理差错的时候选择使用。
资金差错和交易不一样,因为资金是所有交易的总和,排除了技术的问题导致异常,一般都需要核销流程。举个栗子,有个资金账户,直接通过了商户后台转入了100,日终会发现渠道账户比平台多出了100,长款。就是渠道多收了。需要对这100块,走核销流程(上传转账凭证等证明),直到对平金额。
6、最后
一个对账系统从开始到成熟,中间都会迭代多个版本,围绕“对”字展开,涉及简单的交易,资金,复杂的红包,券商(代理商核销闭环)等业务场景。方案总有简单有复杂,避免过度设计,权衡选择最优解则为上策。