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
purchaseon order confirmation andrefundas 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
Purchaseevent 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:*:
| Meaning | Source | Cart field | Order field | Used by |
|---|---|---|---|---|
| GA client id | _ga cookie | field:tracking:gaClientId | cart:tracking:gaClientId | Google Analytics |
| GA session id | _ga_<container-id> cookie | field:tracking:gaSessionId | cart:tracking:gaSessionId | Google Analytics |
| Meta browser id | _fbp cookie | field:tracking:fbp | cart:tracking:fbp | Meta |
| Meta click id | _fbc cookie / fbclid | field:tracking:fbc | cart:tracking:fbc | Meta |
| Awin click value | awc query parameter | field:tracking:awc | cart:tracking:awc | Awin |
Commerce also captures a small amount of client context automatically when the cart is created, from the request headers — no storefront code required:
| Meaning | Captured from | Cart field | Order field |
|---|---|---|---|
| Client user-agent | User-Agent header | field:client:userAgent | cart:client:userAgent |
| Client IP | Resolved shopper IP | field:client:ip | cart:client:ip |
| Storefront origin | Origin, falling back to Referer | field:storefrontUrl | cart: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 extracart:namespace keeps them clearly separated from app-authored order fields, and they are echoed back in the rendered cart'sfields.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:
| App | Value basis |
|---|---|
| Google Analytics | Goods excl. tax and excl. shipping; tax and shipping sent as their own parameters |
| Meta | Excl. tax, incl. shipping — the standard for the Purchase event |
| Awin | Goods 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:
| App | Destinations per order |
|---|---|
| Google Analytics | Many. Every property configured for the order's channel — typically a master property plus the channel's own |
| Meta | One pixel |
| Awin | One 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
- Storefront Integration — capturing and stamping the tracking ids
- Cart Dynamic Fields — the underlying prefix mechanism
- Cart Lifecycle — where
set-fieldfits in the flow