账户系统设计【拓展篇】
拓展阅读1
学会从“账”上解决支付问题
特别是企业的清结算业务,账务是其核心枢纽;另外现在支付体系的基础也可以说是站在账务核心之上,不同的机构的账务管理着不同资金属性的“账户”,管理着不同的信用货币
三方支付机构的支付账户,银行的结算账户,央行的清算账户,二清解决方案的核心监管账户体系,记账本体系,数字货币钱包体系,跨主体清算的往来账户,区块链的分布式账务......我们发现,支付的创新和变革,支付产品的设计都是建立在一套新模式账务体系之上;如果你想做一个支付业务,那么先把账务想清楚,基本事情就成功了一半
1.2从账务上找突破点
作为一名支付产品经理,我们工作中经常会遇到新的业务形式或者业务变化,任何新的业务和变化基本都会触碰到资金的问题,任何资金的问题又会涉及到财务和法务以及公司主体的资金问题,这些问题更多的是“规矩”,交给法务、财务去解决
还有一个问题是技术问题,这个事情如何去落地,我想很多场景我们都会有很多的选择;而最后总会有一个耀眼的明星脱颖而出“从账务上去解决问题”,其实也可以说是“从信息层去解决问题”,换而言之就是“先把账捋清楚,把账务处理搞明白”事情就解决了
怎么把账搞清楚呢,无外乎,这是谁的账,要记到什么账户,使用什么样的费用去记录,什么时候去记录,谁来请求记录......
所以说,精通财务会使你成为职场神一样的存在,因为你经常会发现,无论是技术还是产品还是运营,大家的挡箭牌都是“我不太懂财务......”,为什么财务这么重要,因为这基本是支付的终点,任何支付问题,最后都会从业务上收敛到财务问题,系统上收敛到“账务核心”
大家可以回想一下,自己工作中遇到的各种支付问题,哪些跟账务相关
1.3把账记清楚,把事做明白
我们去理解很多支付产品,或者公司去接入不同的支付解决方案,我们最核心关注的还是对方的账户体系怎么建设的,这就会涉及到支付的两个核心问题,一个是信息流的问题,另一个是资金流的问题
很多时候,通过“玩转账务”会让你在工作中如鱼得水;在信息层解决问题,一个是他会让你凸显不可替代的专业性,会让事情脉络非常清晰,也会让项目成本极大的降低,简单的说会让事情做的很漂亮......
如果一个新业务就像毛线球一样一团糟时,你站出来,从账务模型上把事情抽象出来,事情会清晰很多;账务就像心脏一样将血液有条不紊的输送出去,业务就像各个脏器一样,他们赖以生存的血液又会有条不紊的回流回心脏......
如果你要做线下结算体系的线上化,那么请先把“账”想明白;那些结算对象,他们都要结算什么款项,由哪些主体给他们结算,分别使用什么资金;结算后这些业务财务又需要什么样的报表怎么样去记账;因此如何为结算对象设计“账户体系”
1.4从“账”上解决支付问题
我们都知道,很多企业的某些业务会需要缴纳保证金,比如你在淘宝开店,需要缴纳店铺保证金,你骑共享单车需要缴纳保证金,你在抖音开店需要缴纳保证金;你在支付机构接入支付产品同样也需要缴纳保证金
保证金啥用途呢,其实就是担保,就是增加对象在平台的信用兜底;在淘宝经营出了问题,那么你的保证金就可以作为最后的兜底手段,如果因为退款出现了欠款,那就用保证金还上,其他同理
但是很多企业其实保证金是单独的存在,跟某些业务或者说业务账户直接并不能想通;比如淘宝,你的经营结算账户出现了欠款,不能直接从保证金转入进行抵偿;这个过程会涉及到很多问题;一个是两个账户的业务属性不同,资金属性也不同,法律问题也不同,同样在公司的财务层面上科目也不同,在资金层面上也在不同的企业银行账户中,也可能在不同的监管账户中
这样的情况下,要想将保证金扣一部分去抵扣结算账户欠款,面临的问题就很多了,因为你要兼顾很多问题的合理解决
那么这个时候,就要换个思路,先从信息层“账务”上去把问题解决,从“账务”上去梳理对应的其他事物;因为账务跟公司主体,所属对象,财务科目,背后管理的银行资金相互管理,账务理清楚了这个事就清楚了;账务动了,每一个关联的都会顺势而动
1.5从账务上去解决支付创新问题
我们知道某B2B电商给有商家贷,其支付工具给个人用户有消费贷,其C2C电商给商家或者个人有经营结算账户;所以大家有没有发现这个体系里存在着资金的闭环,同样也存在着风控的闭环
用户在其支付工具内消费贷款,然后在其电商平台购买商品,钱成了商家的结算款;同样商家又可以在平台贷经营贷,然后到B2B平台去采购商品到C电商平台卖......
如果商家在B2B贷的经营贷还不上了,那么就可以用商家在C电商平台的经营结算款去强制偿还......降低了经营贷的坏账;总之,这套供应链金融体系,让资金极大的在内部形成闭环,流动性在内部进行控制,支付效率可以说极高,风控能力可以说极强
那么这个闭环效率,其实就可以从账务层完成;下面这张图我们仅限于从实现手段上探讨;相关的合规问题,法务问题,以及其他更多问题不在这张图里体现,比如不同主体间债权债务关系转移的协议等,实际工作中请严格遵循财务和法务意见以及当地的相关法律和监管制度
在工作中遇到问题,尝试着从账务层寻找突破口,很多时候会事半功倍
拓展阅读2
热点账户常见解决方案
摘要:我们经常听到一个概念“热点账户”,可能很多人不陌生什么是热点账户,但是对如何解决热点账户问题并没有系统性的完整的思路;事物总是发展的,事物所处的场景也是在不断变化的,基于有限的经验去解决无限的可能性是很好的技能,我们试图从认识热点账户开始,再了解几个常见的解决思路和案例,打开对热点账户的世界
2.1关于账户
什么是账户这个话题就不展开讨论了,我们之前也写过很多跟账户相关的内容
对于账户我们要重点理解这几知识点
了解账户的结构是“入账请求、账户流水、账户余额”;入账请求产生了账户流水,账户流水更新账户余额;所以其中我们要关注账户流水的创建以及账户余额的更新,这里账户余额的更新要重点关注,这是后续造成热点账户发生的主要的环节;如图2-1所示
图2-1 账户模型
账户的账务处理主要分三类:收钱,付钱,账户间转账;收钱针对一个账户的余额增加,付款是一个账户的余额减少,转账是两个账户之间一个增加一个减少,如图2-2所示
图2-2 账务流动模型
账户处理的存在最大并发量,超过这个并发量账务处理就会出问题;账户账务处理过程的线程控制,无论是收钱、付钱还是转账,为了保证账务的准确性,每次账务处理都是一个单独的事务,就算是多个请求同时发生,对账户的操作也是一个一个的来;当一笔入账请求开始处理时账户资源会被加锁,等该笔请求处理完以后会释放锁;这样的话就意味着每一笔账务处理都会获得一个时间占用,这个时间内其他入账是不能操作的,这样就出现了资源的瓶颈,也就是账户的入账必然存在一个并发的最大阈值,一旦超过这个阈值,就会出现账户的性能问题,如图2-3所示
图2-3 账务处理耗时原理
热点字段和热点事件;在交易并发过程中,有些字段的使用频率很高,比如流水号、余额、发生额等字段,这些使用频率很高的字段称为热点字段;导致热点字段的事件称为热点事件,比如商家结算日,需要给商家结算付款,这时候造成付款专户的付款并发,这个就是一个热点事件
2.2热点账户定义
业务发生以后会产生业务事件,比如下单支付,业务事件需要申请入账;当在短时间内产生了大量的业务事件,或者狭义的看有大量的交易产生时,造成高并发的入账请求,高并发引起了账户系统的性能瓶颈而产生了性能问题,进而造成入账延迟、失败、账务准确性等各种账务问题;而这个过程中涉及到的账户我们就称为热点账户;所以说热点账户是由于高并发交易时频繁更新账户产生性能问题而造成的,所以这里一个关键的前提是“高并发”,那么热点账户的标准是什么呢,在一些文献里提到以下标准
1)账户每秒有10次以上更新需求
2)串行化时账户处理延迟高于1秒以上
我想热点账户产生的根本机理跟城市交通高峰时段的拥堵地段是一个机理,怎么解决高峰问题,错峰出行,限号限流,分流等等;同样热点账户也是,既然是高并发造成的拥堵,我们就可以以降低账户上的并发为目的,也就是降低热点账户的操作并发以降低账户热度;像可以缓存记账,可以批量汇总记账,可以将账户拆分分摊并发,可以进行记账排队等等手段都可以降低对账户的高并发操作,从而降低账户热度
2.3热点账户常见发生场景
既然产生热点账户的原因是高并发造成的账户被频繁更新,所以我们探索热点账户的发生场景就转换成了探索交易高并发的场景,这些高并发场景都有可能造成热点账户,比如很容易想到“双11购物节”“微信发红包”“某自营电商平台的秒杀抢购”“小米官网新品的预售”等
这里的场景有的是因为高并发收款造成的,有些是高并发付款造成的;而且收款和付款的热点账户解决方案往往会存在差异,不同场景的收款和付款解决方案也会有差异;就像淘宝双11收款,淘宝中间账户其实因为不外漏给用户,后续商家履约周期也长,所以时效性要求并不高,可以考虑批量定时入账、异步入账、缓存入账等,不采用实时入账;所以我们可以将业务场景分为高频入账场景和高频扣款场景;像淘宝双11的中间担保账户就是高频入账造成的热点账户
我们来分析一下淘宝双11产生热点账户的场景
我们在淘宝购物时都清楚,钱是不会直接给到商家的,而是先收到中间担保账户,等履约完成以后才会由担保账户结算给商家,所以这里对于担保账户来说有两个过程,一个是用户购买商品时的收款,另一个是服务履约以后的结算付款,而其中双11期间的用户付款就成了热点事件,从而中间担保账户的收款造成了担保账户成为热点账户,如图2-4所示
图2-4 淘宝担保入账
上面我们介绍了,淘宝担保账户是内部账户,并不外漏给用户或者商家,这样的话,只需要实时告诉用户和商家已经付款成功即可,至于担保账户的入账可以慢慢的处理;这里我们也得到了一个思路,解决热点账户要关注两个问题
一个是给用户的反馈:对交易参与者的反馈策略,参与者需不需要实时知道账户的处理情况,是只需要知道结果即可还是需要实时看到账户余额的变化,显然对于淘宝中间账户来说,账户参与者是不需要知道账户余额更新情况的,只需要知道支付成功的反馈结果即可,而这个结果可以依赖渠道的反馈通知,而内部记账可以不反馈给用户,这样的话担保账户就有了足够的时间和选择来规避并发问题
另一个是账务要求:账务更新时效性要求高不高,账务的准确性要求高不高,这里中间担保户对时效性要求不高,准确性肯定是所有账户要求都是很高的
这样我们可以使用批量的延迟更新中间担保账户的方式来规避双11高并发交易的入账请求,以规避热点账户的发生
这里我们要知道个事实,数据库插入数据的并发支持是非常大的,一般不会造成数据库性能问题,批量插入即可,只是更新账户余额需要进行锁处理,会造成性能问题,所以解决淘宝中间账户的关键是解决账户余额更新问题
首先我们先将高并发的交易的入账请求插入到入账流水表,这时并不着急去更新中间担保账户余额,此时这些流水我们标记一个入账状态“未入账”;定时的去扫描这个流水表,将扫描到的数据进行加锁,确保不会被后续入账或其他处理影响,然后汇总求和,用这个求和的总值去更新中间担保账户的余额,然后将这一批“未入账”流水更新为已入账,然后释放锁,这样就以很小的并发完成了对中间账户的更新,如图2-5所示
图2-5 汇总更新余额
下面我们介绍几种常见的解决热点账户的方案,并且针对每个方案我们列举一个实际的案例为补充;对于热点账户的方案设计过程中,我们需要重点关注几个问题
收支:账户是收入热点账户还是支出热点账户内外:账户是用户热点账户还是内部热点账户
时效:账户是高时效性实时入账还是不需要高时效性
结果:用户是否需要实时知道入账结果还是不需要余额:用户是否需要实时知道账户余额更新还是不需要
对于方案的设计和选择可以先做以上几个方面的分析,然后选择合适的解决方案;比如上面淘宝中间担保账户对时效性要求不高,用户不需要感知余额的场景我们就可以选择延迟批量汇总入账
对于方案的设计,我们就可以基于以上几个问题从解决“账户的单位并发”为核心突破点,因为并发造成的频繁更新是热点账户产生的根本原因,所以解决的热点账户并发的问题也就可以解决热点账户的问题
2.4限号限流-直接控制并发
第一性原理,不想太多,直接解决产生问题的问题本身;并发不是造成热点账户么,那么反向思考,这个并发阈值是多少,在账户之前设到屏障控制这个阈值,开闸放水,门就这么大,只能进来这么多水,就像很多城市的限号限流一样,最终的结果肯定是损害一部分车主的体验;虽然是立竿见影的效果,但是这也是自损800的方案;这里我们不妨称之为“热点阀”,如图2-6所示
图2-6 控制入账并发
所以给账户安装“热点阀”可以解决热点账户问题;但是问题还是比较明显的,除非你很强势,比如交通控制,否则以服务为第一客户优先的企业这种方式一般不会采用
2.5变多为少-明细汇总记账
数据库插入数据是可以支持非常高并发,可能达到3.2w/s,所以插入流水不是热点账户瓶颈所在,而是余额更新;所以我们就将“降低账户的单位并发”设计思路缩小到了“降低余额更新并发”的范围;对于余额更新就是基于流水去增加或者减少余额,了解C语言的应该知道,无非就是下面的这个函数(不一定准确,但是这么个意思)
balance=balance+发生额
就像新余额等于当前余额加上或减去该流水的发生额,降低余额的更新频率我们自然就可以想到,可以降低发生额的更新频率,也就是你们这个多人来更新我,我实在是忙不过来,都堵在门口,不如你们派一个代表10分钟进来一次,汇总大家的要求我一次性解决;这样就是我们说的“汇总明细记账”的方法,这样的话这个函数从意义上就变成了
balance=balance+sum(一段时间内全部明细的发生额),如图2-7所示
图2-7 明细汇总记账
这个方案的适用场景就是不需要实时更新余额,且主要是增加账户余额的场景如果是扣款类场景,可能汇总入账会造成账户余额透支,不过如果允许账户透支,出款类场景也是可以考虑,只不过对资金管理的时效就会变差,你无法从账户余额直接看到剩余可用头寸;
2.6排队办理-缓冲记账
现在大家经常做核酸,因为并发较大,检测人员有限不能实时采集样本,所以大家需要排一个很长的队伍;同时因为一个人一个人检测成本也高,效率也低,所以10个人一组进行混采;混采就像我们上面说的指派代表的汇总记账一样;所以说我们可以为账户设置一个排队机制,出现高并发账户更新不过来时大家进行排队办理,如拓图2-8所示
图2-8 缓冲记账
就算排队可以解决账户的并发问题,但是肯定是有天花板的,就像10个人采样,100万人排队,那要做到什么时候,也可能发生抱怨和投诉;所以怎么办呢?增加检测点是一个很好的办法,1000个人采样,就可以分摊这么多的要检测的排队的人;这就是我们下面要讲的“子账户拆分”分摊压力
2.7临时存放点-缓存入账
高并发请求可以先进行缓存,然后定时将缓存更新到数据库;这个看起来跟缓冲记账异曲同工,但这里有个区别,缓冲记账时账务请求还在排队入账,而缓存记账实际上账务请求已经实时在缓存中完成了记账;缓存记账具备缓冲记账和汇总明细记账的双重优点,如图2-9所示
图2-9 缓存入账
这里要注意因为缓存需要具备账户余额部分的管理,所以账户系统的余额要赋予缓存模块,缓存模块在此余额基础上进行出金和入金的记账操作;定期将缓存同步到账户系统完成最终的记账,记账完成的缓存部分可以进行清空,然后获得最新的账户余额,以此循环
2.8增加点位-子账户拆分
当即要解决高并发的热点账户问题又要保证实时性要求时,上面的会影响账户更新时效的方案自然就不是首选了,那么就需要一个能够支持实时余额更新的方案了;既然一个账户的更新出现了瓶颈,那是不是可以考虑为他找更多的帮手分摊压力呢?答案是肯定的;我们可以将账户进行按需拆分,拆分成多个子账户,将高并发请求分配给各个子账户,从而每个子账户的并发就降下来了;这里要明确一个问题,这个子账户更多是不能让用户感知的,只是内部的处理方案,对用户来说还是一个账户,所以流水和账户余额反映给用户的都是一个;这就意味着账户作为一个整体被用户感知,如图2-10所示
图2-10 子账户拆分入账
这样的话势必要增加很多账户设计的复杂程度,比如入账的时候入哪个子账户,是平均入账还是按序入账,出账的时候怎么出,有个别子账户余额不足但是总账户余额充足时怎么处理;所以说这里会有一个复杂的账务处理模型;不管这个模型怎么设计,要保证金业务上顺利完成账务记录要求以及用户的使用体验,从而确保业务的正常进行
我之前设计的账户系统,每个商家可能会有七八个子账户,出款的时候是按照顺序出款,就是先扣完一个账户扣下一个账户
想起在某支付机构做了断直连接入网联的改造项目,其实网联的项目方案里提到了其要作为人行支付系统的前置系统做人行热点账户系统的前置缓冲,我想这个设计方法是不是可以借鉴到工作当中
2.9小弟先上-前置缓冲
为解决备付金集中存管所形成的热点账户问题,实现对已映射额度管理,网联构建了“备付金热点账户前置系统”即“RCMP”,用于支付机构通过网联平台(EPCC)的业务办理。如图2-11所示
前置系统分为额度管理模块及账户管理模块,网联将为各支付机构在前置系统中建立账户,用于可用额度的监控、已映射额度的管理。
技术层面就不过多讨论了,作为非专业人士,或者说产品视角提些建议“能多增加几台服务器么,可以扩充下硬盘么,你这个cpu可不可以换成顶尖的......”
事物总是变化的,场景也是不断地更新,面对新的场景,新的问题,历史的经验只能作为解决新问题的参考;不妨在遇到虚拟问题时多思考一下真实的世界,也许会有意料之外的答案!
3.1天下大势分久必合
3.2保证金账户是什么账户
对于一个多业务线的平台来说,可能会存在每个业务线都需要缴纳不同种类的保证金,比如你在A业务线需要缴纳A保证金,在B业务线需要缴纳B保证金;这时候你就需要在钱包里分别充值AB两类保证金,同样在平台的账户中心也会有你的两个虚拟账户A保证金账户,B保证金账户;每个保证金账户独立存在,单独管理,如图3-1所示
首先就是支付系统的充值和提现记录;其次是账户系统的保证金开户、保证金余额、保证金流水的相关记录;然后是会计系统对应的保证金科目以及会计记录,和保证金资金管理账户的银行存款科目;最后就是保证金的实际资金账户的实际银行结算账户的资金账务记录,如图3-2所示
更好的方式可以以个人或者商家主体为维度来管理保证金,就是一个人在平台只需要缴纳一份保证金,实现“一金多用,事后核算”的模式,也就是缴纳的保证金属于平台总部统一管理,当各业务线发生保证金扣款时再计入各业务线名下,而不是在账户维度就计入业务线名下;这样大大降低了保证金账户数量以及提升用户满意度,同样也降低了资金账户以及会计的管理成本,如图3-3所示
同理会计系统也要新建对应的统一保证金科目,将原来的A类保证金科目余额和B类保证金科目余额全部结转到新的统一保证金科目当中;至于结转多少,这个要依据账户中心提供的“余额转出”的系统账务统计进行结转
特别是用工市场,像家政阿姨,外卖员,出行司机;什么也没干,上来就交一笔保证金,或者购买一些工具包;可能会有一些抵触;可能对于比较大的平台可以打消大家的顾虑,但是一些小的机构或者组织可能大家就很难交付这样一笔资金
这种情况下就出现了一个这样的模式:你先干着,这笔钱先不用用自己的钱交,从后面的收入里慢慢扣除,直到扣够了为止。我们暂且称这个模式为“倒扣”模式
倒扣模式从一定程度上可以降低招募服务人员的难度,但同时也会加大风险,特别是在有工具的情况下;如果劳动者领取了工具,但是或许没有挣得足够的收入,那么这个工具费用是有可能成为损失的;所以这里面就是二者的博弈,用风险博取商业上的利益
那么在系统设计上如何实现这个倒扣模式呢?我们从两种方法上去做,当然还有更多其他的办法,无论什么办法,我们先说明白要解决的问题,我们要擅长描述清楚需求
知道每个人应该倒扣多少钱,然后在后续的收入中进行扣除,多余的部分结算给商家
4.1知道每个人应该扣多少钱
规则值-累计已扣
4.2二种方法解决剩余代扣问题
这里面有一个自洽关系:剩余待缴=规则-累计已缴
在商家结算之前,先查看这信息里商家是否还有“剩余待缴”,如果有的话要先清分出一部分到这个记录中,剩余部分结算给商家,如表4-3所示
另一种方式是账户的模式,我们为每个商家在认证以后开通一个待缴账户,这个账户的期初余额为0,由账户记录已经缴纳的部分,同样商家的结算采用的也是账户模式,这样商家就有了2个账户,如表4-4所示
贷 保证金账户-李四 1000
4.3保证金的返还
因为这个钱满足一定条件以后是要返还给商家的,所以要有一个返还的账户操作,而需要一个东西来触发这个返还,比如合同结束且没有其他待办事情后,可以通知账务系统进行返还,做如下的账务处理
摘要 保证金返还
借 保证金账户-李四 1000
贷 结算账户-李四 1000
这里比较明显的风险并不是钱都没有交齐,而是发生了违规事项,扣除保证金造成的负余额,而这个负余额就成了资损的风险,后续需要商家缴纳更多来填补;当平台有百万商家时,这个模式就暴露出了很大的风险,如果大部分账户出现欠款的情况,那要想办法杜绝这种情况发生
一种方法是从根本上解决问题,取缔这种倒扣模式,采用先进行充值,这样就可以解决这个模式的问题
另一种办法就是设定可透支阈值,当被透支到一定金额以后封禁商家,需要充值偿还以后才可以继续经营,所以需要增加对该账户进行充值的能力
以小见大,虽然不难,但可以表现出自己的系统性知识和解决问题的能力
这就是账户的本质,建立交易流与资金流的匹配;而这种匹配关系的清晰性,决定了账户体系的效率和灵活性
以上是我们在做账户设计时要关注的账户最核心的部分,我们可以通过一个账户解决基础问题,通过交易分类解决账户流动性的清晰问题
当交易模型复杂,交易流繁多时,可能会造成资金属性的不同,就比如存款、信用额度、理财资金往往是无法混合,这时候我们可能需要多个账户来管理
同样,当一笔钱的来龙去脉不同,不同的用途时,为了交易的效率,我们可能又需要多个账户来管理
而这种不同的特点,衍生出不同的行业痛点和难点;如果我们想去攻克这些难点,对子账户的拆分,提升行业资金管理效率和交易效率是重要的突破口
通过账户方案建立线上交易基础,通过账户拆分提高资金效率
我们拿航旅来说,代理商从航司购买机票,分销给二级代理商,再通过三方平台或者线下代理点到达消费者
以支付作为切入点,通过支付的变革实现行业的变革,改变行业的交易成本和效率;将交易电子化、资金电子化、并实现交易信息流和支付资金流线上高度统一;交易电子化我们可以实现机票电子化,用户可以线上选票、购票、出票,如图5-3所示
资金电子化我们可以基于交易模型为各参与者建立与交易相匹配的账户体系;我们以代理商角色为例,分析在交易模型下其资金行为,如图5-4所示
所以我们将代理商的虚拟业务账户进行拆分,通过子账户体现出这层关系,并将账户内资金的流动性通过子账户之间的业务关系完成,如图5-6所示
一个子账户解决一个问题,那么更多的问题就可以用更多的子账户去解决;比如代理商资金流动性不足,可能就有了信贷的场景,我们就可以为其提供信贷;有的代理商资金充足,可能就有了理财的场景,我们可以为其理财,这样,子账户又被拆分出来;付款账户拆分出信用账户,资金账户拆分出理财账户,如图5-7所示