互联网账户系统如何设计

转载自  互联网账户系统如何设计

在很多互联网公司业务发展的早期,业务模式比较单一的情况下,涉及用户账户资金交易相关的逻辑也比较简单,但是随着公司业务模式的不断创新及类型的多元化发展,会渐渐发现现有系统账户逻辑越来越雍肿,不仅难以支持新业务的扩张,对现有业务的支持也适配困难,最终导致新业务系统不得不重新搭建自己的业务账户逻辑,造成重复建设不说,也往往给后续的财务资金核算造成混乱。

 

以某互联网A租车公司的业务发展路径为例?

阶段A

A公司在早期开展租车业务时根据用户使用场景规定用户必须在缴纳押金以后才可以租车,并且支持用户进行余额充值,余额可以支付租车费用以及购买相关优惠产品。所以账户资金流是这样子的:

通过上述设计基本上就满足了简单的业务需求,用户缴纳押金单独存放在一个押金账户,用户的每次押金冲退都记录账户流水(缴押金记+,退押金记-);用户余额充值单独存放在一个余额账户,用户的每次余额充值、消费、退款都记录账户流水(余额充值记+、余额消费记-、余额退款记-)。

事实上,以上账户逻辑的设计基本已经能满足业务早期的发展的需要了,并且如果账户流水记录完整(例如记录必要的业务类型,如余额购买了一张租车次卡)那么后续也能基本满足早期业务的财务核算需求。遗憾的是,很多公司在类似以上简单账户逻辑的设计上都比较混乱,如有的公司将账户直接绑定在用户信息表上、有些直接更新账户余额,没有完整记录账户流水或账户流水记录业务信息缺乏等,这种情况即使业务没有多元化发展,也很难满足后续业务逻辑的扩展,特别是会造成严重的财务数据核算困难,更不用谈业务多元化发展后如何能够快速支撑了,造成这种问题的原因是多方面的,这里也就不在赘述。

下面我们继续看A公司租车业务的发展演进情况!

假设在A公司租车业务发展过程中为了鼓励用户进行余额充值,采用了充值+返现的形式进行活动,如:“充值100赠送20”,此时用户余额账户的总金额应该是120,那么账户逻辑如何支持呢?

 

这里注意,之所以需要区分余额中真实充值和赠送的原因在于,如果产品逻辑允许余额退款,那么清晰地区分了真实充值和赠送所对应的余额的话,退款逻辑的实现将会比较简单,否则就会变得比较痛苦,并且不清晰的逻辑也会增加造成公司资金损失的风险;另外如果余额返现账户变动流水记录得比较明确的话,对财务后续的收入核算也会方便很多。

但是,是否这样就能满足业务需求了呢?

显然,这样还不能让逻辑完全运行起来,因为增加了账户相应地交易逻辑与资金逻辑都需要进行相应的改变才行,以上业务场景中原来余额充值只需要调用余额账户记账一次,现在需要根据充返逻辑再调用余额返现账户记账一次;而余额消费则需要根据业务规则进行余额消费记账,假设业务规则为“余额消费优先扣减余额返现账户,再次扣减余额账户”,那么系统交易及记账逻辑如下图所示:

 

从逻辑上看业务交易系统需要根据业务规则多次调用余额账户及余额返现账户进行记账,并且需要从流程上保证两个账户记账调用的事务一致性,例如一笔消费订单金额为20元,此时余额账户余额为10元,余额返现账户余额为5元,在优先消费返现账户金额扣款5元后无法再从余额账户消费15元时,交易失败后需要回滚余额返现账户消费逻辑,余额返现账户“交易冲正 +5”。

 

阶段B

在阶段A中,单个业务会根据不同的产品设计进行账户逻辑的迭代,增加余额充返账户后虽然从账户逻辑层面只是增加了新的资金账户,但是交易逻辑却是进行了较大的变更和调整;如果此时该业务场景又出现新的逻辑变化,例如某一天该租车业务针对某些信用良好的用户进行免押金用车活动,并且支持这类用户在退押金时可以选择将押金的全部或部分金额进行余额充值,那么在流程设计上还会存在账户转账的情况(押金账户->余额账户)。

每次产品业务的迭代涉及用户资金逻辑,都不免会影响交易逻辑及账户逻辑本身,但如果业务品类单一,这种迭代及扩展通过硬编码方式多少还能继续支持。但是,如果随着公司业务向多元化发展,问题往往就变得复杂了。

假设A公司在主营租车业务发展态势进入到趋于平缓的阶段后,为了扩展业务范围需要尝试新的业务,例如,某团队提出不能仅仅只搞租车也得弄个网约车平台,那怎么弄?

 

