支付系统知道你赚了多少钱,统计应该告诉你钱从哪里来。前提是收入以设计良好的事件到达:在服务端确认、按订单号去重、处理好币种和退款。本文讲要发的事件、属性、规则,以及它们能算出的指标。
读完你会知道
- 付款确认时从服务端发下单事件,带订单号、金额和币种
- 按订单号去重,退款单独发事件,币种按下单当天汇率换算
- 客单价、ARPU、付费率、复购率和 LTV 都能从干净的下单事件里算出来
统计里的收入埋点是什么
在统计工具里做收入埋点,是把每一笔下单和退款作为带金额的事件发送,这样收入就能按和其他数据一样的维度拆分:渠道、活动、落地页、设备、同期群。支付系统早就知道你赚了多少钱;统计告诉你钱从哪里来、是哪些行为带来的。
前提是收入事件设计得当。缺订单号、只在浏览器端发下单事件、多种币种混在一起,产出的收入数字没人信,最后每次争论都是财务的表格胜出。
要发的事件和属性
两个事件就能覆盖大多数业务:支付成功时发下单(purchase),退钱时发带同一个订单号的退款(refund)。订阅业务再加续费(通常就是又一次 purchase),需要的话再加套餐变更。下表列出让这些事件有用的属性。
浏览、加购、结算是行为事件,它们进漏斗,但不带收入。只有确认的付款才应该产生收入。
| 属性 | 示例 | 作用 |
|---|---|---|
| order_id | ord_1001 | 去重键;把退款关联到下单 |
| revenue | 49.00 | 下单或退款的金额 |
| currency | USD | 换算成同一基础币种时需要 |
| items | [{sku, category, price, quantity}] | 商品、品类和品牌排行 |
| coupon、plan | SPRING10、pro | 按优惠或套餐拆分收入 |
| 访客或会话标识 | 从浏览器传给服务端 | 保留买家的来源和会话 |
退款事件用同一个 order_id。
从服务端发下单事件
在支付渠道确认付款的那一刻,从你的服务端发下单事件,而不是在浏览器的「感谢页」上发。浏览器事件会因为页面提前关闭而丢失,会被部分插件拦截,刷新时还可能发两次。服务端知道付款是真的发生了。
为了让这笔订单仍然关联到访客的来源和会话,把浏览器端的访客或会话标识随订单一起传给后端,再放进服务端事件。登录的买家可以用 identify 关联到用户 ID。示例是 TapCub 格式的服务端事件,用订单号作 insert_id。
{
"events": [{
"type": "track",
"event": "purchase",
"login_id": "user_8f21",
"insert_id": "ord_1001",
"time": 1762214400000,
"session_id": "sess_7d2c",
"properties": {
"order_id": "ord_1001",
"revenue": 49.00,
"currency": "USD",
"items": [{ "sku": "pro-annual", "price": 49.00, "quantity": 1 }]
}
}]
}去重、退款和币种
三条规则能避免大多数收入对不上的问题:
- 用订单号做去重键。支付回调会重试。重试再发一次同样的下单时,订单号要让第二份成为空操作,而不是第二笔订单。
- 退款单独发事件。不要删除或修改原来的下单事件。把退款和收入并列展示,毛收入和净收入都看得到。
- 一定要带币种。按下单当天的汇率换算成同一个基础币种;换算不了的订单要标出来,而不是去猜。
示例流水展示了这几条规则:重试的回调被忽略,退款记到对应订单上,币种异常的订单被标出。
订单流水 · 收到的事件
今天purchase ord_100149.00 USD · 付费搜索 · user_8f21+49.00已计入purchase ord_1001回调重试 · 订单号相同0.00重复已忽略purchase ord_1002129.00 EUR · 按下单日汇率换算+138.70已计入refund ord_0987上周一笔订单的退款−29.00已记退款purchase ord_1003未知币种代码「XXX」—未换算
由这些事件得到的收入指标
下单和退款事件干净了,大多数收入指标不用再额外埋点:
- 收入和订单数:下单的金额总和和笔数;退款单独列出。
- 客单价:收入 ÷ 订单数。
- 付费率:买家 ÷ 当期活跃用户。
- ARPU 和每买家收入:收入 ÷ 活跃用户,收入 ÷ 买家。
- 复购率:下单两次以上的人 ÷ 买家。
- 按同期群的 LTV:按首购月份分组的人均累计收入。
这些指标都能按获客渠道拆分,这正是在统计里跟踪收入的意义。订阅业务再加上收入留存,见流失率和留存率。
和支付系统对账
统计里的收入很难和支付系统分毫不差:测试订单、币种舍入、拒付、时间点都会不同。每月对一次账:先比订单数(每笔付款都发了事件的话应该非常接近),再比金额。订单数有差距说明漏发了事件;只有金额有差距,通常是币种或退款的处理方式不同。
TapCub 里的收入埋点
TapCub 用下单和退款事件建立订单流水。默认名称是 purchase、refund、revenue、currency 和 order_id,可在业务设置里修改。金额按下单当天的汇率换算成站点基础币种,换算不了的订单会被标出,退款单独列示而不是直接扣减。订单号是去重键,下单事件里的 items 数组能生成商品、品类和品牌排行(见文档交易与收入)。
交易报表基于流水显示收入、订单、买家、客单价、付费率、人均收入和每买家收入、首购人数、复购率、退款,以及按首购月份的生命周期价值。服务端事件发往 track 接口,带 insert_id 和毫秒级 time(见文档服务端事件)。目标收入是对目标事件上的某个属性求和,和订单流水不是一个数,不要放在一起比。埋点方案的其余部分见事件埋点一文。
常见问题
什么是收入埋点?
把每一笔下单和退款记录成带金额和币种的统计事件,从而能按渠道、活动、页面和同期群分析收入。
下单事件该从浏览器发还是从服务端发?
从服务端,在付款确认时发。浏览器事件可能丢失、被拦截或重复。
怎样避免同一笔订单被算两次?
用订单号作为事件的去重键,这样回调重试或页面刷新都不会产生第二笔订单。
退款要从收入里扣掉吗?
和收入并列单独展示,毛收入和净收入都看得到;退款作为独立事件发送,带上原订单号。
为什么统计里的收入和支付系统对不上?
测试订单、币种换算、退款、拒付和时间点都不一样。先比订单数,再比金额。
这篇文章对你有帮助吗?
我们会根据反馈修改和补充这篇内容。
提交没有成功,请稍后再试。
谢谢你的反馈,我们会据此改进这篇内容。你已经反馈过这篇了,谢谢。


