前言

大家好,这篇文章我们介绍一下什么是账务。如上所示,如果将支付系统简单分层的话,可以分成业务和账务两层,业务层负责资金转移或者说是促成交易的发生,而账务层就负责为资金的转移提供计算、核对、记录等支撑服务。这篇文章我们把账务层里的各个子系统串起来,简单概述一下它们都具体做了一些什么样的事,以及它们之间有什么样的联系,便于我们后续再单独深入介绍账务层各子系统的架构设计。但我们不打算直接回答账务是什么的问题,因为如果你是小白,笔者无法一句话让你知道账务到底是什么,而如果你是专家那我的解释就是多余的还显得有些班门弄斧。但本文主要是面向小白读者的,对于没有任何账务经验的同学,最好的学习方式不是从概念入手而是从体验开始,因此这篇文章我们一起体验一下账务相关的工作,有了经验性的认识之后,关于账务是什么,或许你也能给出自己的认识。
假设,我们收购了一家做支付业务的金融机构,当前这家机构只有代收业务,代收业务简而言之就三件事:第一件,通过支付渠道,帮商户向他的客户收钱既代收;第二件,将收到的钱打到商户的账户既结算;第三件,确保渠道帮我们收的钱以及给我们结的钱都核对得上既渠道对账。第一件事资金转移发生后,便会产生第二件事商户结算与第三件事渠道清算,渠道清算是指渠道给平台结算资金,而平台需要和渠道进行对账并进行内部账务处理,我们先说渠道对账再说商户结算,但这两件事没有必然的先后次序之分。开始之前,我们先明确一下本文所使用的几个关键术语在本文的含义:渠道,本文泛指提供支付能力的三方、网联、银行等机构;清算,通常是银行或清算机构之间的债权债务关系的清偿,而一般企业之间的债权债务关系清偿的称谓是结算,所以本文不区分两者有何差异,说渠道结算和渠道清算是一回事,说渠道待清算和渠道待结算也是一会事;账户明细,是从客户视角对账户资金变化记录的称谓,从会计视角这一记录被称之为分户账。
渠道对账
为了处理平台和渠道之间的内部账务,我们需要在平台自身的账务系统中为对应的渠道设置一些账户如银存账户,长款账户、短款账户、待清算账户、应清算账户、手续费账户等渠道相关的账户,来辅助我们完成内部账务的处理。那为什么需要这些账户呢?首先待清算账户,是用来记录平台和渠道之间“信息账“,因为交易的真实性和交易资金的到账还有待确认,所以把账先记到这个账户上,等到交易对账完毕且确定交易正确后,再将其转至其它账户;然后,因为对账不是每笔交易资金都和预期的一致或者结算资金与预期的一致,有时候会多有时候会少,所以我们就需要另外的两个账户:长款账户、短款账户,来记录因各种原因导致的差额,以便事后跟踪和处理这些差异;接着,是应清算账户,用来记录交易对账成功之后,因为未到结算周期或者渠道已结算但是资金在途的情况;再接着,是手续费账户,用来记各渠道的交易成本;最后,因为渠道对账的最终目的是渠道账户的余额和我们预计的一致,所以我们需要设置一个与渠道真实账户对应的虚拟账户,来记录和跟踪真实账户的资金变动,这样我们通过每日检查两者的一致性,来保证渠道账户资金变动都能做到有迹可循。 设置好虚拟账户之后,如果真实账户有余额,那么我们还要初始化一下虚拟账户的初始余额:将渠道真实的余额作为虚拟账户余额的初始值录入系统,之后虚拟账户的余额就通过记账的方式来保持和渠道账户余额同步。假设我们有三条渠道分别是C1、C2、C3,C1渠道有100初始余额,C2余额为0,C3专门用于商户结算,它有1200,那么这两个有初始余额的账户需要做如下余额初始操作:

账户明细,上面说过是会计核算体系下的分户账,这里为了展示的字段信息不那么冗长,科目、分录序号以及一些辅助核算项,这些分户账本该有的信息,我们都省掉了。账户设置和余额初始工作都完成后,我们就可以开始处理平台与渠道之间的账务了,假设下面是平台和C1、C2渠道第一天的交易记录,这里将其称之为渠道订单。

为了第二天和渠道进行对账,第一天日终前我们就需要把上面的交易全部记入到待清算账户上,记录的方式可以是实时逐笔,也可以日终汇总,具体选择那种方式依赖于具体的业务需求。通常是实时登记,但为了便于展示,这里我们采用日终汇总记账的方式,将第一天平台和渠道之间的交易按渠道分类汇总,记到渠道的待清账户上,如下所示:

系统化的会计记账有两个操作:更新账户余额、记录账户明细,为了方便我们只展示账户明细而不展示账户的余额。因为采用复式记账,所以我们不光要记渠道方面的账,还要记这笔资金源自何处,因为是代收业务,所以我们用一个收单账户来记录资金的来源。因为复式记账是在两个或以上账户上进行记账,所以上面两笔汇总的账会涉及到三个内部账要登记:C1待清算分户账,C2待清算分户账、收单分户账,C1、C2各登记了一笔账,收单账户记了两笔,所以第一天我们总的收单金额就是收单账户记录的金额1110。账记好后,需要等到第二日从渠道获取对账单,才能真正开始渠道对账的工作,前面的记账操作是为对账做准备。渠道对账可以细分为交易对账,结算对账,余额对账三个部分,下面我们依次来看一下。 首先,是交易对账,我们将平台第一天已入账的渠道订单和第二天我们从渠道获取的交易对账单,按渠道单号或平台单号进行匹配,以渠道对账单为准,并逐一核对交易的各项内容如收付款人信息、手续费,但最主要的是交易金额,假设下面是第一天的交易在第二天的对账结果:

因为我们使用的是系统已入账的交易数据和渠道对账单进行核对,核对的是双方账簿上的账,所以对账内容不包含交易状态的核对。在逐笔核对过程中,我们需要将对比一致的交易标记成对平,金额不一致的标记为金额差异,平台有记录但渠道没有的标记为平台单边,反之标记为渠道单边;另外,凡是有差异的交易记录我们都单独生成一条差异记录,便于后续跟踪和处理这些差异。

上面四笔差异,如果都找不到原因,从资金差异视角可以将这些差异归为长款和短款。如果对账出现长短款且渠道对账单准确无误,那么意谓着待清算账户当期的发生额和真实账户当期的发生额不一致。比如昨天C1渠道的两笔交易:C103这笔交易渠道比平台少50,意思是平台的待清账户当期的账多记了50,而C102这笔渠道单边正好相反,意思是平台的账少记了250。既然账记错了,那么我们就要调一下账,让平台记的账和渠道给的账对齐,这一调整过程称之为挂账,记录挂账动作的单据这里称之为挂账单,如下所示:

为了提高渠道对账的自动化程度,都应该由系统自动进行挂账,这样便于对账系统自动推进到后续的结算对账和余额对账,挂账对应的记账操作如下:

差异都挂账之后,交易对账就结束了,接着汇总一下对账结果,形成如下交易对账汇总单:

我方对账单总额600+510=1110,这和我们第一天记的账是一致的,但是渠道对账单总额800+500=1300,和我方记录的总额之间有190的缺口,这个缺口我们根据是长款还是短款分别做了挂账处理。最终对账汇总单中的各种金额要符合这个等式:平台对账单总额+已挂长款-已挂短款-已消长款+已消短款=渠道对账单总额,如果不相等说明还有一些差异未挂账或未消账;如果相等,我们确认对账汇总单并将待清算账户的余额转到应清算账户中,这样便于我们区分各个渠道有多少资金是平台已经对账待渠道结算,有多少交易总额还未对账或者说各个渠道当日的交易总额有多少,如下所示:

虽然我方记录的交易总额才1110,但是我们是以渠道交易对账单为基准来进行账务调整的,所以以渠道为准的话第一天的交易渠道应该给我们结算1300,因此应清算账户的总额是1300,这和渠道交易账单总额就一致了。 接下来,是结算对账,就是和渠道核对资金是否真实到账。假设平台和C1、C2这两个渠道的结算周期依次是:D1、T1,费率分别是:1%、2%,第一天是周六,第二天是周末,第三天是周一,那么根据结算周期和渠道费率以及已确认的对账汇总单,我们可以为C1渠道生成结算日为第二天的结算对账单如下所示:

对账汇总单和结算对账单是多对一的关系,对账汇总单按天汇总,结算对账单按平台和渠道的结算周期汇总,因此一条结算对账单有可能由多条对账汇总单的数据汇总形成,比如C2是T1结算,那么C2渠道的对账结算单要等第三天也就是周一,汇总周五(没有交易)、周六(第一天)、周日(第二天)的对账汇总单生成。结算对账单中的手续费是我们根据总额乘以费率计算出来的,但如果对方计费规则复杂,那在交易对账之后还得增加一个计费环节来计算每笔交易的渠道手续费,为了简单起见我们这里按固定费率来处理。生成C1的结算对账单后,我们就可以去C1渠道获取对应账户的资金记录既余额明细,假如我们获取到如下两条余额明细:

两条记录减一下就是到账金额:792,到账金额和我们计算出的结算金额一致,说明结算没有差异,确定一致后我们更新一下渠道结算单的到账金额和结算状态,然后记一下账如下所示:

最后,是余额对账。结转之后,假如渠道账户没有其它的资金出入,那么当前渠道账户的余额应该就等于我们结转之后虚拟账户的余额:892,如果不一致,那么我们就需要找原因,暂时找不到原因就将差额做挂账处理,使虚拟余额和渠道账户保持一致;如果一致,那么C1渠道第一天的账就算清了。上述流程,如果各个对账环节渠道都能提供接口,那么可以完全由系统进行自动化对账,如果某个环节缺少接口,那么这个环节就需要人工参与。最后,第二日的渠道账务处理完成后,我们看看各个渠道相关账户的余额情况:

两个渠道的待清算账户余额都是0,说明这两个渠道第一天的交易我们都一一核对了,因为我们交易是日终汇总入账,所以可以通过这个余额判断昨日的交易是否有遗漏未核对的;而如果是实时入账的场景,那么判断昨日交易是否有遗漏未核对的情况,可以通过渠道待清算账户昨日交易发生总额是否和平台对账单总额一致来判断。因为C2未到结算周期,所以账在应清算账户上。另外,长短款因为找不到原因或者说找到原因了,但是暂时无法处理,所以我们让差异临时悬挂在这两个账户上。 商户结算 商户结算可以分成三个环节:内部对账、清分、打款或记账,我们先进行内部对账,你可能会问为什么有内部对账一说?这实际上是系统设计方面衍生出来的数据“对账“,因为稍微大一点的支付系统都会被拆分成不同的域,每个域都有自己的职责和对应的单据,一笔成功的交易会由各个域各司其职、相互协作共同完成。这个过程中各个域便会产生自己的单据,单据之间因为分布式问题,数据之间可能会不同步,为了保证各个域之间的数据一致性,就需要进行系统层面的对账既内部对账。当然,如果你做的支付系统业务足够简单,简单到只有一个单据,那自然没有内部对账一说。但这里我们还是以文章开头的支付架构设计为例,将支付业务的交易链路分成三各环节:收单、支付、上送,收单由面向商户的交易系统负责,支付由承上启下作为轴心而存在的支付核心负责,上送由面向渠道负责报文传输的渠道网关负责;它们各自域的单据我们称之为商户订单、支付订单、渠道订单,内部对账次序是先渠道订单和支付订单核对,后支付订单和商户订单核对;为了展示方便这里将商户订单和之前已对平的渠道订单进行核对。 处理商户端的账务之前,类似于处理渠道端的账务,我们也需要一些账户来支撑商户端的账务处理,但商户端要设置的账户和业务息息相关,如果我们目前只有代收业务并且是结算到卡,那么只需要设置一个总的、内部的商户待结算账户,就能满足我们的账务处理需求;而如果我们期望将商户的结算资金结算到平台为商户开设的账户中,那么我们就需要为每一个商户都设置一个面向客户的账户如结算账户;另外如果业务发展,收单交易有了新的角色参与其中比如代理角色,那么我们还要为代理设置结算账户。不管情况如何,我们先进行内部对账,然后再看不同情况下如何处理商户端的账务,假设下面的商户订单是我们和商户之间的交易记录:

内部对账是实时进行的,目的是及时发现平台内部子系统之间的掉单以及数据不一致可能导致的资损,但不能绝对保证资金的安全性。因为交易结果是实时通知商户的,商户结算是以商户订单为准而且不依赖于渠道对账是否成功,即使渠道对账有差错,那也是第二天事后的事情了。比如一笔代收交易商户的订单是100,渠道订单是100,当日我们已经实时通知商户了,商户也完成了商品和服务的交付;如果第二日渠道对账发现渠道交易金额是50,实际客户支付的也是50,那么这一部分的资损如果无法追回,那么就由平台承担,而非商户承担,否则平台将因信誉问题而丢失客户;而如果是客户实付是100,渠道交易记录是50,那么事后再找渠道要回这50的差额。下面我们将商户订单和渠道订单进行核对,假设对账结果如下所示:

系统稳定之后,内部对账通常不会出现单边和金额差异的情况,主要是状态不一致,发现后补发一次内部通知就可以解决这个问题。除了实时的单笔核对外,日切前要检查一下内部单据总额是否和当日收单账户发生额一致,不一致意谓这有些订单状态还未同步。商户订单总额比收单账户余额小说明存在内部掉单的情况,如果多了就需要特别注意,有可能黑客篡改了商户单据。虽说这一步不是必须的,但从资金安全角度来说,总额校验是非常有必要的。 接着,是清分,就是算清楚每笔交易各个交易参与方拿多少或出多少。假设上面两个商户同属一个代理,那么再加上平台自身,商户端的交易就有三个交易参与方:商户、代理、平台,这里没有渠道这个角色,因为平台和商户与平台和渠道之间的账务处理是分开独立进行的。假设下面的计费规则就是各个参与方如何“分钱“的规则,按商户维度划分,如下所示:

那么,根据上面的计费规则,我们就可以生成各交易参与方的清分明细。这个阶段我们可以基于清分明细生成前一日的交易对账单,提供给商户进行交易对账,但我们的结算流程不依赖商户是否对账。依据计费规则,我们可以生成下面的清分明细以及按日汇总后的清分汇总单:

平台和商户之间是一级的清分关系,两者的清分金额之和等于交易金额,而平台和代理是二级清分关系,代理的清分金额源自平台清分金额,一般不能大于平台手续费除非平台进行补贴。清分可以实时或按批次进行,也可以日终汇总,这里因为结算都是跨天,所以我们按日依据清分汇总单进行清分,如下所示:

清分之后资金到了待结算户中,假设结算方式是结算到卡,那么依据清分明细和结算周期,第二天我们可以为各商户和代理生成第一天交易的结算单:

结算单生成之后,就剩给对应的银行卡打款了,假设结算使用的是渠道C3,那么打款之前进行如下记账:

记账成功且完成打款后,商户和代理的结算款我们就算结了,但如果结算方式是结算到户,又该如何处理呢?首先,我们得为每一个商户和代理都设置对应的结算账户,把资金结到这个账户中,后续客户可以通过提现的方式把钱转到真实银行账户。我们为商户开设的账户和我们之前纯粹用来处理账务或记账用的账户有所不同,它多了交易属性。之前账户的余额记多了或者记少了还只是内部账的问题,通过一定的检查机制发现错误后可以纠正,而商户结算账户如果记多了,就会有资损的可能因为可以自行提现,里面的余额表示真实的钱,所以也将这类账户称之为资金账户,在会计核算体系下这类账户称之为外部户,如果我们采用结算到户的方式结算,那么记账如下所示:

如果商户和代理当日自行全额提现,那么先生成提现单,然后基于提现单做如下记账,最后打款。这里为了方便,提现是直接扣款,一般的方式是先冻结,打款成功之后才进行真正的记账,如果失败就解冻。

可以看出,忽略提现手续费的情况下,如果商户和代理当日提现,那么C3待清算账户的余额和平台主动打款结算方式下的余额是一致的。 交易入账 至此,第二天的账务工作除了当日的交易未入账之外,渠道对账和商户结算相关的账务我们都处理了。假设第二天仅有一笔入款交易,那么日终时,我们把当日的交易入一下账,如下所示:

第二日的账务都处理完成之后,我们看看下面各账户的余额情况:

C1待清算账户余额:250,是第二日的交易总额,C2应清算账户余额:0,表示平台第二天没有C2的交易,C3待清算账户余额:1098.90,是给商户和代理结算的总金额,要等第三天进行对账之后结转,C2应清算账户余额:500,表示已对账待渠道结算的总交易金额,其他我们就不一一介绍了,下面我们看看差异如何处理。 差异处理 假设现在是第三天,平台对账单中只有一笔交易C102,渠道侧C2第二天的交易对账单只有C205一笔交易,C1渠道没有交易对账单,C3我们忽略不介绍。类似于之前的交易对账,我们将双方的交易记录进行核对,按之前的对账流程,第三天交易对账后的差错记录如下:

从第二天和第三天的对账差异记录中,可以看出第三天对账的两笔单边和第二天对账的两笔单边是匹配的,这是日切问题导致的。这种情况第三天的两笔单边应该自动进行滚动对账:将当日发现的单边记录和差错池里前几天已挂账但未消账的差异进行匹配,如果金额、单号都匹配上,那么自动进行如下消账处理:

这样,第二天的两笔因日切问题导致的单边,第三天对账就可以自动消掉。单边消掉后,我们还剩两笔资金差异,我们先看一下C103,假设这笔50的短款是因为渠道自身bug导致的,而且第二天渠道已经给我们的账户补了49.5,少掉的0.5是手续费;但渠道没有给我们补对应的交易记录,这种情况确认渠道已经补单后,我们可以自行给渠道对账单补一笔差额的交易记录,然后人工将手动录入的差异记录和对应已挂账的短款差异进行匹配消账,如下所示:

最后一笔差异C203,假设是因为支付渠道本身支持多付少付,用户下单200,实付250,但平台因为取值问题以200作为客户的实付金额。也就是说第二天的交易我们给商户少结了50,需要补给商户,那具体如何补呢?补的方式有两种,一种是绕过业务系统直接给商户打款或者调整账户余额把资金补上,另一种是通过业务系统创建一笔特殊的新订单补结差额。前一种方式看似简单,实则需要人工清分,如果参与方很多,那就是件很繁琐的事而且会造成业务单据和账务数据不一致的情况;而后一种方式通过复用结算流程来补结差额,不但不需要人工清分而且能保证业务和账务数据的一致性,这里将这种方式称之为补发。补发是一种特殊形式的补单,通常所说的补单是因为未收到渠道回调通知或系统异常而导致的两边状态不一致而进行的人工或者自动重发支付结果的一种补偿机制,而补发是因为结算后发现交易金额不一致,而进行的资金补偿,常见的情况是客户多次支付但业务上需要将资金补结给商户而非原路退回(这种情况在海外有些国家很常见,国内通常是原路退回),另外就是因为平台或者渠道系统bug导致的差额,这不常见但会存在,如果出现上述两种情况,可以通过补发解决这类问题,下面是补单的处理流程:

图中,我们展示了三种情况的补单,掉单和差额通常是在对账环节发现的,而重复支付是渠道通知平台的,但也有可能源自渠道对账单,无论源自何处,补单事件都需要像上面一样,沿着逆向的下单链路层层传播至交易系统。这里我们就不再深入这一部分,让我们继续差异处理。补发需要先“补“资金,后补交易两步操作来实现。因为如果待结算账户没有资金可结,那么即使有交易也无法结算。那如何先“补“资金呢?就是将挂账的金额消到收单账户中,让收单账户有资金可结,或者新设置一个补单账户专门用来处理这类账务,这样账务上会更清晰一些,这里我们采用前一种方式。资金补上之后,再补一笔对应差额的商户订单,这样这笔补发订单的后续结算处理流程就和正常订单一样,会按正常流程自动被清分和结算,所以C203我们先消账,首先,我们在补单模块创建一条补单记录,如果需要人工审核,那么审核过后将记录同步至渠道清算进行实时对账处理,并等待消账通知,如下所示:

对账模块发现这笔交易没有正常与之匹配的渠道订单后,会就将其添加到差错池中,如果我们设置了差额的消账规则,那么可将该差异记录和已挂账但未消账且差异类型是金额差异的差异记录进行匹配,匹配上就自动消账,但也可以人工处理,假设人工处理,那么处理结果如下:

消账之后,由渠道清算发出消账事件,补单模块收到消账通知后,调用渠道网关的补单接口进行补发,之后该笔交易沿着逆向下单支付链路传播至交易系统,交易系统创建对应的商户订单,这笔订单和源订单的关键信息要保持一致,但平台单号需要不一样,如下所示:

如果商户单号是唯一键,那么可以像上面一样在原单号加后缀区分两种订单,如果期望单号不变那么订单模型就要有一个字段区分是正常订单还是补发的订单,将商户单号和该字段作为唯一键。补发成功之后该订单就会进入商户结算流程,而结算流程上面已经介绍,这里就不再一一赘述结算的各个环节。至此,四笔差异我们就已经处理完成了,接下来我们看看第三天的对账汇总单:

C1渠道对账单总额有50,实际C1渠道并没有给我们对账单,而是我们自行帮渠道补上了一笔交易记录,这笔平台帮补的渠道交易记录应该算到渠道对账单总额里面,否则之前的等式就不成立。C2平台对账单总额有50,这50是第三天平台补发的交易记录,它的交易日期和正常的交易不同,补发订单要实时进入渠道清算进行对账,所以它的日期是当天既第三天,正常的交易是第二天。这样根据之前的校验公式,确认交易对账无误之后,我们确认交易对账汇总单后进行如下账务处理:

确认之后,我们根据对账汇总对账单和结算周期生成对应的渠道结算对账单,如下所示:

因为C2的结算周期是T1,所以第三天(周一)根据结算周期生成C2的结算单时,需要汇总第二天和第三天的对账汇总单,生成对应的结算单。之后就是核对资金到账情况,如果一致,那么就结转至虚拟账户,如下所示:

接着核对一下余额是否一致,如果一致,那么第三天的渠道账务我们就处理完了,假设今天依旧没有任何的交易发生,那么各账户第三天的期末余额状况如下:

至此商户结算、渠道清算、交易入账、差异挂消账等和支付业务有关的主要账务工作我们大致都介绍了一下。我想读者应该对账务有了一个概览式的认识,知道什么是账务了,无论什么行业,只要有交易发生,就会有账务工作要做,而账务处理无论业务的差异有多大,“供应链“或上下游之间的资金对账和结算大体流程总是相似的,不会有多大的差异。 结尾 本文以代收为例介绍了平台与商户和平台与渠道之间的账务处理,其它的业务如代付、充值、提现只是业务场景不一样,账务处理流程都是一致的,先有业务或账务单据,然后生成凭证,之后记账。本篇因为是为小白读者入门而准备的,内容上我们省掉了很多会计领域的知识以及系统架构方面的内容,所以后续《账务架构设计》这篇文章我们重点介绍账务系统的架构设计以及会计有关的一些基础知识。由于笔者才疏学浅,内容难免存在疏漏和偏颇,欢迎大家不吝指正,如您有更好的见解,欢迎交流。