首先肯定是需要先集结队伍啦。集结完队伍就需要好好分析分析下业务场景了,我们先大概看看一个网约车平台的大概业务场景是什么样子的,其中涉及的资金交易的流程应该如何设计呢?

在A公司的租车业务中,从参与角色角度来看涉及的逻辑并不算太复杂,只有“用户、车、租车公司(内部可称租车业务线)”,而从交易场景上看,用户缴纳押金、预存余额及余额消费都只是单向的C->B交易模型,如果不考虑公司层在线交易账户体系(这里是指公司层面的交易账户)业务复杂度还不算十分复杂,并且在这种单向业务模式下,没有公司层面的在线交易账户本身并不影响业务流程,收入核算只需要线下计算即可,这也就是为什么前面会特意强调账户流水业务关键信息不能缺失的原因了。

而约车业务则是多向的C->B-C-B的交易模型,因为从参与角色上看除了普通打车用户外,还有司机、打车平台都会紧紧地参与到整个业务流程中;而从账户资金流上看用户支付的车费不会以C->C的模式直接支付给司机,而是会由打车平台代收,打车平台扣除订单抽成后剩下的车费才会打到司机在打车平台开的账户上,司机才能从个人账户提现。

 

从上图的分析中我们可以看到,我们需要为普通用户、司机账户、打车平台分别设置必要的账户逻辑,普通用户账户逻辑与之前的租车业务比较类似,用户可以直接支付打车费用、也可以通过余额充值后使用余额支付打车费用;而平台则需要代收用户的打车费用并且需要按照服务规则从代收的打车费用中扣掉部分服务费,然后通过代收/付平台账户将车费实时结算给司机端收款账户,司机通过个人收款账户发起提现后经过结算账户完成提现。资金流如下:

此外,为了满足产品逻辑的扩张,例如要具备冻结司机账户的业务功能,则需要设置冻结账户;平台为了进行市场营销活动,如发放红包则需要设置平台市场营销账户等。

阶段C

业务发展到这个阶段,初步看好像并没有太多的逻辑变动,并且看着只需要扩展下之前租车业务的账户逻辑就好了。但真的是这样吗?

事实上从单纯的产品逻辑来看,同一套个人用户账户貌似是没有什么问题的,但是根据很多互联网公司业务发展的路径来看,不同的业务线根据发展情况不同往往会分别设置不同的法律主体,而且根据业务性质的不同监管层面的政策也是完全不一样的,例如在国内运营的租车业务司机车费代收代发这类业务是要求运营公司具备支付牌照的,没有则会牵扯到非法二清这样的法律风险,而一般来说在没有支付牌照又想继续运营的话,替代方案目前主要是采用银行资金托管的方式,即用户资金通过银行三类账户进行托管。

一旦涉及这类业务,整个系统的业务复杂度会成倍地增长,所以如果采用同一套个人用户账户的话,资金流将会变得难以拆分,对整个系统的升级也会造成比较大的困扰。

另外如果除了租车业务、打车业务外又尝试了别的新业务,如直播之类。业务类型完全不同,且财务本身就要求进行分类的话,只能重新设计新的账户逻辑了;但,从某种角度看这类账户逻辑实质上又是与之前业务存在共性的。如直播类平台也是普通用户充值,购买平台礼物后打赏给主播,此时平台会对用户赠送的礼物抽成后将其转换为可提现的余额结算给主播账户,这类账户逻辑与约车平台其实是很类似的。

那么,是否存在既能统一财务数据又能良好地支持业务的横向扩展相对通用的账户系统模型呢?

接下来继续和大家探讨一套可以持续扩展的业务账户系统该如何设计?

业务模型

首先我们分析下大多数在线资金业务涉及的逻辑实体,用户是第一存在,但是用户根据参与的性质不同又分为普通消费端用户、普通服务端用户,拿打车来说一个普通打车的人属于普通消费端用户,而司机个人则属于普通消费用户,并且司机身份也是可以转换为普通打车用户,另外就是平台用户,是指公司内部各个不同的业务主体,它们关联的法律主体可能是同一个也可能是不同的。

所以综上所说,我们需要的可能是一套“为不同公司主体下,不同业务的同一个/不同用户提供不同账户交易逻辑支撑,并且可以满足业务及用户平滑扩张的系统”。

事实上要达到这样的效果是很难的,需要在系统平台层面进行良好地系统及业务架构设计,并且确保在制定业务规则时遵循一定的制度及规范才行。

以下图示为目前业内相对比较完整的通用账户体系模型,俗称“三户模型”,最早是电信行业为适配复杂通信业务场景而设计的一套账户体系模型;而大部分互联网公司业务的复杂度是低于复杂的电信业务的,所以在这里我们对此模型进行部分改进,以期形成适应互联网公司业务发展的通用账户体系模型。

