PAYATHON 2026

如何通过 GA4 Measurement Protocol 正确归因付费订单设备数据?

支付阿杰

结论

不要把 User-Agent、sec-ch-ua、sec-ch-ua-mobile 或 sec-ch-ua-platform 作为普通事件参数发送。GA4 不会根据这些自定义参数自动填充设备类别、操作系统和浏览器维度。这样发送后,订单可能全部显示为 desktop,也可能按照发送请求的服务器环境来识别。

建议按以下方式处理:

  1. 在用户浏览器中获取并保存原始设备信息。
  2. 在服务端识别设备。
  3. 通过 Measurement Protocol 顶层的 device 对象传递设备属性。
  4. 使用浏览器端生成的 client_id 和 session_id,把 purchase 事件关联到原始会话。
  5. 区分 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。

会话归因还需要满足的条件

设备字段传递正确,并不代表系统一定能恢复原始广告归因。要尽量把服务端订单关联到浏览器中的原始会话,还需要满足以下条件:

  1. client_id 必须来自发生访问和转化的浏览器。
  2. session_id 必须来自对应的 GA4 会话。
  3. timestamp_micros 应反映订单实际发生的时间,并符合 Measurement Protocol 对回填时间的限制。
  4. 订单事件应发送到与浏览器事件相同的 GA4 属性和 Web 数据流。
  5. 如果业务使用 user_id,浏览器事件和服务端订单最好使用相同的 user_id。
  6. 广告点击标识、同意状态及相关来源信息应在访问阶段正确采集。仅靠支付事件中的设备数据,无法事后重建这些信息。

user_id 不能替代 client_id,client_id 也不能替代 session_id。三者各有不同用途。

调试与验证

正式发送前,可以通过 Measurement Protocol 验证端点检查请求结构:

https://www.google-analytics.com/debug/mp/collect

验证请求成功,只能说明字段结构可以被接受。这不代表事件一定已经进入报表,也不能证明渠道和设备归因符合预期。

可以按以下顺序排查:

  1. 确认 device 位于请求顶层,而不是 events[].params。
  2. 确认 category 的值为 desktop、mobile 或 tablet。
  3. 对照浏览器端的 GA4 事件,确认两边的 client_id 和 session_id 完全一致。
  4. 检查 DebugView 和 Realtime 中是否出现 purchase。
  5. 等标准报表处理完成后,再查看设备、系统和浏览器维度。
  6. 如果已经连接 BigQuery,可以检查原始导出数据,排除报表阈值、处理延迟或维度兼容性造成的误判。

如果当前使用的 Measurement Protocol 接口或属性还不接受 device 对象,就无法通过添加任意名称的 UA 参数覆盖内置设备维度。此时应优先由浏览器发送 purchase,或者升级到支持覆盖设备信息的官方 Measurement Protocol 请求结构,并先通过验证端点确认相关字段可以被接受。

备注:内容仅供参考。