简介:《OCS计费原理与实现(排版后)》面向电信运营商业务支撑、计费系统设计与运维人员,系统梳理在线计费系统的核心概念、工作流程与落地实现。内容从离线计费向实时计费的演进切入,解释TAG、业务用量、费用项、产品、订购、入帐关系等关键术语,并围绕事件捕获、事件处理、账单生成与结算展开计费原理,进而讨论计费引擎、数据库、消息中间件及安全机制等实现要点。资源包仅含1个doc文档,约1.87MB,排版后更便于通读和查阅,适合作为OCS入门梳理与项目设计参考。目前已有297人学习,可帮助读者建立从业务术语到系统实现的整体认知,理解实时信用评估、额度控制与费用归属等关键环节,为计费流程优化和系统设计提供参考。
1. 先看一个场景:余额只剩三块,为什么电话还能再打两分钟
挂掉电话才发现余额只剩几块钱,可刚才那通电话并没有被立刻掐断,只是响了一声提示音——很多人以为系统是事后才来收钱的,实际上从你按下拨号键的那一刻起,运营商那边已经在一边放行、一边算钱、一边盯着你的余额了。这套“边用边算、算完就扣”的系统,就是 OCS(Online Charging System,在线计费系统)。它要回答的问题听起来不复杂:这次消费该收多少钱、用户付不付得起、付得起就先放行多少,但真落到实现上,概念、流程、配置数据一大堆,新人很容易一上来就被术语劝退。这份《OCS计费原理与实现》就是专门为降低这个门槛写的,从名词解释到呼叫、充值、月结三条主流程,一层层往下走,适合刚接触计费、还分不清批价和入帐的新手。
2. 先想清楚为什么学:四代计费系统的演进就是一部“被需求逼出来”的历史
很多人学 OCS 卡在第一步,不是因为公式难,而是因为不知道这些概念是怎么长出来的。你把手上的名词当成凭空出现的定义去背,当然背完就忘。换个顺序会轻松很多:先看计费系统这二十年被业务需求推着走了哪几步,每一步卡在哪里、怎么改的,等你把这条线捋顺,回头再看“业务用量”“定价计划”“模板”这些词,会发现每一个都对应着某一次具体的麻烦。
2.1 四代演进:每一代到底卡在哪个环节
最早的计费需求朴素得可爱,只要主被叫号码不同、费率不同就行。当时的做法是两张表:一张用户表存余额,一张费率表按主被叫的归属地、拜访地号码头去查费率。欠费怎么防?用反算,也叫预算——用户打电话之前,系统先根据余额算出“你最多还能打几分钟”,把这个时长交给呼叫控制系统去盯着,通话结束再按实际时长扣钱。这套做法很粗糙,但它已经把在线计费最核心的两个动作摆出来了:事前给额度、事后结账。
问题很快来了。一个地区有多个号段,主叫归属地、主叫拜访地、被叫归属地、被叫拜访地四个维度一组合,费率表的记录数直接爆炸。更麻烦的是局方隔三差五调费率,每调一次就要人工分析这张巨表里哪些记录要改,改漏一条就是投诉。于是有了第二步改造:把查费率拆成三段——先用号码分析把号码头归一到地区号,再用计费矩阵把一次呼叫拆成基本费、漫游费、长途费三类消费并各自对应一个消费类别索引,最后用一张很小的费率表承接具体价格。费率要调只动费率表几条记录,新增号段只动号码分析表,维护成本一下子降下来。
再往后,单纯降价拉不动用户了。运营商开始上套餐:消费积分、专款专销(50 元买 500 分钟长途,只能打长途)、充值优惠(充 100 送 40 分月返还)、越打越便宜(前三分钟四毛,之后两毛、一毛)。这一轮改造动的是骨架:系统一分为二,实时计费模块管每通电话的费率计算,定期事务模块管赠送、月租、分月返还这些按天跑的后台动作;用户余额被抽象成“帐户”,可以有好几种类型,长途免费时长、市话免费时长、赠送金额、累计消费各占一个;消费类别从一个纯粹的费率索引,扩展成“这笔消费只能在哪些帐户上扣、按什么顺序扣、费率是多少”,费率本身也支持分档。
到了业务内容变丰富的阶段,前面这套又不够用了。一卡多用要求同一个余额能同时被通话、上网、短信几种业务占用,而老机制里一个帐户同一时间只能被一个业务锁着;计费单位从单一的“通话时长”变成条数、流量、直接扣款金额;套餐推出节奏越来越快,靠调消费类别来凑优惠既不直观也容易出错;预付费和后付费明明只是付款方式不同,却要走两套逻辑;代码分支越加越多,改一个资费可能顺手把别的模块带翻。这一轮的解法是把概念再抽象一层:把“消费类别”升级成“业务用量”——既说清消费的是什么业务,也说清消费了多少量;把每种计费请求抽象成“计费事件”,影响计费的参量抽象成“计费要素”;把实时模块和定期模块里那些可复用的计费能力抽成“模板”和“策略”;再用“定价计划”把这些模板组装成一个可售卖的产品。预付费和后付费则统一用三种用量来区分:请求业务用量、授权业务用量、已使用业务用量。
提示:这条演进线不用背年份,只要记住每一代是被什么问题逼出来的。你后面遇到的绝大多数配置难题,本质都是“这次的业务形态,超出了当初那套抽象能覆盖的范围”。
2.2 学会 OCS 之后,你能接住哪几类活
搞清楚原理之后,最直接的收益是配资费不再靠试。一个套餐上线,你要回答的无非是几个问题:这次消费属于哪类计费事件、命中哪个定价计划、调用了哪些模板、产生哪几条费用项、从哪些帐户按什么顺序扣。这五个问题在流程里都有明确落点,你只要知道去哪一层看,就不用把整条链路重新猜一遍。
第二类收益是排查。现网出问题的时候,最怕的是只知道“钱扣错了”却不知道错在哪一步。懂原理的人会按预处理、批价、入帐三段去切,先确认业务用量的数值对不对,再确认费率规则命中得对不对,最后确认入帐关系和帐户优先级对不对。三段各自有输入输出,切开来一看,问题范围立刻缩小一大半。
第三类收益是沟通。计费系统从来不是孤立的,上游有业务控制,下游有帐务和客户关系管理,中间还有一堆定期任务。你在会上听到“授权额度没返回”“累计项没累上”“回赠没触发”这些说法时,能立刻对上它在流程里的位置,讨论效率完全不一样。
这份资料本身也有个很实在的定位:它不教你成为定位问题的专家,也不是资费配置的参考手册,更不教你搭测试环境。它干的事是把原理讲透,让你在没有真实环境的情况下也能把很多工作往前推。对刚入行的人来说,这个顺序其实是对的——先看懂,再动手。
3. 零基础第一课:把十个名词翻译成人话
概念抽象是在线计费劝退新人的头号原因。这一章不讲流程,只做一件事:把这些名词一个个摁到具体场景里。你不需要记住定义,只需要在脑子里建立画面,后面看流程的时候能对上号就够了。
3.1 从一张超市小票看懂业务用量、费用项和 TAG
想象你在超市买了 2 瓶矿泉水、4 个面包。这里“矿泉水 2 瓶”“面包 4 个”就是业务用量——它描述的是“消费了什么、消费了多少”,不谈钱。放到呼叫场景里,主叫在漫游状态下拨了一个长途,通话 5 分钟,那么这次消费会同时产生三条业务用量:基本费时长 300 秒、长途费时长 300 秒、漫游费时长 300 秒;如果用户没漫游,漫游那条就是 0 秒。业务用量的种类是设计阶段就规划好的,不是运行时临时拼的。
TAG 就是这些业务用量的编号。可以把它理解成变量名,只不过计费侧习惯用数字而不是英文名,说“TAG 1080 的值是 300”,比说一长串变量名省事。下面这张表是某地局点呼叫主叫子流程划分的用量示意,看一眼有个印象就行,不用记:
| 用量名称 | TAG | 备注 |
|---|---|---|
| 基本费时长 | 2003 | 主叫侧必出 |
| 长途费时长 | 2005 | 拨打长途时出 |
| 漫游费时长 | 2004 | 主叫漫游时出 |
| 被叫漫游长途时长 | 2311 | 被叫侧场景 |
| 附加费业务量 | 2317 | 预留未用 |
批价算完之后,会输出一串费用项,你可以直接把它当成超市小票上的消费明细:矿泉水 2 瓶 4 元、面包 4 个 4 元。计费里的小票长这样——业务用量 2003 基本费时长 300 秒,金额 50 分,归到“本地通话费用项”;2005 长途费时长 300 秒,金额 100 分,归到“长途通话费用项”;2004 漫游费时长 300 秒,金额 150 分,归到“漫游通话费用项”。三条费用项串成链表,就是这次通话的完整消费清单,也是下一步入帐的输入。
这里最容易混的一点是:业务用量和费用项不是一回事。业务用量是“用了多少”,费用项是“这笔用量算出来多少钱、归到哪一类”。一个人可以有多条业务用量却只产生一条费用项(比如几条用量合并计价),也可能一条用量拆成几条费用项(比如跨了分档)。
3.2 产品、订购、入帐关系:谁决定怎么算,谁决定从哪扣
产品在计费侧统一理解成“定价计划”,也就是一整套费用计算体系。你可以把它想成一张套餐卡:里面写着这个套餐含多少免费资源、超出之后什么价、哪些场景有优惠。它不是一条费率,而是一包规则的集合。
订购回答的是“这个用户拥有哪些定价计划”。这一步非常关键,因为它是所有优惠生效的前提——用户没订购,这套定价计划对他就是不存在。实际运维里也靠这个机制做隔离:新套餐上线前把测试号订购上,只有测试号会走新逻辑,其他用户完全不受影响。
入帐关系回答的是另一个问题:这笔消费明细,应该在哪个帐户上扣。用户身上可以挂好几个帐户,长途免费时长一个、市话免费时长一个、赠送金额一个、基本余额一个,入帐关系就是那张“哪类费用项允许扣哪些帐户、先后顺序如何”的对照表。
把三个词串起来看:用户订购了某个定价计划,这个计划规定了怎么算钱;算完产生费用项;入帐关系规定这些费用项去哪几个帐户里按什么顺序扣钱。缺任何一环,钱都扣不对。
3.3 模板与策略:为什么新套餐能只加数据不改代码
这是整套设计里最值得新手多花十分钟理解的地方。模板(有的地方叫策略模板)是把某一种计费能力封装成一个可复用的模块,把差异做成参数。比如“定期赠送话费”这件事,逻辑是固定的,但赠多少、赠几个月、赠到哪个帐户,这些是参数。封装好之后,赠送模板就变成一个可以被反复调用的积木。
定价计划则是拿这些积木搭出来的成品。举个例子,一个“20 元套餐,赠 300 分钟市话、200 条网内短信、省内漫游一毛一分钟”的活动,实现方式是:调用赠送模板,参数填“300 分钟市话”“200 条网内短信”;调用呼叫计费模板,参数填费率“一毛每分钟”,适配条件填“省内漫游”。整个过程没有写新代码,只是新增了一份定价计划数据。
这个设计带来两个直接好处,也是新手配数据时最该守住的两条底线。第一是兼容性:新增定价计划只是加数据,不改动现网已有的任何逻辑,上线风险天然可控。第二是可测试性:因为走订购,测试用户订购了新计划才会命中新规则,其他用户的计费路径完全没变,测试范围天然被圈住。
反过来,如果你图省事直接去改一个现网已经在用的模板或者费率,那就是把所有订购了这个计划的用户一起拖下水,这是新人最容易犯的错,后面避坑那一章还会专门讲。
4. 第一个能跑通的例子:跟着一通电话走完计费全流程
概念铺垫完,该上流程了。这一章用一次最普通的呼叫把三段主链路走一遍:预处理、批价、入帐。你不需要有环境,拿纸笔跟着推一遍就行。推完这一遍,你再看充值、月结这些支线,会发现它们只是换了输入和模板,骨架是一样的。
4.1 预处理:把零散的呼叫信息整理成能算的形状
呼叫刚开始或者刚结束时,计费系统拿到的东西其实是零散的:号码、时间戳、位置信息、请求的时长、业务类型标识等等。这些东西格式不统一、字段可能缺失、单位可能不一致,直接拿去算钱肯定出错。预处理干的就是“整理”这件事。
它的输入是原始请求或者话单,输出是一组标准化的计费事件和计费要素。具体做什么呢?补齐缺失的要素、把号码解析成归属地区和拜访地区、把业务类型映射到对应的计费事件、把各种时间戳换算成统一的时长单位、做一些基本的合法性校验。你可以把它理解成餐厅后厨的备菜环节:菜洗好切好按份分好,炒菜的人拿起来就能下锅。
新手在这里不需要钻到“预处理机制”内部去看它怎么编排、怎么配置,只要记住它的输入输出:进来的是原始记录,出去的是干净的、带齐要素的计费事件。你排查问题的时候,如果怀疑数据不对,第一步就该来这里看要素补齐了没有。
4.2 批价:五分钟通话的每一分钱是怎么算出来的
批价是整个 OCS 里最核心的一段。它分两步走:先做业务识别,再做批价处理。
业务识别解决的是“这次消费该按哪套规则算”。它会根据计费事件、用户号码、位置、时间等信息,找出用户订购的定价计划里,哪一个适配当前场景。比如同一通电话,省内漫游和省内非漫游命中的规则可能完全不同,这一步就是做这个匹配。
批价处理解决的是“按规则算出具体金额”。它拿着业务用量和命中的费率规则,逐条算钱,过程中还要处理分档(前多少分钟一个价、超过之后另一个价)、免费资源抵扣、累计项累加这些情况。下面这段示意代码演示了最朴素的算法,只是为了让你看清“用量乘费率”这个动作长什么样,真实系统比这复杂得多:
def price_event(usages, rate_plan): # usages: 业务用量列表,每项形如 {"type": "基本费时长", "qty": 300} # rate_plan: 命中的费率规则,key 是业务用量类型,value 含单价和计价单位 items = [] for u in usages: rule = rate_plan.get(u["type"]) if rule is None: continue # 该用量类型没有配费率,就不产生费用项 # 按计价单位折算金额:qty 单位是秒,unit 表示多少秒一个计费单位 amount = rule["rate"] * u["qty"] / rule["unit"] # 封顶保护,没配 cap 就取原值 amount = min(amount, rule.get("cap", amount)) items.append({ "usage_type": u["type"], "qty": u["qty"], "amount": amount, }) return items这段代码里几个参数值得说清楚。usages里的qty单位必须和rate_plan里unit的单位对齐,一个用秒一个用分钟,算出来就会差六十倍,这是实际配置里最常见的一类错误。rate是每个计价单位的价格,unit是计价单位的大小,比如rate=0.1, unit=60表示六毛钱一分钟。cap是单条费用项的封顶值,用来兜住异常用量。
拿刚才那通电话套一下:主叫漫游打长途 5 分钟,市话费率一毛一分钟、长途两毛一分钟、漫游三毛一分钟。三条用量都是 300 秒,算出来分别是 50 分、100 分、150 分,一共 300 分也就是 3 块钱。三条费用项串成链表,就是这次呼叫的消费清单。
真实批价里还有两个绕不开的动作。一个是免费资源抵扣:如果用户帐户里还有 300 分钟市话免费时长,那 50 分那条费用项就该被抵掉,而不是照扣。另一个是累计项:有些规则要看用户本月已经打了多少分钟才能定档,这就需要在批价过程中读累计值、算完再写回去。这两个动作都有固定的执行顺序,顺序错了金额就错。
4.3 入帐:钱从哪个账户扣、按什么顺序扣
批价输出费用项链表,入帐接手。入帐要回答两个问题:扣哪个帐户、按什么顺序扣。
第一个问题靠入帐关系。前面说过,入帐关系是一张“哪类费用项允许扣哪些帐户”的对照表。比如长途通话费用项只允许从长途免费时长、赠送金额、基本余额这三类帐户里扣。如果这张表里没配某个帐户,那这个帐户对这类费用就是不可见的,钱不会从那里走。
第二个问题靠帐户优先级。同样一笔费用,先扣免费时长、再扣赠送金额、最后扣基本余额,这是最常见的顺序。为什么要讲这个?因为顺序决定了用户体验和争议。如果先扣了基本余额,把免费时长留到最后,用户月底一看“我明明有免费时长怎么还扣钱了”,工单就来了。
入帐完成后,预付费用户这边基本就结束了,最多再出一张话单留档;后付费用户后面还要接帐单生成、帐单寄送、欠费催缴这一串动作。两边的批价入帐逻辑其实是一致的,差别只在后续环节有没有人找你收钱。
4.4 充值、月结和免费资源:另外三条必须知道的支线
呼叫流程走通了,另外三条支线就好理解了,因为它们共用同一套骨架,只是输入和调用的模板不同。
充值流程的输入是一笔充值请求,预处理阶段把充值金额、赠送规则、生效时间这些要素整理好,然后调用对应的赠送模板,算出这次该给用户加多少钱、分几个月返还、返到哪个帐户。回赠这个概念就在这里出现:充 100 送 40,不是一次性到帐,而是拆成若干期,每期由一个定期任务触发。
月结流程是典型的定期事务,按周期跑一次,做的事情包括出帐、扣月租、触发赠送、处理回赠。它和呼叫流程最大的区别是触发方式:呼叫是被动的、事件驱动的;月结是主动的、定时跑的。所以月结出问题往往不是算错了,而是任务没跑、跑的顺序不对、或者上一轮的状态没清干净。
免费资源和累计项这两块,建议新手单独拿出来看。免费资源处理决定了用户套餐里那些“送的时长、送的流量”怎么被消耗;累计项处理决定了“本月已用多少”“连续几个月在网”这类跨次消费的状态怎么维护。这两块不出现在主流程图上,但几乎每一个真实套餐都要用到。
5. 新手避坑:五类最容易翻车的地方,先看现象再看原因
原理看懂了不等于不犯错。这一章列的都是新手在配数据、看流程时最容易踩的坑,每条按“现象、原因、解决”写,你可以当成一张检查表放在手边。
5.1 概念先分清:四组最容易混成一团的词
第一组是业务用量和费用项。前者是“用了多少”,后者是“算出来多少钱、归到哪一类”。混了之后,你会去费率表里找“本地通话费用项”的价格,找不到是正常的,因为价格挂在业务用量上。
第二组是产品和模板。产品是能卖的东西,模板是搭产品的积木。有人问“新增一个模板算不算新增一个产品”,不算,模板只有被定价计划引用之后才对用户可见。
第三组是订购和入帐关系。订购决定“这套规则对这个用户生不生效”,入帐关系决定“钱从哪个帐户扣”。两个都配对了,钱才扣得对;只配对一个,要么不生效,要么扣错地方。
第四组是授权业务用量和已使用业务用量。前者是系统在消费前给出的“允许你用多少”,后者是消费结束后上报的“你实际用了多少”。预付费靠前者控风险,后付费靠后者算钱,搞反了就会出现在线用户被超额放行或者后付费用户被提前限额的情况。
5.2 现象、原因、解决:五条最常遇到的翻车现场
现象一:新套餐上线,测试号用着正常,隔天收到其他用户的投诉。
原因通常是为了图快,直接改了现网某个已经在用的模板或费率,而不是新增一个定价计划。所有订购了原计划的用户,瞬间都走进了新逻辑。
解决方式是回到“新增定价计划加重订购”这条路上来。模板本身只在确有必要扩展能力时才动,动之前要确认它被哪些计划引用,改完的影响面有多大。这条血泪经验几乎每个做计费的人都交过学费。
现象二:通话时长明明五分钟,算出来的钱差了整整六十倍。
原因多半是单位没对齐。业务用量的数值单位是秒,费率规则里配的计价单位是分钟,代码按分钟去除秒数,结果自然离谱。这种图表上看不出来,因为两边都是“合法”的数字。
解决方式是配完费率先倒推一遍:拿一个整数时长手工算一次,和系统跑出来的金额对一下,对不上就先查单位。倒推的这一步花不了一分钟,能省掉后面几个小时的排查。
现象三:费用算对了,但钱从错误的口袋里扣了。
原因出在入帐关系或者帐户优先级。常见的是新加了一种帐户类型,忘了在入帐关系里挂上去;或者优先级配反了,先扣了基本余额,把免费时长留到最后。
解决方式是先看费用项类型,再查这类费用项允许扣的帐户清单,最后核对优先级顺序。顺序不对的话,即使金额一分不差,用户体验也是错的。
现象四:用户套餐里有免费时长,第一个电话却直接扣了余额。
原因通常是免费资源没被正确识别或者没被优先消耗。可能是免费资源的配置没挂到当前定价计划上,也可能是批价抵扣那一步的执行顺序不对。
解决方式是先把这次消费的业务用量、命中的定价计划、可用的免费资源余额三样列出来,确认免费资源确实存在且被识别到,再去看抵扣动作有没有执行。
现象五:预付费用户余额早就该耗尽了,电话却一直能打通。
原因通常在授权环节。要么是反算出来的授权业务用量没有被正确返回给业务控制侧,要么是请求业务用量压根没发出去,直接按后付费的方式在跑。
解决方式是沿着“请求业务用量进、授权业务用量出”这条线看一遍,确认每个环节的数值都在动。这条链路不出问题,欠费风险控制才成立。
6. 下一步学什么:从看懂流程到能配出一个简单套餐
如果你已经把前面几章跟下来了,接下来别急着去啃最厚的部分,按这个顺序走会顺很多。
| 阶段 | 目标 | 具体做什么 |
|---|---|---|
| 第一阶段 | 名词不卡壳 | 合上资料,用自己的话把业务用量、费用项、定价计划、订购、入帐关系各讲一遍,讲不通的回头再看 |
| 第二阶段 | 三条流程走通 | 呼叫、充值、月结各画一遍输入输出,重点是充值那条,它比呼叫简单,适合练手 |
| 第三阶段 | 批价能手工算 | 拿一个三档费率加免费资源的例子,纸笔算一遍金额,再和示意代码对一遍 |
| 第四阶段 | 能配一个套餐 | 从“20 元套餐赠 300 分钟市话”这种最简单的开始,配完自己走一遍订购加消费 |
这里给你一个具体技巧,比看十遍流程图都管用:找一张 A4 纸,横着画三栏,左边写这次消费的业务用量和数值,中间写命中的定价计划和调用的模板,右边写产生哪几条费用项、从哪几个帐户按什么顺序扣。三栏都填满,说明这条链路你看懂了;中间那栏填不出来,说明你还没搞清楚这次消费到底命中了哪套规则。这个动作在排查阶段尤其有效,比直接上去改配置安全得多。
还有一点,别一上来就去啃批价的分档细节和复杂的适配条件。真实套餐里的分档经常是好几层叠加的,新手硬啃容易钻进去出不来。先把“一条用量、一条费率、一个帐户”这种最小闭环跑通,再往上面叠免费资源、累计项、跨月回赠。这个顺序反过来,很容易学了一堆细节却说不清一次通话到底发生了什么。
我现在还保留着一个习惯:每次碰到算不对的资费,先不碰数据,拿张纸把用量、计划、模板、费用项、帐户这五样写出来,写不全就说明我还没看懂,这时候改配置基本是瞎蒙。这习惯救过我很多次,也让我少了很多事后返工。希望帮到你。
本文还有配套的精品资源,点击获取