Commerce tracking
Commerce tracking
Section titled “Commerce tracking”MetriXs tracks commerce the same way for every site, whether you run Shopify, a custom-built storefront, or a server-side checkout. There are no commerce- specific columns: commerce is just a set of custom events with a few agreed-upon property names. When you enable commerce on a site, the dashboard shows Revenue, Average Order Value (AOV), conversion rate, a checkout funnel, and a top-products breakdown, all driven by those events.
Enable commerce on a site
Section titled “Enable commerce on a site”- Go to Settings → Sites in the dashboard.
- Find your site and toggle Commerce to On.
- Optionally pick a display currency (default EUR; see below).
Shopify sites have commerce on by default (the MetriXs web pixel fires the events for you); the toggle and currency are still there if you want to turn commerce off or change the display currency. Custom sites opt in here and fire the events themselves. A copy-paste event snippet appears on the site’s Install & verify page once commerce is on.
The event schema
Section titled “The event schema”Three custom events make up the commerce funnel. Send them from your checkout in this order:
| Event name | When to fire | Required props |
|---|---|---|
checkout_started |
Visitor enters checkout | total, currency |
payment_submitted |
Payment details submitted | (none) |
order_completed |
Order is placed (thank-you / confirmation) | total, currency |
For order_completed, you may also send an items property with the per-
product breakdown so the Top Products panel can break revenue down by product.
Property names
Section titled “Property names”total(number) — the order/cart total.currency(string, ISO 4217, e.g.EUR,USD,GBP) — the currencytotalis in. MetriXs converts it to EUR (see below).items(string) — a JSON-encoded array of{ title, quantity, price }(one object per line item).order_id(string, optional) — your internal order id, for reference.
Revenue is stored in EUR
Section titled “Revenue is stored in EUR”MetriXs stores all revenue in EUR. When a commerce event arrives with a
non-EUR currency, the ingestion pipeline converts total (and each item
price) to EUR using daily ECB reference rates before storing it, and
records the original currency as currency_original. The stored total is
therefore always EUR, so revenue and AOV are consistent even for multi-
currency stores.
- If you omit
currency, MetriXs assumes the amount is already EUR (no conversion). - Unknown currencies are left as-is (treated as EUR) so a typo never silently zeroes your revenue.
- The rates are the ECB’s daily reference rates, refreshed automatically every day (a cron fetches the official ECB feed and caches the rates in Redis). If the fetch fails or the cache is cold, MetriXs falls back to a static reference table baked into the image, so EUR normalization never breaks on an upstream outage. Reference rates are not live trading rates.
Display currency
Section titled “Display currency”While revenue is stored in EUR, you can choose a different display currency per site. MetriXs converts the EUR-stored amounts to your display currency in the dashboard using the same daily ECB rates, so Revenue, AOV, the Revenue graph, the funnel, Top Products, and the revenue column in the Sources/Locations/Devices panels all show in your chosen currency.
- Default: EUR (no conversion).
- Set it per site in Settings → Sites alongside the commerce toggle. The list covers the common currencies (USD, GBP, CHF, SEK, NOK, DKK, PLN, CZK, CAD, AUD, JPY, INR, CNY, BRL, and more).
- This is a display setting; it does not change what is stored or how you
send events. Always send
currencyon the event for accurate EUR conversion.
Fire the events from a browser checkout
Section titled “Fire the events from a browser checkout”After the tracker script is installed, the global window.metrixs(name, { props })
function is available. Fire the events from your checkout flow:
// visitor enters checkoutwindow.metrixs('checkout_started', { props: { total: 49.99, currency: 'EUR' } })
// payment details submittedwindow.metrixs('payment_submitted', { props: {} })
// order placedwindow.metrixs('order_completed', { props: { total: 49.99, currency: 'EUR', items: JSON.stringify([ { title: 'T-shirt', quantity: 2, price: 24.99 }, ]), },})Use keepalive: true (or a navigator.sendBeacon fallback) on the
order_completed call if your thank-you page unloads quickly.
Fire the events server-side (after a payment webhook)
Section titled “Fire the events server-side (after a payment webhook)”Redirect-based checkouts (Stripe, Mollie, iDEAL, etc.) often never reach a
browser “thank you” state reliably. In that case, send order_completed from
your backend after the payment provider’s webhook confirms the order.
- In the dashboard, go to Settings → Sites, expand API keys under the site, and create a site-scoped key. Copy it immediately (it’s shown once).
POSTto/api/eventwith the key as aBearertoken. The body is JSON. Noteitemsis a JSON-encoded string (an array serialized to a string), because MetriXs stores all event props as strings:
{ "n": "order_completed", "u": "https://yourdomain.com/thanks", "d": "yourdomain.com", "p": { "total": 49.99, "currency": "EUR", "items": "[{\"title\":\"T-shirt\",\"quantity\":2,\"price\":24.99}]" }}Equivalent curl:
curl -X POST https://app.metrixs.eu/api/event \ -H "Authorization: Bearer mtx_live_yourapikey" \ -H "Content-Type: text/plain" \ -d '{"n":"order_completed","u":"https://yourdomain.com/thanks","d":"yourdomain.com","p":{"total":49.99,"currency":"EUR","items":"[{\"title\":\"T-shirt\",\"quantity\":2,\"price\":24.99}]"}}'Requirements for the server-side path:
- The API key must be site-scoped to the site sending the event (the
ddomain). The API rejects the request if the key’s site doesn’t matchd. u(page URL) andd(domain) are required and must match a verified site on your account.Content-Typeistext/plain(avoids a CORS preflight on the browser path; the API parses the body as JSON regardless).- The browser bot-detection token is skipped for API-key-authenticated requests, because a server can’t produce a browser fingerprint and the key already proves the caller is the site owner’s backend.
- The same per-IP rate limit as the browser path still applies.
What you get in the dashboard
Section titled “What you get in the dashboard”Once commerce is on and events are flowing, the site’s dashboard shows:
- Revenue — sum of
totalonorder_completedevents (shown in your display currency; stored in EUR). - AOV — revenue ÷ number of
order_completedevents. - Conv. rate —
order_completedcount ÷ unique visitors × 100. - Conversion funnel — visitors →
checkout_started→payment_submitted→order_completed. - Top products — revenue and quantity per product title (from
items). - Revenue per source / location / device — the Revenue column appears in those panels too, so you can attribute revenue to a campaign or channel.
Migration from Google Analytics 4
Section titled “Migration from Google Analytics 4”If you already fire GA4 e-commerce events via the dataLayer, the property
shapes are similar but the event names differ. The minimum mapping:
| GA4 event | MetriXs event |
|---|---|
begin_checkout |
checkout_started |
add_payment_info |
payment_submitted |
purchase |
order_completed |
The items array uses { title, quantity, price } instead of GA4’s
{ item_name, quantity, price }, so rename item_name to title when you
adapt your existing dataLayer push.