Skip to content

Conversion Tracking

A family of apps that report conversions to advertising and analytics platforms server-side, from the order rather than from the browser. Each app listens for the same order lifecycle events, maps them to its platform's event format, and sends them from a reactor.

Server-side reporting exists because browser tags are unreliable: ad blockers, tracking prevention, and shoppers who close the tab before the thank-you page all lose conversions. The order actor, by contrast, always knows a purchase happened.

Where a platform de-duplicates on a transaction identifier, these apps send the order number, so a browser tag firing for the same order collapses into one conversion instead of double-counting.

Available tracking apps

  • Google Analytics 4 — GA4 Measurement Protocol. Sends purchase on order confirmation and refund as units are returned, attributed via the GA client id captured at the storefront. Reports to several properties per order — a master property plus the channel's own — for multi-site setups.
  • Meta Conversions — Meta Conversions API. Sends a Purchase event with hashed customer data, de-duplicated against the browser Pixel on the order number.
  • Awin — Awin server-to-server conversion tracking. Reports a sale when an order is confirmed, attributed via the Awin click value, with per-channel and per-country advertiser resolution.

The tracking-id convention

Every one of these apps needs something the browser knows and the server does not: a cookie value, a click id, a session id. The storefront captures it and puts it on the cart; Commerce carries it onto the order; the tracking app reads it off the order graph.

The shared namespace for this is field:tracking:*, which Commerce projects onto the order as cart:tracking:*:

MeaningSourceCart fieldOrder fieldUsed by
GA client id_ga cookiefield:tracking:gaClientIdcart:tracking:gaClientIdGoogle Analytics
GA session id_ga_<container-id> cookiefield:tracking:gaSessionIdcart:tracking:gaSessionIdGoogle Analytics
Meta browser id_fbp cookiefield:tracking:fbpcart:tracking:fbpMeta
Meta click id_fbc cookie / fbclidfield:tracking:fbccart:tracking:fbcMeta
Awin click valueawc query parameterfield:tracking:awccart:tracking:awcAwin

Commerce also captures a small amount of client context automatically when the cart is created, from the request headers — no storefront code required:

MeaningCaptured fromCart fieldOrder field
Client user-agentUser-Agent headerfield:client:userAgentcart:client:userAgent
Client IPResolved shopper IPfield:client:ipcart:client:ip
Storefront originOrigin, falling back to Refererfield:storefrontUrlcart:storefrontUrl

The client IP is captured at creation rather than completion because a cart is often completed by a PSP callback, whose IP is the payment provider's, not the shopper's.

Adding a new platform needs no Commerce change

The namespace is vendor-neutral. A new tracking app picks a key under field:tracking:, the storefront stamps it, and it arrives on the order — no change to apps.commerce at all.

Why field: and not order:

Commerce projects three prefixes onto the order, and the choice matters here:

  • field:<key>cart:<key> — for values that originate at the storefront, i.e. from an untrusted client. The extra cart: namespace keeps them clearly separated from app-authored order fields, and they are echoed back in the rendered cart's fields.
  • order:<key><key> — for values an app authored server-side. These land unprefixed in the order's shared dynamic map, so they must be vendor-prefixed to avoid collisions.

Tracking ids come from the browser, so they belong in field:. An app that derives its own attribution data server-side should use order: with a vendor-prefixed key instead.

Reporting the conversion value

The apps deliberately do not agree on what a conversion is worth, because the platforms don't:

AppValue basis
Google AnalyticsGoods excl. tax and excl. shipping; tax and shipping sent as their own parameters
MetaExcl. tax, incl. shipping — the standard for the Purchase event
AwinGoods excl. tax and excl. shipping — commissionable value only

Each app follows its platform's convention rather than a house style, so the numbers line up with what the platform's own reporting expects.

One target or many

The apps also differ in how many destinations a single order reaches:

AppDestinations per order
Google AnalyticsMany. Every property configured for the order's channel — typically a master property plus the channel's own
MetaOne pixel
AwinOne advertiser, resolved country → channel → app default

The multi-property case is specific to analytics, where a group-level roll-up alongside per-market properties is a standard reporting setup rather than an edge case.

See Also

© 2026 Hantera AB. All rights reserved.