4.2 计量计费:用量采集与账单

场景:免费额度撑不出商业模式

系统跑顺之后,CEO 拿着一张 Excel 找我:这是十五户的用量,你看看我们到底该怎么收钱。表格里是各户的人数、活跃度、存储量和 API 调用次数,散乱无章。他那句话我印象深刻:「要是一直按人头包年,我们就是在给大户打工、给小户做慈善。」

事实确实如此。按人头包年是最省事的计费方式,但它把成本结构掩盖了:存储大户每天上传二十个 GB,付费却与一个只存五十 MB 的户相同;API 调用密集的客户每个月打两百万次接口,成本几乎都在带宽与数据库连接上,而账单上看不出任何差异。SaaS 的利润藏在用量曲线里,看不到用量就等于闭着眼睛定价。

我们花了一个季度做计量计费体系,目标有三:用量能采、账单能算、客户能懂。前两件是技术问题,第三件是产品问题,而且最难——账单是客户每个月都会认真看的东西,它比任何功能都更代表公司的专业度。如果非要用一句话总结这个季度的投入,那就是:免费额度撑不出商业模式,而撑不出商业模式的系统也还不上它欠下的技术债。

计费维度是第一个要定的事:

维度 计量容易度 反映成本程度 客户理解度
按人头 容易 低 高
按存储量 容易 高 中
按 API 调用 中 高 低
按活跃用户 中 中 高

最后的组合是:人头做基础套餐(含基础配额),存储与 API 超出部分按量加费,活跃用户单独做了一档企业版,给那些需要专属支持的客户一个明确的身份标签——他们付的溢价买的不是功能,而是服务承诺。这个组合的核心思想是把「变化的成本」与「固定的价值感」分开收:客户买套餐买的是确定感,超量付费买的是弹性。定价会议吵了三回,最后大家都接受了一个朴素的判断标准——任何一条计费规则,如果客服在电话里三句话解释不清,就简化它。这条标准事后被证明比任何定价模型都管用。

演进:三代计费形态

计费体系同样走了三代,周期比别的模块更长,因为它牵扯合同与财务流程:

代际 形态 痛点
第一代 人工 Excel 按人头包年 大户亏、小户赚
第二代 自动采集按固定档计费 边界情况争议多
第三代 组合计费与双路径对账 仍在演进

第二代的争议率最高,每个月都有客户来讨论「我们到底用到了哪一档」。第三代的改进不只是算得准,更重要的是账单带上了用量图表与历史对比,客户自己就能看出为什么是这个数——透明本身就是争议的灭火器。账单与用量图表上线后第一年,我们做到了年底续费谈判时没有任何一家客户再要求逐条对账,这在以前是不可想象的。

配置:用量采集与计费流水

采集写在中间件层,每个请求的计费点统一记录,日结落库,绝不实时扣费——实时扣费在性能与一致性上都是灾难:

class MeteringMiddleware
{
    public function handle($request, Closure $next)
    {
        $start = microtime(true);
        $resp  = $next($request);

        $ctx = app(TenantContext::class);
        // 只计费业务接口,健康检查与内部调用跳过
        if ($this->shouldMeter($request)) {
            $this->meter->record([
                'tenant_id' => $ctx->id(),
                'route'     => $request->path(),
                'calls'     => 1,
                'bytes_in'  => strlen((string) $request->getContent()),
                'bytes_out' => strlen($resp->getContent()),
                'day'       => date('Ymd'),
            ]);
        }

        return $resp;
    }
}

采集先写本地缓冲,异步批量入库,高峰期每分钟落一次。账单计算是独立的日结任务,逻辑只有三段:上月结算日到本结算日之间的用量汇总、按套餐规则算出各档费用、生成账单与明细 PDF。三段之间用幂等键保护,日结任务可以安全重跑而不会重复计费——这个设计在某个春节假期救了我们一次,那天的定时任务因为时区问题跑了三次,幂等键替我们省掉了成百上千张错误账单。账单明细必须细到客户能自己复核的程度——我们遇到过三次客户对账单的疑问,两次是客户自己改名导致重复计数(是 bug),一次是我们把分页放大成了调用次数。账单系统必须默认自己是错的,这是对账文化的基础,也是技术团队对财务最负责的态度。