在上述模型中信息被划分成了三个类型:客户、用户、账户。客户是用户身份信息的承载实体,例如张三这个人是一个客户;而客户也不仅仅只是针对个人,针对业务线所关联的法律主体也划分在客户的范畴,如某某打车公司。而有了基本的客户信息后,企业客户具体可以开展什么业务,普通个人用户是否使用了该企业客户提供的服务,在模型中是采用用户这个概念来承载的。企业客户开展该业务时根据业务的设计需要开通什么平台账户,普通个人用户使用该业务服务需要开通什么样的个人账户都可以根据业务的设计通过用户下设立相应地账户进行隔离区分。

假设此时A公司的租车业务与打车业务法律主体尚未进行拆分属于同一家公司,但是财务上要求隔离两类业务的资金流,那么可以在账户系统上为租车业务开立租车业务用户,如果张三使用了租车业务则为张三设置租车业务用户并在该用户下开立余额、余额返现、押金三类账户并配置业务及记账规则,此外若希望业务资金在平台上也有个完整体现也可以在租车业务用户下设立相应的平台账户,只是业务流程上可以采用缓冲或异步记账的方式。

而打车业务则需要根据普通客户信息为普通打车用户开立相应的个人账户,若是司机则需要开通司机相关的业务账户,而平台也需要开通相应的平台账户。在信息流上,客户信息为所有业务所共用,用户信息则是根据不同的业务设置,账户是根据业务挂在相应地业务用户下。如若各业务间没有横向地联系,各业务层账户体系根据自身业务分别运行、互不干扰,而如果存在联系,如租车余额可以进行打车,则可以设计为允许业务层间账户的互转,只是这种资金流会更复杂,需要配置的记账分录也会更加复杂。

以上述模型的定义而设计的账户系统会初步形成一个具备支持多类业务账户逻辑并行的通用中台账户系统雏形,从财务角度看账户层次会相对清晰。另外,图中还定义了机构的概念以支持总公司-分公司这样具备层级关系的财务核算需求,当然这种情况在互联网公司的扁平化模式下并不常见,所以可以暂时忽略。

本篇通过业务场景举例从业务模型上大概阐述了互联网账户系统如何设计得相对通用和清晰,事实上在系统设计上也需要进行更多的设计,并且需要根据公司实际业务情况进行一定的取舍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325956.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数组(ArrayList)底层怎样扩容

ArrayList维护了数组transient Object[] elementData; 初始化 数组需要扩容时

Visual Basic 15语言新特性

对于C#的两个重要特性元组和Ref返回值,Visual Basic 15提供了对等的实现。这两个特性都是“不完全的”,但已经可以提供足够的变通方案,让VB应用程序可以消费使用了这些特性的C#库。 元组 在VB中,从单个函数调用直接返回多个值是…

Struts2面试问题

转载自 Struts2面试问题 1.什么是Struts2? Apache Struts2是一个用Java构建Web应用程序的开源框架。Struts2基于OpenSymphony WebWork框架。它从Struts1中得到了很大的改进,使其更加灵活,易于使用和扩展。Struts2的核心组件是Action&…

谷歌工程师文化中的几个核心原则

转载自 谷歌工程师文化中的几个核心原则 每周,一组谷歌员工都会在厕所的墙壁上粘贴一页来分享本周的测试小建议。有时这页纸会讨论依赖注入,并提供一个简单的示例展示如何用不同语言使用它;有时它可能会分享如何安装一个用于测量团队代码库…

初探CSRF在ASP.NET Core中的处理方式

前言 前几天,有个朋友问我关于AntiForgeryToken问题,由于对这一块的理解也并不深入,所以就去研究了一番,梳理了一下。 在梳理之前,还需要简单了解一下背景知识。 AntiForgeryToken 可以说是处理/预防CSRF的一种处理…

HBase体系架构说明

HBase体系架构说明! client:两种—-Hbase shell 命令行接口 JavaAPI client访问Region不能直接访问,首先client需要先连接到zookeeper,zookeeper管理HMaster,说明,hdfs集群,在没有zookeepe…

asp.net core 编译mvc,routing,security源代码进行本地调试

因为各种原因,需要查看asp.net core mvc的源代码来理解运行机制等等,虽说源代码查看已经能很好的理解了。但是能够直接调试还是最直观的。所有就有了本次尝试。因调试设置源代码调试太辍笔,所以不用这个方法,转而使用编译源代码的…

并查集判断是否有环存在

