
计费引擎设计:复杂费率如何准确、可解释、可运营
原创2026/7/2大约 7 分钟
计费引擎设计:复杂费率如何准确、可解释、可运营
计费的底线不是算出一个金额,而是任何费用都能解释当时用了哪条规则、哪些输入和哪个版本。
为什么值得讨论
走廊、币种、金额、客户等级、活动和专属价会组合出复杂规则。本文把定价从散落代码变成统一、可运营的领域能力。
适合读者:支付商业化、定价产品、账务、财务和计费研发团队。
1. 设计目标与原则
- 统一:所有产品线的费用计算收敛到一个引擎,杜绝各业务自算费(否则账单对不平、审计无法追溯);
- 报价即锁定:对客展示的费用在 Quote 有效期内不可变,实扣必须等于报价(03 篇:全球付款系统:从指令生命周期到失败退回);
- 可审计:每笔费用可追溯到"费率规则 + 规则版本 + 计算过程";
- 可运营:销售可申请商户专属价,审批后生效,全程留痕;
- 计费与收费分离:计费(算多少)、收费(何时怎么扣)、结算(账单聚合)三层解耦。
2. 领域模型
ProductCode(计费对象) 收款入账 / 提现 / 本地Payout / SWIFT-Payout(SHA|OUR) /
换汇 / 退票 / 账户月费 / 增值服务...
PriceScheme(价格方案)──┐ 标准价卡(按商户分层:S0标准/S1银牌/S2金牌...)
MerchantPrice(专属价)──┼──► RateRule(费率规则)
CampaignPrice(活动价)──┘
RateRule {
rule_id / version / status(草稿→审批中→生效→失效)
scope: product_code, currency_pair?, channel_type?, corridor?(国家/币种走廊)
charge_type: FIXED | PERCENT | FIXED_PLUS_PERCENT | TIER(阶梯) | FX_MARKUP(bps)
params: { fixed, percent, min_fee, max_fee, tiers[], markup_bps }
fee_currency_policy: 交易币种 / 指定币种 / 商户结算币种
effective_from / effective_to
}
FeeItem(计费结果,不可变){
fee_id, order_id, product_code, rule_id+version(溯源)
calc_snapshot(输入参数与计算过程快照)
amount / currency, charge_mode(内扣/外扣/账单), status(已锁定/已收取/已退还/已核销)
}要点:
- 匹配优先级:活动价 > 商户专属价 > 商户分层标准价,同级按 scope 精确度(走廊级 > 币种级 > 产品级)取最特定规则;匹配不到 = 拒绝交易(而非默认免费——宁可失败不可漏计费);
- FX Markup 也是 RateRule:换汇加点作为一种 charge_type 统一管理,报价引擎(04 篇:换汇与头寸管理:定价、敞口与流动性的系统解法)向计费引擎取商户的 markup_bps 后生成对客价——这是"隐性计费显性管理"的关键;
- FeeItem 不可变:费用调整走"退费/补收"新 FeeItem,与账务红字冲正原则(06 篇:金融账务核心:多币种账户与复式记账怎么设计)一致。
3. 计费流程
3.1 交易内计费(主流程)
业务下单 → 计费引擎.quote(order 上下文)
① 规则匹配(优先级 + scope 特定度)
② 计算(含阶梯:取商户当月累计量定档,见 §3.3)
③ 生成 FeeItem(status=已锁定,绑定 Quote 有效期)
业务确认执行 → 计费引擎.confirm(fee_id)
④ 按 charge_mode 触发收费:
内扣:出款金额 = 订单金额 − 费用
外扣:另生成余额扣费的记账事件
账单:仅记账挂应收(月末出账,见 §5)
⑤ 发记账事件 → 记账核心生成费用分录([06 篇:金融账务核心:多币种账户与复式记账怎么设计](/posts/payments/ledger-core/)模板)
交易失败/退票 → 计费引擎.reverse(fee_id)
⑥ 退费政策引擎:渠道费不退/平台费可退([03 篇:全球付款系统:从指令生命周期到失败退回](/posts/payments/global-payout-lifecycle/) §6.2),生成红字 FeeItem3.2 周期计费(月费类)
调度任务按账期生成 FeeItem → 余额扣费;余额不足进入欠费状态机(宽限期 → 限权 → 清欠)。
3.3 阶梯计费的工程细节
- 档位依据:商户自然月累计交易量(金额或笔数),计费时点取已确认量,避免并发下档位抖动;
- 跨档策略:整单按当前档(简单,推荐)vs 分段计价(精确,复杂),一期用整单按当前档;
- 月末重算:若承诺"整月量回溯定档",月末批量重算差额,以退费/补收 FeeItem 体现——政策要在商务合同里写清,系统两种都支持。
4. 与关联系统的接口
| 系统 | 交互 |
|---|---|
| 报价引擎(04) | 取 FX markup_bps;费用与汇率共同构成对客 Quote,同一有效期 |
| 订单中心(09) | quote/confirm/reverse 三接口,幂等(order_id + product_code) |
| 记账核心(06) | 费用记账事件(收费/退费/账单应收),分录模板由记账核心管理 |
| 账单服务(08 §4) | FeeItem 明细供账单聚合,账单必须与 FeeItem 逐笔对平 |
| 运营后台 | 费率配置、审批流、专属价管理、模拟试算 |
| 数据平台 | 收入分析(按产品/走廊/商户的毛利),FX 收入需结合头寸损益(04 §6) |
5. 账单与商户侧透明度
- 账单结构:账期 + 期初/期末余额 + 交易明细 + 费用明细(按 ProductCode 分组小计)+ 税费(如适用 GST/VAT)——逐笔可下钻到 FeeItem;
- 费用预估 API:下单前商户可调用试算接口(quote-only),电商 ERP 集成场景刚需;
- 账单制(后付费)客户:FeeItem 挂应收 → 月末账单 → 商户付款核销;超期走催收与授信冻结(03 篇:全球付款系统:从指令生命周期到失败退回待定点 4,需授信管理模块支持);
- 税务:部分辖区对手续费征收增值税/消费税,税率由计费引擎按商户税务属地计算并在账单单列——税务字段一期就要留(和 legal_entity 一样属于"后补极贵"的字段)。注意依赖关系:税务属地判定取决于与商户签约的持牌主体是谁——本项与 18 篇:法人主体与资金结构:跨境支付架构真正的地基《法人主体与资金结构》强关联,主体结构定了税务方案才能定。
6. 运营治理
- 变更流程:草稿 → 模拟试算(对最近 30 天真实交易回放,输出收入影响)→ 审批(四眼)→ 定时生效;
- 灰度与回滚:新价卡先对白名单商户生效;规则版本化天然支持回滚;
- 一致性监控:每日核对 FeeItem 总额 vs 账务费用科目发生额(08 篇:清结算与对账:如何持续证明每一分钱都对得上内部对账的计费专项);
- 防呆:percent 与 bps 单位混淆是经典事故源,配置界面强制单位显示 + 超阈值(如单笔费率 >5%)二次确认。
设计取舍
- 阶梯计费的跨档与回溯政策(商务合同模板需同步);
- 账单制授信额度模型与催收流程归属(风控域 or 结算域);
- 税务引擎自建 or 外采(Avalara 类),取决于持牌主体分布;
- 一期价卡结构:建议只上"标准价 + 商户专属价"两层,活动价二期。
核心结论
- 费率规则必须版本化并保存计算快照。
- 匹配不到规则应拒绝交易,不能静默免费。
- 费用明细、账务科目和客户账单必须逐笔对平。