每个字段背后都有一段故事。比如明细里专门有「调用次数」与「有效调用次数」两列,后者扣除了系统自身的健康检查与重试。增加这一列的原因是一家客户的技术负责人自己写脚本对过账,发现账单比他抓包看到的多出百分之十,差点怀疑我们虚报——查清楚之后我们主动把那笔差价退了,并把扣除规则永久写进了账单。那次之后我们的原则是:客户能自己算的账,才是站得住的账。

账单生成后还有一道审核:任何超出阈值百分之三十的账单会自动标记并推送给客户成功经理,先于客户自己发现异常。这个动作把三次可能引发续费危机的误计费消化在了客户问之前。信任在账单上尤其脆弱,提前一步解释和事后解释,效果天差地别,前者叫主动服务,后者叫亡羊补牢,客户记得的往往是后者而不是前者。

量化:计量体系的健康指标

计量系统是系统中不能出错的少数几个模块之一——它错了不是故障,是法律风险。我们用三个指标盯着它:

指标 采样方式 健康标准
采集丢失率 网关日志与入库计数比对 小于十万分之一
账单差异率 双路径并行计算对账 完全一致
客户争议率 财务工单分类 逐月下降

第二项的双路径对账值得多写一句:我们把账单用两套独立实现各算一遍,结果不一致就告警。第一版我自己都觉得过度工程,但它真的拦截过一次——某个月的天数计算被夏令时坑了,算多算了一天。双路径的意义不在于哪条路对,而在于两条路必须有相同的答案,不一致本身就是信号。

踩坑:计费路上的四个雷

第一个坑是计量点与业务脱节。中间件按路由名计费,结果同一个路由因参数不同工作量差十倍(列表接口),客户为「一次调用」付了很多份钱。细化后按返回数据量分级计费,并把规则写进了帮助文档,规则越透明,争议越少。这个教训也提醒我们:任何技术上的省事,在计费场景里都会变成客户关系上的费事,计量点的颗粒度必须对齐客户的直觉而不是代码的直觉。

第二个坑是免费试用期的计量阈值。一开始试用不限量,被某家公司拿来跑生产业务。后来试用设上限并在到达百分之八十时提醒,到期自动停写不停读,既防了滥用又给了缓冲。

第三个坑是套餐变更的过渡计费。月中升级套餐按天换算每月跑出几十种边界情况,总有客户对不上。最后简化了规则:变更次月生效,本月按原套餐执行,把复杂的换算留给产品规则而不是计费代码。简单规则胜过聪明代码,产品规则上的克制才是计费系统最好的架构。后来这条经验被我们写进了新员工入职材料,标题就叫「别和账单耍聪明」。

第四个坑是账单 PDF 的生成时机。月末最后一天集中生成,服务器经常排队到凌晨,而客户成功经理第二天就要用。我们把生成时间滑到了每月第一天的六点,主动改了客户习惯后发现没有任何人抱怨——没有人在月末最后一天真的期待账单出现,也没有客户成功经理喜欢在系统最繁忙的窗口做客户沟通。

小结

计量计费不能只当财务功能来做,它是 SaaS 商业的镜像:用量采得到,定价才谈得上科学;账单算得清,客户才敢持续把业务放上来;规则足够简单,客户成功经理才解释得清。技术上的要点是采集与计费分离、日结代替实时、双路径对账兜底;产品上的要点是把账单当作每月一次的品牌接触点来做——它是客户唯一一定会打开的页面,上面写的每一个数字都在替公司说话。下一节看安全边界,那是账单之外另一个容易掉以轻心的方向。再给两个账单产品化的细节。第一个是账单的可解释性:客户收到一笔四位数的账单时,最想看到的不是总数,而是「为什么是这个数」。我们的账单页拆到每个计费项的明细用量(多少次接口调用、多少 GB 存储、多少条短信),并附上月环比。复购率较高的客户几乎都养成了先看明细再付款的习惯。第二个是争议账单的处理闭环:账单上每一行都支持一键发起争议,工单直达财务与客户成功经理,七天内必有结论。这个功能上线第一年收到四十多单争议,其中三分之一是我们真的算错了——要不是这个通道,这些错大概率永远不会浮上来。账单系统不怕算错,怕的是算错了客户没有方便的渠道告诉你。把争议通道做出来之后,我们的账单准确率也被客户的眼睛推着上了一层台阶。

延伸阅读