题目描述 思路分析 代码实现 package com.atguigu.disjointSet;public class djset {public static int VERTICES6;public static void initialise(int parent[]){int i;for (i 0; i < VERTICES; i) {parent[i]-1;}}public static int find_root(int x,int parent[]){int …

Visual Studio 2017更新,侧重于提高稳定性

Microsoft已对其旗舰开发软件产品Visual Studio 2017&#xff08;VS2017&#xff09;的安装程序和设置引擎做了全新设计&#xff0c;意在能快速地部署更新到VS2017。VS2017的第一个命名版本更新在VS2017首发的一个月后就可用&#xff0c;这充分体现了这一全新设计的优势所在。 …

阅读器关闭时尝试调用Read无效时的解决方法

今天在写asp .netmvc的项目时&#xff0c;发现了个困扰我很久的问题&#xff0c;经过仔细研究终于解决了。 问题如下&#xff1a; 首先来看一下原来有问题的代码&#xff1a; public static SqlDataReader Excutereader(string sql,params SqlParameter [] param) {using (SqlC…

.NET或将引入类型类和扩展

类型类是另外一项正被考虑引入.NET未来版本的特性。在提案“外观和扩展&#xff08;Shapes and Extensions&#xff09;”中&#xff0c;该特性被称为外观&#xff0c;它们将大幅提升.NET泛型的能力。Mads Torgersen这样描述类型类&#xff1a; 接口抽象的是作为类型实例的对象…

成为更优秀的程序员:退后一步看问题

转载自 成为更优秀的程序员&#xff1a;退后一步看问题 一天&#xff0c;在工作中… Bug #3890 来自客户&#xff1a; 有个程序出现了错误&#xff0c;程序提示说“SpeedCalculator::compute()里出现了除零情况”。 请尽快修复&#xff01; 你打开SpeedCalculator.php&#…

深夜福利, 小试linuxkit

前言 今天小编的朋友圈被DockerCon和linuxkit刷屏了&#xff0c;再不出来写点linuxkit的东东恐怕就要跟不上时代了。小编翻阅了N多的有关linuxkit的文章&#xff0c;发现绝大多数都是英文的讲解&#xff0c;小编本着对读者负责的态度决定先将linuxkit的文章翻译成中文&#xff…

.NET Core 2.0及.NET Standard 2.0

.NET Core 2.0的发布时间&#xff0c;.NET Core 2.0预览版及.NET Standard 2.0 Preview大概在5月中旬或下旬发布。 .NET Core 2.0正式版本发布时间大约在Q3 2017发布&#xff0c;具体我估计大概在8月份左右。同时一起发布的也就是.NET Standard 2.0。 MilestoneRelease Date.…

Linux清理磁盘挂载点方法(亲测有效)

问题现象 Linux操作系统云服务器根目录空间占用率过高。例如&#xff0c;以图1为例&#xff0c;根目录空间占用率为96%。 根目录空间占用率过高 查询当前系统存在一个约42G 大小的文件access_log&#xff0c;这个文件应该是apache产生的访问日志文件&#xff0c;从日志大小来…

.NET程序在Linux容器中的演变

本文将首先讨论镜像的构建时间和启动时间&#xff0c;接着会将一个简单的.NET程序运行在基于容器的应用上&#xff0c;然后观察镜像大小的变化&#xff0c;最终缩短镜像的构建和加载时间。此外&#xff0c;代码优化是本文的另一个主题。 现在&#xff0c;.NET开发人员可以无障…

微服务的概念——《微服务设计》读书笔记

《领域驱动设计》&#xff08;Eric Evans&#xff09;&#xff1a;告诉我们用代码呈现真实世界的重要性&#xff0c;并且告诉我们如何更好地建模。 持续交付理论&#xff1a;如何更有效及更高效地发布软件品&#xff0c;并指出保持每次提交均可发布的重要性。 六边形架构理论&a…

想要玩转实现负载均衡,你知道这些吗?

转载自 想要玩转实现负载均衡&#xff0c;你知道这些吗&#xff1f; 一、前言 互联网早期&#xff0c;业务流量比较小并且业务逻辑比较简单&#xff0c;单台服务器便可以满足基本的需求&#xff1b;但随着互联网的发展&#xff0c;业务流量越来越大并且业务逻辑也越来越复杂&…

netcore实践:跨平台动态加载native组件

缘起netcore框架下实现基于zmq的应用。在.net framework时代&#xff0c;我们进行zmq开发由很多的选择&#xff0c;比较常用的有clrzmq4和NetMQ。 其中clrzmq是基于libzmq的Interop包装&#xff0c; NetMQ是100%C#的zmq实现&#xff08;基于AsyncIO组件&#xff09;。以上两种…