如何通过 GA4 Measurement Protocol 正确归因付费订单设备数据?
结论
不要把 User-Agent、sec-ch-ua、sec-ch-ua-mobile 或 sec-ch-ua-platform 作为普通事件参数发送。GA4 不会根据这些自定义参数自动填充设备类别、操作系统和浏览器维度。这样发送后,订单可能全部显示为 desktop,也可能按照发送请求的服务器环境来识别。
建议按以下方式处理:
- 在用户浏览器中获取并保存原始设备信息。
- 在服务端识别设备。
- 通过 Measurement Protocol 顶层的
device对象传递设备属性。 - 使用浏览器端生成的
client_id和session_id,把purchase事件关联到原始会话。 - 区分 GA4 中的 Platform、Operating system 和 Device category。Web 数据流的 Platform 通常仍是
Web,手机和桌面设备应通过 Device category 区分。
为什么当前参数没有生效
下面这些字段即使放在 events[].params 中,也只会被当作自定义事件参数:
user-agent
sec-ch-ua
sec-ch-ua-mobile
sec-ch-ua-platform
例如,以下写法无法覆盖 GA4 的设备维度:
{
"events": [
{
"name": "purchase",
"params": {
"user-agent": "Mozilla/5.0 ...",
"sec-ch-ua-mobile": "?1",
"sec-ch-ua-platform": "\"Android\""
}
}
]
}
即使 sec-ch-ua-mobile 的值是 ?1,GA4 也不会自动把 Device category 设置为 mobile。这些字段同样不会自动映射到 Browser、Operating system 或 Platform。
服务端直接向 Measurement Protocol 发送请求时,请求中的 HTTP User-Agent 很可能来自后端 HTTP 客户端,而不是付款用户的浏览器。因此,依靠这个请求头识别设备并不可靠。
推荐的数据链路
1. 在浏览器侧获取 GA4 标识
创建订单前,应保存浏览器端真实的 client_id 和 session_id:
const measurementId = "G-XXXXXXXXXX";
gtag("get", measurementId, "client_id", (clientId) => {
// 将 clientId 与当前订单一起传给后端
});
gtag("get", measurementId, "session_id", (sessionId) => {
// 将 sessionId 与当前订单一起传给后端
});
实际实现时,可以等待回调完成后再提交订单,也可以提前把这些值写入前端状态。不要等支付成功回调发生后,再由支付服务器重新生成 client_id。
浏览器提供的原始识别信息也可以一并发送到自己的后端:
const deviceSource = {
userAgent: navigator.userAgent,
language: navigator.language,
platform: navigator.userAgentData?.platform,
mobile: navigator.userAgentData?.mobile,
screenResolution: `${screen.width}x${screen.height}`
};
并非所有浏览器都支持 navigator.userAgentData,因此需要处理字段缺失的情况。高熵 Client Hints 还可能需要异步调用 getHighEntropyValues()。不能假设浏览器一定会返回完整的设备型号或系统版本。
2. 在服务端解析并标准化设备信息
服务端应使用成熟的 User-Agent 或 Client Hints 解析库,把原始信息转换为 GA4 所需的明确字段,例如:
{
"category": "mobile",
"operating_system": "Android",
"operating_system_version": "14",
"browser": "Chrome",
"browser_version": "136.0",
"language": "zh-cn",
"screen_resolution": "1080x2400"
}
不要只根据字符串中是否包含 Mobile 来判断设备类别。平板电脑、使用桌面模式的 iPad、部分内嵌 WebView,以及经过缩减的 User-Agent 都可能因此被误判。
3. 通过顶层 device 对象发送
完整的 purchase 请求可以采用以下结构:
curl -X POST \
"https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXXXXX&api_secret=YOUR_API_SECRET" \
-H "Content-Type: application/json" \
--data '{
"client_id": "1234567890.1710000000",
"user_id": "user-12345",
"timestamp_micros": "1710000123456000",
"device": {
"category": "mobile",
"language": "zh-cn",
"screen_resolution": "1080x2400",
"operating_system": "Android",
"operating_system_version": "14",
"brand": "Google",
"model": "Pixel",
"browser": "Chrome",
"browser_version": "136.0"
},
"events": [
{
"name": "purchase",
"params": {
"session_id": 1710000000,
"engagement_time_msec": 1,
"transaction_id": "ORDER-20260318-001",
"currency": "CNY",
"value": 299.00,
"items": [
{
"item_id": "SKU-001",
"item_name": "示例商品",
"price": 299.00,
"quantity": 1
}
]
}
}
]
}'
需要注意各参数所在的层级:
client_id、user_id、timestamp_micros和device位于请求顶层。session_id位于purchase事件的params中。session_id应使用原浏览器会话的值,不能使用订单号或自行生成的新时间戳。transaction_id应保持唯一,避免同一订单被重复计入收入。
Platform 不等于操作系统
GA4 中的几个相关维度含义不同:
- Platform:通常表示
Web、iOS或Android等采集平台。 - Device category:通常为
desktop、mobile或tablet。 - Operating system:例如
Windows、macOS、Android、iOS。 - Browser:例如
Chrome、Safari、Firefox。
如果订单通过 GA4 Web 数据流发送,即使用户使用的是 Android 手机,Platform 仍可能显示为 Web。要查看设备拆分,应使用 Device category、Operating system 和 Browser,而不是要求 Platform 显示为 Android。
会话归因还需要满足的条件
设备字段传递正确,并不代表系统一定能恢复原始广告归因。要尽量把服务端订单关联到浏览器中的原始会话,还需要满足以下条件:
client_id必须来自发生访问和转化的浏览器。session_id必须来自对应的 GA4 会话。timestamp_micros应反映订单实际发生的时间,并符合 Measurement Protocol 对回填时间的限制。- 订单事件应发送到与浏览器事件相同的 GA4 属性和 Web 数据流。
- 如果业务使用
user_id,浏览器事件和服务端订单最好使用相同的user_id。 - 广告点击标识、同意状态及相关来源信息应在访问阶段正确采集。仅靠支付事件中的设备数据,无法事后重建这些信息。
user_id 不能替代 client_id,client_id 也不能替代 session_id。三者各有不同用途。
调试与验证
正式发送前,可以通过 Measurement Protocol 验证端点检查请求结构:
https://www.google-analytics.com/debug/mp/collect
验证请求成功,只能说明字段结构可以被接受。这不代表事件一定已经进入报表,也不能证明渠道和设备归因符合预期。
可以按以下顺序排查:
- 确认
device位于请求顶层,而不是events[].params。 - 确认
category的值为desktop、mobile或tablet。 - 对照浏览器端的 GA4 事件,确认两边的
client_id和session_id完全一致。 - 检查 DebugView 和 Realtime 中是否出现
purchase。 - 等标准报表处理完成后,再查看设备、系统和浏览器维度。
- 如果已经连接 BigQuery,可以检查原始导出数据,排除报表阈值、处理延迟或维度兼容性造成的误判。
如果当前使用的 Measurement Protocol 接口或属性还不接受 device 对象,就无法通过添加任意名称的 UA 参数覆盖内置设备维度。此时应优先由浏览器发送 purchase,或者升级到支持覆盖设备信息的官方 Measurement Protocol 请求结构,并先通过验证端点确认相关字段可以被接受。
备注:内容仅供参考。
