账户系统设计
账户作为支付交易的基础设施,非常重要,其核心不是设计本身,而是他的理念和规范以及基本原则;本小节可以帮助你从0到1全面掌握账户系统的设计方法,最后附带后台设计的几页关键页面原型。
1
账户系统概述
账户体系是支付交易的基础,就像电池对于手机,油罐对于加油站,心脏对于人体?那么这么核心的系统是不是很难设计呢,其实恰恰不难;这也印证了那样一句话“大道至简”
1.1什么是账户
先看标准定义:账户是根据会计科目设置的,具有一定格式和结构,用于反映会计要素的增减变动情况及其结果的载体。账户的基本结构应同时具备以下内容:
账户的名称,即会计科目;
日期和摘要,即记载经济业务的日期和概括说明经济业务的内容;
增加方和减少方的金额及余额;
凭证号数,即说明记载账户记录的依据。
如果财务知识不是很充足,可能对以上的账户定义很难理解;如果从业务视角来看账户,可以理解为账户是用于记录某个主体、某类型资金的余额、以及余额变动明细的数据载体,进而账户有3个关键的内容,如图1所示:
账户余额:这个账户有多少钱
账户流水:这个账户资金进进出出的明细记录
账户交易:怎么把钱放进去,怎么把钱取出来
抓住了上面3个点,基本就抓住了账户设计的核心了。基于这3个点去构建账户的辅助设施,比如账户主体,账户种类,账户余额结构,账户流水的记录字段,账户的功能权限,账户的出入账,账户服务(账户开通注销,冻结解冻,余额流水查询等)等
1.2账户的种类
跟科目分类相同,账户可以分资产类账户,负债类账户,损益类账户,共同类账户等,如图2所示
如果从业务的视角来看,可以基于业务场景来对账户进行分类和命名,比如商户的结算款会结算到商户结算账户,支付公司在银行开的账户叫备付金账户,备付金账户又分存管户,收付户,汇缴户;按主体类型可以分个人账户/企业账户;按账户功能定位又可以分为会员子账户、商户子账户、中间担保户。如图3所示的与监管户相关的账户分类和命名
图3 监管账户的账户结构
从账户命名上基本就知道了这个账户是干嘛用的;就像你有10张卡,一张是放工资的你叫他工资卡,一张是公积金的你叫公积金卡等等,基于业务命名,目的是为了区分账户用途。
但是,无论账户叫什么名字,都是有账户余额,账户流水,账户交易;无论卡叫什么名字都是银行卡;所以账户的本质属性没有改变,设计办法也基本相通。唯一不同的是附属内容存在区别,例如支出户只能打款不能收款,中间担保户不能为负等等,账户权限可能不同,主体不同,交易特点不同.....
1.3账户的结构
账户系统的基本功能脑图如图4所示
图4 账户系统功能脑图
账户主体:这个账户是谁的,个人的?企业的?还是内部业务线的?
账户结构树:就像会计科目,就像商品类目,由于账户可能种类繁多所以有时也需要一个结构树,如图5所示:
账户类型:账户的分类,比如个人账户/对公账户,结算账户/付款账户,收款账户/打款账户
账户名称:便于核算
账户余额:账户余额一般为了业务需要,会设计多个金额属性,比如冻结金额,可用金额,可提金额
账户流水:账户的资金变动记录,记录对手账户,收支方向,金额,费用类型等基本信息
账户服务:开通/关闭、权限设置、入账、扣账、调账、冻结/解冻、余额查询、流水查询等
账户底线原则:支付成功才入账,扣账成功才出款
1.4如何设计账户类型
就像有的公司叫产品经理,有的公司就产品策划,有的公司叫需求分析师;但本质做的都是产品设计工作。如可以按照如下分类为账户命名:
基于主体类型命名账户:个人账户,企业账户
基于业务类型命名账户:电商商家结算户,快递商家结算户
基于资金属性命名账户:工资账户,公积金账户,手续费账户
基于账户职能命名账户:待清算账户,中间担保账户
1.5账户的附属设施
有了电池还需要充电线,有了油罐还得有加油设备,安全设备;同样有了账户还需要有附属模块才能实现账户的资金管理职能。一般的账户系统应该具备如下的功能模块:
费用项:每笔交易都有业务场景,比如下单付款,投诉罚款,用户充值,余额提现,账户年费等等,一方面为了让用户知道这是笔什么交易,另一方面是让财务能够知道编写什么科目的会计凭证,如表1所示
表1 费用项
入账规则:上游有业务系统请求一笔费用的入账,入账到那个账户呢,收支方向如何呢?入账规则就是来确定这笔入账怎么入的问题,规则主要有2部分组成,如表2所示
表2 入账规则模型
冻结规则:有些费用入账后需要暂时冻结,比如用户领的活动奖金,必须冻结7个工作日以后才能使用;某业务线的商家结算收入,统一在次月15号可提走;所以一条入账规则需要关联一个冻结规则,如表7-3所示
表3 冻结规则模型
费用、入账规则、冻结规则之间的关系如何,一个费用入账时,可能记一笔账,也可能记多笔;比如商户佣金费用,则会入两笔账:成本账户入一笔扣款,商家佣金账户入一笔收入;而扣款不用冻结,收入需要冻结7天,该关系如图6所示
对外服务:任何系统都不是孤岛,账户系统同样需要将能力赋能给上游实现自己的价值;账户向外提供的基础服务有——开户,注销,查询(余额,流水,状态),交易(支付,退款,充值,提现,冻结)等。如图7所示
图7 账户对外服务
账户管理后台:账户系统需要提供一个业务后台给相关的运营,财务等内部用户;后台可以查看账户信息、账户的状态、所属主体、余额情况;还可以操作账户进行注销,还需要能够查看所有的出入账流水,配置相关费用,配置入账规则和冻结规则。
1.6账户的应用
账户除了管钱之外还可以在此之上构建一些应用产品比如下面两个例子:
钱包:像微信钱包,就是用户的一个支付账户,在钱包里可以看到余额,可以充值余额,也可以将余额里的钱提现到银行卡。
余额支付:账户可以作为一种支付方式,包装出一个支付通道,利用平台自己的账户进行平台商品的支付。
1.7合规浅谈
果然最后说的都是重头戏,账户作为一种资金池形态,要严格做好其合规性,如果平台没有资质牌照,那么自建可以但是用户账户的真实资金一定要放到监管账户当中进行监管,避免违规沉淀资金池。
2
账户主体
账户本身记录的是资产或者负债或者费用,需要归属于一个主体,也就是谁的钱、谁的债。账户归于谁,而这个谁就是本小节要介绍的内容。
2.1什么是主体
主体可以是人,可以是公司,可以是一个组织,主体是一个具有基本特征和属性的一个可定义的对象
2.2主体的广义定义
基于对象出发,主体可以认为是自然界存在的实体物质和虚无的对象;如一个人是一个主体,一个公司是一个主体,一个组织是一个主体;公司的一条业务线是一个主体,公司的一个部门也是一个主体,一个城市也是一个主体,一座房子也是一个主体。
说明账户的主体可以非常广义,比如一个城市的GDP,可以通过一个统计报表得到,同样也可以为每个城市设置一个GDP账户,那么这个账户的主体就是一座城市;北京GDP账户2020年年末余额4万亿!
所以只要是一个可以被定义的对象,我们就可以将它作为账户的主体来管理,就可以为之开通某种意义上的账户,账户也可以是广义的,不只是金钱余额,也可以是水量余额,电量余额,好感度余额等等。从而账户的广义我们是不是就可以认为:账户是一个可以记录数量和数量变化历史的工具。
2.3狭义账户主体
回归账户主体本身,就是账户的归属对象;最常见的主体就是个人和企业;银行卡的主体有个人主体和法人主体。
对于一个公司内部来说为了经营分析或者管理的需要,又会虚拟出更多的主体类型,比如营销账户的主体可以是业务线或者部门或者小组,来记录部门和小组的预算以及预算的消耗情况。
站在人民银行的角度看清算账户的主体就是网联、银联、各商业银行、各城市处理中心、各特批处理机构;站在银行角度看银行账户的主体就是个人、企业、支付机构;站在一个普通企业看账户主体就是个人用户、企业用户、内部业务线、子公司等。
2.4主体的唯一ID
就像个人的唯一ID可以是身份证,在开银行卡的时候就是用的身份证ID作为个人的唯一ID,在办理社保的时候也是用身份证ID作为身份的唯一ID;唯一ID的条件就是能够唯一识别这个主体。
个人的唯一ID可以是身份证、手机号、社保号、一个平台的userID,其他在这个平台的唯一ID。
企业的唯一ID可以是统一社会信用编号,也可以是对公户的卡号等;如果企业入驻了一个平台那么这个平台为这个企业生成的企业编码也可以唯一识别这个企业。
唯一ID的用途是唯一识别这个主体,但有时候可能这个主体的唯一身份ID不够用,比如这个人在淘宝即是个人用户又是商家用户,那么他在开户时可能就不能只用身份证了,而是用userID 去开付款户 和 bussid 去开结算户 。
2.5主体的身份认证
为了安全起见,平台需要核查主体的身份,像去银行开户需要本人到场+身份证核验;二类户的开通需要多要素鉴权识别主体身份的合法性。对于企业来说可以通过企业的营业执照、法人签字、盖章或者对公户小额打款来验证企业的真实身份
2.6主体的创建
对于平台而言,其账户系统的主体无非有以下几种
个人用户:具有身份证或者手机号唯一识别的一个自然人个体
企业用户:具有企业信用编号唯一识别的一个法人主体
内部主体用户:内部的子公司主体或者业务线主体或者部门
主体下业务线用户:一个子公司下面的一个业务线或者部门
我们在创建主体的同时就需要定义每一类主体的唯一识别ID。在开户的时候,需要使用这个唯一识别ID作为账户主体的唯一识别ID。
2.7主体的信息管理
一个平台的各类主体信息一般是放在用户中心,这些系统去调用账户中心给用户开通账户。这些系统存储着主体的基本信息,比如ID信息、属性信息、权限信息、关系信息;有什么信息就增加字段管理即可,也可以将信息分类,每一类记录的不同的表中,比如身份信息,认证信息,账户开通信息等,如表4所示:
表4 主体信息管理
2.8为主体开户
有了主体以后,可以通过人工开户,也可以通过上游系统调用开户接口开通相关账户,如图8所示。
通过接口开通账户需要要传入下面的信息:
主体ID:123
ID类型:userid
用户类型-个人
用户姓名:张三
开通账户类型:佣金账户
特殊要求:可付款
请求成功后账户系统先在账户主体表中插入基本主体信息,如表5所示:
表5 增加主体信息
根据主体ID可以去账户表查询开通的所有账户,基于开户请求我们在账户中心表中创建对应的账户,账户中心表中要有主体的唯一ID,如表6所示:
表6 账户信息
在账户余额表中创建账户余额,如图表7所示:
表7 账户余额信息
在账户的权限表中设置账户权限,如表8所示:
表8 账户权限
账户中心经过一些列的处理后,账户就开通成功了,然后返回给开户方开户结果:开通成功。从上面的开户过程可以看出来,账户和主体之间有复杂的对应关系。
2.9主体与账户的关系
通过2.8知道,主体和账户以及账户内部有复杂的对应关系,主体与账户是一对多的关系,一个主体可以开通多个账户,每一个账户又会关联余额表,权限表,流水表,如图9所示:
主体的开户ID去关联账户的账户ID,账户ID去关联账户的余额表中的余额,权限表中的权限。
3
账户结构
设计账户前需要了解账户的基础结构,所面对的业务不同,就意味着需要的账户结构就会存在差异。
3.1简单账户结构
账户结构一方面是账户本身的结构有什么组成,另方面就是账户与账户之间的构成模型,我们主要说后者,我们看几个简单的账户结构。
只有一个类型的账户,比如整个账户系统只有一类账户:张三-工资账户,如图10所示
有多个类型的账户,比如图11,但本质上依然很简单,很容易管理
3.2简单余额结构
余额结构就是账户的余额如何划分,就像火锅,有一个锅,鸳鸯锅,九宫格;同样,账户作为一个容器,其内部依然可以划分成多个存储空间。
只有一个余额的余额结构,比如微信钱包的余额就只有一个,这样的余额结构必然支持的交易种类就很简单,收入,支出;无法支撑其他的针对余额的处理
3.3复杂账户结构
随着业务的复杂度增加,各类功能性以及运营需求增加,简单的账户结构开始变得不够用,难以支撑更复杂的业务模型,比如红包可能每个业务线都要推出一种红包营销形态,比如保险业务线,游戏业务线;而红包又被拆分成了现金红包,虚拟币红包,这样的话红包账户结构就成了多层级的账户结构;如图12所示
关于二清监管户体系,其账户结构设计更加复杂,不仅存在多层级的账户关系,还从业务层面对账户进行了分组,比如下面图13中具有众多子账户的账户结构,协同完成资金的监管和分账职能。
3.4复杂余额结构
因为资金清算周期或者业务流转节点多,或者其他风控要求,需要对账户余额进行复杂的处理操作,比如有的能提,有的不能提,最常见的结构就是三个余额属性,如表9所示:
表9 复杂余额结构
核算恒等式:总余额=冻结余额+可用余额
基于这样的结构,就可以对账户余额进行一些复杂的处理,比如发的红包7天后才能提现,那么红包入账户时就会先入冻结余额,7日后解冻之可用余额。
3.5账户结构和余额结构的关系
从上面我们可以看到,账户可以分多级,余额可以分多块,那么他们之间有什么关系呢?可以用下面的公式表达:
多级之间:x级总账户总余额=sum( x-1 级子账户所有账户总余额之和 )
某个账户:总账户余额=冻结余额+可用余额
上面两个恒等式可以用于校验账户系统记录的合法性。
3.6账户管理表的设计
了解了前面的账户主体、账户结构、账户余额结构以后,基本可以设计出账户表的基本字段了,大体上应包含这几部分信息:账户主体信息、账户结构信息、余额信息、账户状态信息;设计如表10所示,除了核心字段以外,其他想展示的字段可以去相关表中查询,比如主体姓名,可以用主体ID去主体表中查询。
表10 账户管理
4
费用管理和入账配置
有了账户以后,账户里就需要存入和存出,充值和提现,转账和消费;这样账户才会流动起来,才有了生命力;那么在交易场景里费用就显得十分重要了,多少钱,什么费......我们以滴滴司机的结算账户为例来讨论本节内容
4.1交易场景
任何一笔收支都依赖于一个场景,而且这个场景基本涵盖所有后续清结算的信息,例如用户叫了一辆快车,张师傅接了单子,从立水桥南到奥森公园;这就是一个交易场景,我们可以称为”快车打车场景“,在这个场景下我们可以知道用户是谁,在哪儿打的车,什么车型,起步价多少,每公里多少,司机是谁等。
如果车到了,超过了4分钟用户不用车取消了,此时用户就需要支付一个取消费用,这又是一个场景,我们可以称为“超时取消场景”。将平台的所有交易场景进行枚举,如果要新增场景,那么要预先在场景中心申请场景编号,才能开展上线业务。
4.2费用项
在上面的场景中,就会产生交易,因此产生一系列的费用,例如打车单订单费用,完单后要给司机做结算就有了订单结算费用,平台要抽取一定服务费就有了“平台服务费用”,如果是在高峰期,要给司机发一些补贴,就有了“高峰补贴费”等等。
费用就是站在业务角度定义资金的业务属性,基于业务侧的费用我们可以关联到后续的财务科目,费用是从业务发生那一刻就产生,而且最后关联到会计科目。如图14所示
4.3计算
业务场景中的费用计算需要一个强大的计费系统,我们将会在清结算模块做重点介绍,这里只做简单的介绍。
下单前的预计算,为用户选择起点和终点后预先计算可能需要的订单费用,如图15所示:
图15 下单前各类场景的预计算
进行中的实时计算,这部分这里略过;结束后的计算,计算出本单实际产生的费用,如图16所示
图16 订单完成结束后的计费结果
可以看出订单总费用包含三部分:起步价+里程费+时长费;你可能会问,一个订单为什么要拆成这么多费用呢?我们简单想一下,这三个费用的特点,而且这三个费用在不同的城市,不同的时段,不同的用户,不同的车型都会发生变化,所以我们可以理解为,费用的细化是精细化运营的必然结果,另外用户也需要知道为什么收这么多钱。
订单完结后就需要给司机做结算,就需要再进行一次计算,计算出这一单应该给司机多少钱,平台抽多少钱,要不要实时扣税,有没有其他费用,比如保险费,我们得出如下的清算结果,如表11所示:
表11 完单后的计费结果示例
4.4账户结构和余额结构
假设每个司机只有一个结算账户,在某支付平台开通的二类支付账户,没有其他类型的账户,接单的收入,补贴奖金全部结算到该账户,司机可以进行提现,如图17所示
基于各类运营诉求,我们为司机设置一个7天的订单结算冻结期,这样的话账户余额分成了冻结余额和可用余额,可用余额可以用于提现。
4.5费用管理设计
上面我们讲了交易场景和费用的定义,现在我们就来设计费用管理,设计费用有三个关键点
费用编码 费用名称 费用结构
当然,围绕费用可以展开非常深的设计,比如与科目的管理,费用的资金方向,用途等进行表的扩展,本章节仅从简单的原理进行设计,不做过于复杂的分析。设计办法常见的有2种
一级枚举型,就是费用之间没有关系,对所有费用进行枚举,如表12所示
表12 费用管理1
多级结构,可以对费用进行分组,在不同的使用场景下展示不同级别的名称,如图18所示
图18 费用管理2
以上两种方式可能第二种更好一些,特别是在核算和统计时,可以进行总分分别进行统计分析和核算。
4.6入账规则管理
在每个节点都会产生费用,或者计算出相关的费用,例如司机收入。计费之后就需要计入相关的账户,如司机收入要计入司机的结算账户;有时候一个费用要计入多个账户,又比如司机奖金可能要同时计入平台的运营账户和司机的结算账户,如图19所示
入账规则设计有两个关键点,一个是匹配条件:要基于入账请求传参的条件来匹配到相关的入账规则条目,我们需要定义每类记账请求需要什么条件,比如司机收入入账,一个条件就够了
费用类型:司机收入
另一个是入账规则:就是这个条目指定入什么账户,比如司机收入匹配到的规则应该是要入司机结算账户,则入账规则是
账户主体:司机
主体ID:司机ID
账户类型:结算账户
这样我们就得到了一条入账配置规则,如表13所示
表13 入账规则表
基于上面的规则,上游系统在申请入账时必须传几个参数:费用类型,主体类型,主体id;基于司机收入这个费用,我们就匹配出一条规则,应该入司机的结算账户,利用司机ID找到相关的结算账户ID然后计入账户,如图20所示
5
冻结配置与账户流水
业务系统请求入账以后,基于费用类型以及入账规则我们就可以知道应该入哪个账户;那么问题就来了,因为账户余额也是分结构的,有冻结和可用,那么要是想先冻结起来怎么办呢?这就需要冻结规则去实现。
5.1冻结规则
我们在账户系统设计详解里讲过冻结模块,这里再细讲一下;冻结就是一个费用请求入账时要基于业务要求决定需不需要暂时冻结起来,还是直接就可以使用;如何设计冻结规则呢?
冻结规则是基于入账规则设置的,也就是这笔入账需不需要冻结,如何冻结,是全部冻结还是部分冻结;这里我们以全部冻结为例,所以一个入账规则要关联一个冻结规则,入账的时候就需要同时获取冻结规则;入账规则和冻结规则是一对一的关系,费用类型和入账规则是一对多的关系,如图21所示
冻结规则有2部分组成,一个是关联的入账规则;另一个是冻结规则;也就是说在配置入账规则的同时就需要关联性的去配置一条冻结规则,如表14所示
表14 冻结规则
配置原型如图22所示(备注:原型图中的选择费用模块应该变更为“入账规则ID”这样就可以直接将冻结规则关联到入账规则上去)。
图22冻结规则配置
冻结规则的配置有以下几个关键点:
冻结模式:就是按照固定时长冻结还是冻结到固定时间点
冻结时间:如果选择固定时长的话就填一个时间值,如果是固定时间的话就选择一个可循环的时间点函数,比如次月10号,就配置成M+1月10号
5.2账户流水
账户有2个核心部分组成,一个是账户余额,另一个就是账户流水,账户流水是记录了账户的历史变动明细。为了记录资金的变动明细,账户流水需要记录最基本的明细信息,一般必须包含以下内容:
账务流水号:作为该笔明细的唯一标识
请求ID:请求入账方的ID,便于后续的核算
账户ID:这笔流水属于哪个账户(会计记账就是科目编号)
费用类型:这笔流水是什么费用金额:发生额
剩余余额:这笔流水发生后的账户余额
收支:支出,收入,这笔流水是增加余额还是减少余额(同会计分录的借贷)账务发生时间:记账时间
会计时间:作为业务口径和财务口径转换的时间(非必须)
备注:业务备注信息
冻结状态:冻结的管理
操作:冻结/解冻
基于上面设计就可以将业务的记账请求通过入账规则处理,冻结规则处理,记入到账户系统并且生成账户流水了,如图20所示
5.3更新账户余额
这里有一个账务处理任务流,每笔入账都需要从头执行到尾,不能遗漏,任何一个处理失败了这笔入账就宣布失败,进行入账的失败处理,我们先设定一个最简单的任务流,如下:
检查账户流水合法性
账户流水表插入账户流水
基于账户流水信息更新余额表对应账户的冻结余额或者可用余额
总余额=总余额+本次发生额
冻结余额=冻结余额+本次发生额(冻结时)
可用余额=可用余额+本次发生额(不冻结时)
自洽校验:总余额=冻结余额+可用余额
入账成功
经过上述的处理,成功的完成了入账,并通知请求方,至此本次入账结束。
5.4余额解冻
因为入账的时候有的流水处于冻结状态,就需要按照冻结的规则进行解冻,这时候就需要一个冻结解冻处理的任务进行扫描执行,至于扫描的模式要基于冻结模式去设计,我们以冻结固定时长最小单位为天为例,那么任务就需要每日凌晨去扫描遍历所有处于冻结状态的账户流水,满足解冻条件的流水就变更冻结状态为未冻结,然后对余额进行处理,即减少冻结余额并增加可用余额,账户总余额不变,如图23所示
6
后台设计
6.1账户列表
账户列表按照账户的维度可以查看全部的账户,包括账户的基本信息,所属主体,账户类型,账户余额等内容,如图24所示
图24 账户列表
6.2账户信息管理
账户信息是某一个具体账户的详细内容,如图25所示
图25 账户信息管理
6.3账户流水管理
账户流水管理可以查看账户的全部变动明细,如图26所示
图26 账户流水管理