This is a last-click (UTM-based) attribution system. We prioritize data sources that capture the customer’s most recent measurable marketing touch before purchase.
Primary Attribution Source Hierarchy
The order attribution system evaluates data sources in this specific priority order:| Priority | Source Type | Description |
|---|---|---|
| 1 | Shopify Custom Attributes Override | Order-level attribution set via Shopify customAttributes (Checkout / Admin GraphQL API). Treated as an explicit override (shopify_custom_attribute_override). |
| 2 | Shopify Last Customer Visit | The final tracked visit before order placement, captured by Shopify’s customer visit tracking |
| 3 | Shopify Landing Site | UTM parameters extracted from the order’s landing page URL |
| 4 | Shopify Order Notes (Legacy) | UTM data written to order notes / note attributes by tracking tools (Elevar, Blotout, etc.) |
| 5 | Website Event Tracking | First-party event pixels from GA4, Elevar, or other website analytics |
| 6 | Shopify First Customer Visit | The customer’s first tracked visit, captured by Shopify’s customer visit tracking |
| 7 | GA4 | Transaction data from Google Analytics 4 |
| 8 | Shopify Order Referring Site UTMs | UTM parameters parsed from the order’s referring_site URL |
Universal Analytics (UA) has been sunset by Google. If your organization already exported and retained historical UA data, treat it as historical-only and prefer GA4 for ongoing tracking.
Website Event Tracking Details
For website event tracking sources (priority 5), the system uses qualifying events within a 90-day lookback window before the order. When multiple events exist, they’re ranked by:- Days between event and order (closer to order = higher priority)
- Event timestamp (earlier
event_local_datetimewins ties) - Event ID and source system (as final tie-breakers)
referral.
Shopify Custom Attributes Override (Priority 1)
If your Shopify order has attribution data written tocustomAttributes (Shopify Admin GraphQL API / Checkout attributes), SourceMedium treats it as an explicit override and prioritizes it ahead of the default Shopify attribution sources (visits, landing site, website events, GA4).
This is the recommended mechanism for:
- Backfilling attribution onto historical orders
- Capturing UTMs at checkout when cookie-based tracking is unreliable (ad blockers, ITP, cross-domain, etc.)
Supported keys (allowlist)
Only a specific set of keys are extracted fromcustomAttributes to prevent accidental capture of non-attribution data.
Keys are normalized (case + delimiter + snake/camel agnostic) before matching:
utm_source,utmSource,UTM_SOURCE,utm-source→ treated as the same keysm_utmParams,smUtmParams→ treated as the same keyGE_utmParams,ge_utm_params→ treated as the same key
| Key | Purpose |
|---|---|
sm_utm_source, sm_utm_medium, sm_utm_campaign, sm_utm_content, sm_utm_term, sm_utm_id | SourceMedium override keys (recommended to avoid collisions with other apps) |
utm_source, utm_medium, utm_campaign, utm_content, utm_term, utm_id | Standard UTM keys |
sm_utmParams, utmParams, GE_utmParams | Aggregate UTM query-string fields (parsed into individual UTM keys) |
sm_referrer, referrer | Referring URL |
Conflict resolution (deterministic)
If yourcustomAttributes data is messy (duplicate keys, multiple sources provided), SourceMedium applies a deterministic waterfall to resolve each final field.
Field-level precedence
For each UTM field, the first non-empty value wins (highest → lowest):- Direct SM override key (
sm_utm_*) - Direct standard UTM key (
utm_*) - Parsed from
sm_utmParams(query string) - Parsed from
utmParams(query string) - Parsed from
GE_utmParams(query string) utm_sourceonly: click ID inference (scclid→irclickid→msclkid→ttclid→fbclid→gclid)
referrer is resolved similarly: sm_referrer → referrer.
Duplicate keys (same tier)
If the same normalized key appears multiple times at the same tier (for example bothutm_source and UTM_SOURCE, or repeated utm_source entries), SourceMedium de-dupes deterministically using MAX() (lexicographically largest value after decoding/cleaning).
To avoid surprises, only set each key once.
Click IDs are processed as a fallback (see below), but the raw click ID values are not stored as attribution fields.
Aggregate UTM fields
If you sendsm_utmParams, utmParams, or GE_utmParams as a URL query string (e.g., utm_source=google&utm_medium=cpc), SourceMedium parses it and extracts the individual UTM keys. Parsing is snake/camel agnostic (both utm_source= and utmSource= are supported) and URL-decoding is applied.
URL Handling
URL encoding insm_utmParams, utmParams, and GE_utmParams values is fully decoded:
- Percent encoding:
%XXpatterns (e.g.,%20→ space,%26→&) - Form-style encoding:
+characters are decoded as spaces (common in checkout apps)
Click ID to Channel Inference
When only a click ID is present (no explicitutm_source), the system infers a fallback utm_source value:
| Priority (highest first) | Click ID | Inferred utm_source | Platform |
|---|---|---|---|
| 1 | scclid | snapchat | Snapchat Ads |
| 2 | irclickid | impact | Impact (Affiliate) |
| 3 | msclkid | microsoft | Microsoft/Bing Ads |
| 4 | ttclid | tiktok | TikTok Ads |
| 5 | fbclid | meta | Meta (Facebook/Instagram) |
| 6 | gclid | Google Ads |
- Direct
customAttributesclick ID keys (e.g.,scclid,gclid) - Click IDs embedded inside
utmParams - Click IDs embedded inside
GE_utmParams
Click IDs are fallback only. If an explicit
utm_source exists, it takes precedence over any click ID inference.Checkout UI Extensions (recommended)
Use Shopify Checkout UI Extensions to write attribution to checkout attributes (which become ordercustomAttributes).
Checkout UI extensions are sandboxed and can’t access the browser DOM (e.g.,
document.cookie, localStorage, or window.location). Capture UTMs on the storefront and write them into cart/checkout attributes before checkout starts.Custom attributes may be used by other apps. To reduce collisions, prefer
sm_utm_* / sm_utmParams keys for explicit overrides (matching is normalized, but canonical keys reduce ambiguity).Shopify Order Notes (Priority 4)
Order notes are a key attribution source written by server-side tracking tools like Elevar and Blotout. These tools capture UTMs at checkout and write them to Shopify order notes / note attributes.If you have control over implementation, prefer customAttributes override (priority 1) instead of writing attribution into notes. Notes are shared and can be overwritten by apps; custom attributes are clearer and explicitly prioritized.
Note Attributes (Legacy)
The system supports extracting attribution from legacynote_attributes patterns, including:
- Standard UTM keys like
utm_source,utm_medium,utm_campaign,utm_content,utm_term,utm_id - Tool-specific payloads (e.g.,
_elevar_visitor_info) when they contain nested UTM data
UTM Field Collapsing
After the primary source is determined, the system “collapses” supplementary UTM fields from lower-priority sources. Example: If priority 2 (Last Customer Visit) providesutm_source=google but no utm_campaign, and priority 3 (Landing Site) has utm_campaign=summer_sale, the final attribution will combine:
utm_source=google(from priority 2)utm_campaign=summer_sale(from priority 3)
utm_source grouped channel is the same across sources—we don’t mix data from different channels.

