Skip to content

Commerce applications / Case 21

Real scenario · client identity private

Shopify campaign attribution that survives browsing, login, and Buy It Now

Campaign data needed to reach the Shopify order through both cart checkout and Buy It Now. A 24-hour last-touch snapshot, cart attributes, and product-form properties kept the current campaign attached while expired data was actively cleared.

ShopifyJavaScriptUTMAttributionCart dataAnalytics

What this solved for the business or user

A shopper might arrive from an ad, browse for a while, leave, and come back before ordering. The business needed the most recent valid campaign information attached to the order, but only for a defined 24-hour window.

What was happening

The commerce site needed to capture utm_source, utm_medium, utm_campaign, utm_content, gclid, and fbclid. Attribution should be last-touch: a newer valid marketing visit replaces the previous snapshot. If no order is placed within 24 hours, the old attribution must expire instead of following the customer indefinitely.

Why the obvious solution was not enough

Buy It Now can bypass the cart, so cart attributes alone could not cover every order path. Login navigation and browser history could restore earlier cart state, and ordinary cart updates could replace data that had already been synchronized. Expired campaign values needed active cleanup rather than simply disappearing from browser storage.

How the solution works

  1. Read only recognized marketing parameters from the landing URL and ignore ordinary query parameters that do not represent attribution.
  2. When at least one valid marketing parameter is present, create a new attribution snapshot with a captured timestamp and expiry timestamp.
  3. Store the snapshot in session state for the current browser flow and a cookie so normal navigation or a short return visit can recover it.
  4. Treat a newer valid marketing visit as the new last touch instead of merging two campaigns into one ambiguous record.
  5. Synchronize the current valid attribution into the cart or order metadata layer used by the commerce platform.
  6. Also synchronize the snapshot into product-form line-item properties so the direct Buy It Now path can carry campaign context without depending on a cart-page visit.
  7. Re-check forms and cart data after cart edits, account navigation, browser-history restores, and tab focus so the active snapshot remains consistent across entry paths.
  8. When cleaning captured marketing parameters from the address bar, preserve unrelated query parameters required for product state or theme previews.
  9. Before reading a saved snapshot, compare the current time with its expiry. Remove expired session, cookie, and cart values rather than returning stale data.
  10. Verify order association separately from browser storage. Capturing a UTM value is not useful if it never reaches the final order record.
Simplified expiry rule
const MAX_AGE = 24 * 60 * 60 * 1000;

function isValidTouch(touch) {
  return touch && Date.now() - touch.capturedAt < MAX_AGE;
}

if (hasMarketingParams(location.search)) {
  saveTouch({ ...readMarketingParams(), capturedAt: Date.now() });
} else if (!isValidTouch(loadTouch())) {
  clearTouch();
}

What should be verified before shipping

  • Capture each supported UTM and click ID independently as well as in a full campaign URL.
  • Visit again with a different valid campaign and confirm it replaces the previous last-touch snapshot.
  • Confirm ordinary navigation without campaign parameters does not erase a still-valid touch.
  • Simulate the 24-hour boundary and verify expired session, cookie, and cart attribution is removed.
  • Test guest and logged-in order flows and confirm the final order contains the expected valid attribution values.
  • Complete both cart checkout and Buy It Now and inspect the resulting orders for the same current campaign context.
  • Test cart edits, login navigation, back-button restores, and tab focus before checkout, including an expired snapshot.
  • Confirm marketing-parameter cleanup preserves product and theme-preview query parameters.
  • Ensure a purchase does not accidentally reuse an older expired campaign after the order or cart state changes.

What changed

Campaign attribution became a defined piece of Shopify state with a replacement rule and expiry. Cart attributes covered the normal cart path, while product-form properties covered direct checkout. Restored and updated carts could be reconciled with the current snapshot instead of keeping an old campaign indefinitely.

Reusable lesson

Attribution is state management. Define when the state is created, what replaces it, how long it is valid, and exactly where it becomes part of the order.