这篇文章主要从研发的视角讲清楚:账务相关的一些基础概念,账务系统核心的职责,以及一些关键模块的设计要点。
进入正题前,先讲个小故事。
几年前一个狂风暴雨电闪雷鸣的下午,老板把负责账务系统的技术经理炒了鱿鱼,并把账务系统及对应的研发小组划到我这里,于是除了风控系统仍然在大数据团队(彼时还没有算法团队一说),整个支付系统包括收单结算、收银支付、渠道、账务等全部划归到我这里。
那时距离我进入第三方支付行业已经过去5个春秋,但我对账务的理解仍处在只知道“有借必有贷,借贷必相等”的程度。为不辜负老板的信任,也为了不让小弟们看不起,我决定认真学习账务。过了一个月,恰好重构的新支付核心上线灰度切流,发生日切不过,为校验学习成果,我身先士卒深入进去查原因,查了2天,终于......很不幸,木有查出原因,仍是依靠小弟们解决了问题。
这是我和账务系统之间的一个小插曲。
1. 前言
我在支付行业呆了十年有余,一直从事研发相关工作,从个人以及身边同事的经验看,除了从事账务系统研发的工程师外,大部分支付研发工程师对账务都了解甚少,主要原因仍然是账务系统的业务门槛往往大于技术门槛,比如很多支付研发工程师甚至不了解复式记账。所以有必要从研发工程师的角度来介绍一些账务系统入门的知识。
需要说明的是,不同支付公司内部设计的账务系统必然存在差异,但有些基本原则大家都会遵守,比如复式记账、账户管理、记账、对账、会计中心、日切等。本次只谈这些公共的内容,大家可以结合各自公司的系统实现或内部文档辩证地看。
需要说明的是,纯概念或术语不好理解,所以我会把相关的概念融合到示例中去讲,但里面夹杂了很多我个人的理解,可能和专业的教科书存在部分描述不一致的情况。
2. 复式记账理论简要介绍
账务系统的理论基础是复式记账法。如果对于复式记账没有任何了解,建议先找网上一些公开的优秀资料先做初步的学习。
整理了一份面试笔记包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 面试专题
需要全套面试笔记的【点击此处即可】即可免费获取
如果能看懂下面的场景描述,说明已经掌握了复式记账的初步知识。
以用户通过支付平台使用招商银行CMB支付500块为例做个简要说明。
假设:支付平台同样使用CMB做为收单行,在CMB开设有备付金账户。
涉及的支付平台内部账户:
账户类型 | 账户 | 备注 |
---|---|---|
借记账户 | 应收-渠道-CMB | 简单判断账户类型的方法:恒等式一:资产=负债+所有者权益恒等式二:利润=收入-费用恒等式三:资产+费用=负债+所有者权益+收入左边的【资产】、【费用】是借记类账户,右边的【负债】、【所有者权益】、【收入】是贷记类账户。 |
贷记账户 | 应付-过渡-网关过渡户应付-平台托管-商户待结算应付-平台托管-商户余额手续费收入-商户-消费 |
记账步骤(只以支付成功并结算到商户余额做示例,渠道清算相关记账后面讲):
阶段 | 操作账户 | 金额 |
---|---|---|
第一步资金从渠道到网关过渡户 | 借:应收-渠道-CMB贷:应付-过渡-网关过渡户 | 500 |
第二步扣除手续费 | 借:应付-过渡-网关过渡户贷:手续费收入-商户-消费 | 10 |
第三步网关过渡户到商户待结算账户 | 借:应付-过渡-网关过渡户贷:应付-平台托管-商户待结算 | 490 |
第四步结算给商户 | 借:应付-平台托管-商户待结算贷:应付-平台托管-商户余额 | 490 |
说明:
- 支付系统的记账一定是复式记账法。内部开设了很多账户和科目。
【借记类】账户:资产,应收款等;
【贷记类】账户:负债,所有者权益,应付款等;
- 借贷方向简要公式(不太严谨,但是够用):
【借记类】账户(如资产,应收款),【增加】为【借】,【减少】为【贷】;
【贷记类】账户(如负债和所有者权益,应付款),【增加】为【贷】,【减少】为【借】;
- 复式记账的专业术语很多,这里只摘录几个重要的说明:
复式记账法定义:对每项经济业务按相等的金额在两个或两个以上有关账户中同时进行登记的方法。
记账原则:有借必有贷,借贷必相等。
记账依据:会计恒等式:1. 资产 = 负债 + 所有者权益;2. 利润 = 收入 - 费用。
账户:具有一定格式和结构,能够用来连续、系统、全面的记录反映某种经济业务的增减变化及其结果。
科目:同类财务交易的分类,比如资产、负债、所有者权限、收入或费用等都属于科目。一般科目会分为多级。
账户和科目的区别:科目只有名字,账户包括结构和格式,每个账户对应一个特定的科目。
3. 账务系统产品架构图
拆解记账之前,我们先看一个典型的账务系统具备哪些产品能力。
账务系统一般说来需要负责管理账户、余额、记账、对账、清结算、会计核算、报表等能力。大致如下:
后面单独再开文章详细介绍设计思路。
4. 从最基本的支付说起
我们以最典型的电商购物举个例子(只是举例):小明使用PayPal在拼多多电商(海外)通过多多钱包(海外)支付了50美金。
经过简化后的交互图如下:
说明:
- 持牌的第三方支付机构和电商是独立的法律主体,所以多多钱包和多多电商是互相独立的,需要走独立的结算。
- 为突出重点,中间省略了很多中间机构,比如花旗通过清算网络才能转账到汇丰,清算网络先略过。
- 为简化描述,还有几个假设:
-
- 假设拼多多电商选择结算到银行卡。还有一个场景是电商选择结算到余额,然后自己手动提现。
- 假设单币种场景,跨币种场景还涉及到外汇兑换。
下面我们针对这个典型场景做进一步的细化来讲解账务相关的概念。
5. 记账全流程
5.1. 支付记账完整顺序图
说明:
- 图中只画了正常场景,像明细对账出现差异(长短款)、账单对不平(渠道少打款或多打款)等场景没有画出来。
- 日切相关的在后面单独说明。
- 给商户结算也在后面单独说明。
- 记账方案也会在后面单独说明。
上面只写了顺序,为更清楚描述各系统的参与,下面单独再拆解几个核心步骤,并加渠道网关、支付引擎等子系统的交互。
5.2. 渠道扣款成功
说明:
- 对账中心监听渠道网关的消息,注册我方流水,用于后续和渠道的对账。
- 账务中心记账:DR:应收-渠道待清算,CR:应付-网关过渡户。因为现在有可能收单域的订单已经被关闭,所以这里还不能直接【CR:应付-商户待结算】。
- 每条记账明细都会对应记录一条会计分录。
5.3. 收单订单推进成功
说明:
- 收单成功后,需要把手续费扣出来。
5.4. 明细对账
说明:
- 渠道本身也会收手续费,还可能帮政府代收税费,实际应清算金额=支付金额-渠道手续费-税费。
5.5. 账单对账
说明:
- 账单对账和明细对账不一样的地方在于,明细对账是支付渠道PayPal给的清算文件,账单对账是备付金银行收到支付渠道打款后给出的账单文件。
- 在记账模块先是记银行头寸的账(收到银行账单,说明钱已经到账),再记应清算的账。
- 有些场景没有穷举说明,比如渠道应清算49.50USD,实际只到账40USD,这时仍有9.50USD属于应清算。
5.6. 结算打款
说明:
- 上述是商户结算到卡场景。
- 各公司的内部户编制可能有所不同。
6. 其它重要知识点
6.1. 账户
在账务系统中,通常包含以下几种账户类型:
- 客户账户:对客可见。包括:对私的个人客户账户,对公的商户账户。
- 内部账户:对客不可见。包括:头寸、手续费收入、过渡户(也称中间户)等。
6.2. 实时记账与缓冲记账
一般来说,客户账户的记账需要是实时的,比如用户充值、提现,商家提现,用户退款等。
这些账户如果不做实时记账,一来有损用户体验,二来有资损风险。比如用户充值100块,如果延时不到账,用户可能会投诉。如果提现不实时记账,用户有可能重复提现成功。如果退款不实时记账,有可能在退款场景下被透支。
假设记账需要30ms,一个账户最高也就只支持30多TPS的记账请求,对于一些高并发的账户(也称为热点账户)一定是性能不足的。这个时间可以使用缓冲记账,以提高性能。开通缓冲记账的,通常是内部账户或允许商户透支的流出场景。
缓冲记账通常就是先记录流水,然后起定时任务去捞取流水,汇总后进行记账。前提是一定要做好资损防控。
除了缓冲记账外,还有拆分账户的方式来解决热点账户问题。
6.3. 记账方向
说明:
- 账户类型与借贷方向,相同为加,相异为减,也就是所谓的:DD+,DC-,CC+,CD-。
- 示例:用户提现100元,记账如下:
DR:用户余额(负债类账户)100
CR:提现过渡户(负债类账户)100
6.4. 会计科目与会计分录
会计科目与账户、会计分录的关系如下:
说明:
- 科目有多级科目,所以有个自关联。
- 账户分为客户账户和内部账户,二者的结构有一些小的区别,比如内部账户一般不会被冻结,但是客户账户可以被冻结。
会计科目示例:
说明:
- 一般支付系统使用三级科目就已经足够。部分特别复杂的系统,可能会用到五级科目。
- 为便于理解,上面的示例做了很大的精简,各公司内部对科目的编制差异可能会比较大。
下面是一个典型的支付系统会计科目的部分截图示例。
6.5. 记账方案
有了账户和会计科目,发生一笔交易时,如何让系统自动去记账?这个是记账方案做的事。其中一个解决方案就是给不同的交易场景制定不同的交易码,通过交易码来驱动记账。
下面是一个典型的支付系统的记账方案示例(部分截图)。
6.6. 会计日与日切
会计日,也称为会计结算日或账务结算日,是支付平台在会计周期中进行账务处理和结算的特定日期。比如在分布式环境下,各机器可能存在时间差,一笔交易在零点时有可能跨天处理,如何判断一笔交易归属于哪天,就依据会计日来计算。
所谓日切,简单理解就是切换到下一个会计日。主要做的工作:
- 借贷试算平衡。
- 父子科目试算平衡。
- 总账试算平衡。
- 日、月、季度、年汇总。
- 会计日变更。
日切试算平衡核心逻辑:
- 借方发生额 = 贷方发生额
- 借方余额 = 贷方余额
- 期末余额 = 期初发生额 + 发生额
- 父科目累积额 = 子科目累积额
6.7. 三层对账体系
第一层是信息流对账。我方流水和银行清算文件的流水逐一核对。可能会存在长短款情况。
第二层是账单对账。就是把我方流水汇总生成我方账单,然后把银行流水汇总生成银行账单,进行对账。可能会存在银行账单和我方账单不一致的情况,比如共支付100万,渠道分2次打款,一笔98万,一笔2万。
第三层是账实对账。就是我方内部记录的银行头寸和银行真实的余额是否一致。可能存在我方记录的头寸是220万,但是银行实际余额只有200万的情况。
6.8. 记账服务与会计中心简要关系
为便于理解,这里做了极简化处理。
记账服务负责记账,主要关注账户余额变动等;会计中心负责会计核算,主要关注点在于会计分录、科目汇总、会计报表等。实际情况会比这个复杂。
7. 结束语
账务子系统负责为支付平台管理所有资金,是支付平台最核心的子系统之一。相关会计报表是公司经营决策的依据,也是合规申报相关报表的基础。理解账务子系统的核心概念,能帮助我们构建一个完整的支付系统设计与实现的理论基础。本文从研发工程师的视角,介绍了账务子系统一些最核心的概念,希望能为大家在学习账务系统相关知识时能提供一些有益的参考。
这是《百图解码支付系统设计与实现》专栏系列文章中的第(35)篇。 欢迎和我一起深入解码支付系统的方方面面。