We’re upgrading our email infrastructure — for immediate response, email andrewjgaber@gmail.com meanwhile.
Skip to main content
Part of Digital Empire
Product analytics / CDP

Segment Analytics.js analytics.track('Order Completed') at Shopify checkout

Segment (Twilio) · Web Pixels API replacement · confidence: high

Dies 2026-08-26

Paste-ready snippet
// Wave4-Hotel7 (2026-08-20): Segment Analytics.js `Order Completed` event
// replacement. Segment (now Twilio Segment) is a CDP that fan-outs one
// analytics.track() call to 300+ destinations (Google Analytics, Amplitude,
// Braze, Iterable, Facebook Ads via CAPI destination, etc.), so this ONE
// snippet often carries five or six downstream analytics platforms with it.
// The legacy install pastes analytics.js into Shopify Additional Scripts
// and fires analytics.identify() + analytics.track('Order Completed', ...)
// on the order-status page. That entire code path stops executing 2026-08-26.
//
// Two variants: pick ONE.
//
// ============================================================
// VARIANT A -- BROWSER-SIDE (Shopify Web Pixels sandbox).
// Loads the Segment Analytics.js snippet inside the pixel sandbox and
// fires Order Completed matching the Segment E-commerce Spec V2 exactly
// (property names are case-sensitive downstream). SEGMENT_WRITE_KEY is a
// source-scoped Write Key; safe to embed in browser per Segment docs
// (it's the documented client-side auth pattern -- rate-limited on
// Segment's side, revoke + rotate if abused).
// ============================================================
(function loadSegment() {
  if (window.analytics && window.analytics.initialize) return;
  const a = window.analytics = window.analytics || [];
  a.methods = ['track', 'identify', 'page'];
  a.factory = (m) => (...args) => { args.unshift(m); a.push(args); return a; };
  a.methods.forEach((m) => { a[m] = a.factory(m); });
  a.load = function (key) {
    const s = document.createElement('script');
    s.async = true;
    s.src = 'https://cdn.segment.com/analytics.js/v1/' + key + '/analytics.min.js';
    document.head.appendChild(s);
  };
  a.load('SEGMENT_WRITE_KEY');
})();

analytics.subscribe('checkout_completed', (event) => {
  const { checkout } = event.data;
  if (!checkout || !checkout.email) return;

  window.analytics.identify(
    checkout.order ? String(checkout.order.customerId || checkout.order.id) : checkout.token,
    { email: checkout.email }
  );

  window.analytics.track('Order Completed', {
    order_id: checkout.order ? String(checkout.order.id) : checkout.token,
    checkout_id: checkout.token,
    total: Number(checkout.totalPrice.amount),
    subtotal: Number(checkout.subtotalPrice ? checkout.subtotalPrice.amount : checkout.totalPrice.amount),
    revenue: Number(checkout.totalPrice.amount),
    shipping: checkout.shippingLine ? Number(checkout.shippingLine.price.amount) : 0,
    tax: checkout.totalTax ? Number(checkout.totalTax.amount) : 0,
    currency: checkout.totalPrice.currencyCode,
    products: (checkout.lineItems || []).map((li) => ({
      product_id: li.variant && li.variant.product ? String(li.variant.product.id) : null,
      sku: li.variant ? li.variant.sku : null,
      name: li.title,
      price: li.variant && li.variant.price ? Number(li.variant.price.amount) : null,
      quantity: li.quantity,
    })),
  });
});

// ============================================================
// VARIANT B -- SERVER-SIDE (Segment HTTP Tracking API + Shopify webhook).
// Recommended. Bypasses ad-blockers, uses a Server Write Key that never
// touches the browser, and Segment's Cloud-mode destinations are the
// canonical path for 90%+ of Segment installs.
// Docs: https://segment.com/docs/connections/sources/catalog/libraries/server/http-api/
// ============================================================
//
// // Shopify webhook: orders/paid
// export async function handleShopifyOrderPaidForSegment(order) {
//   const auth = Buffer.from(process.env.SEGMENT_SERVER_WRITE_KEY + ':').toString('base64');
//   await fetch('https://api.segment.io/v1/track', {
//     method: 'POST',
//     headers: {
//       'Authorization': `Basic ${auth}`,
//       'Content-Type': 'application/json',
//     },
//     body: JSON.stringify({
//       userId: String(order.customer ? order.customer.id : order.id),
//       event: 'Order Completed',
//       messageId: 'shopify-order-' + order.id,  // dedupe key
//       timestamp: order.created_at,
//       properties: {
//         order_id: String(order.id),
//         total: Number(order.total_price),
//         revenue: Number(order.total_price),
//         subtotal: Number(order.subtotal_price),
//         shipping: order.shipping_lines.reduce((s, l) => s + Number(l.price), 0),
//         tax: Number(order.total_tax),
//         currency: order.currency,
//         products: order.line_items.map((li) => ({
//           product_id: String(li.product_id),
//           sku: li.sku,
//           name: li.title,
//           price: Number(li.price),
//           quantity: li.quantity,
//         })),
//       },
//     }),
//   });
// }

Legacy pattern detected via: analytics\.track\(\s*['"]Order Completed['"]|analytics\.track\(\s*['"]Completed Order['"]|analytics\.identify\(\s*['"]?.+['"]?\s*,

What this does NOT cover

What this does NOT cover: Segment's Product Viewed / Product Added / Checkout Started events (which fire pre-checkout and belong in theme.liquid or in checkout_started / product_viewed Web Pixels subscribers), and Group / Alias calls (which are lifecycle CRM signals unrelated to purchase). If you use Segment Personas / Twilio Engage for audience segmentation, those still work off this same event but audience recomputes may lag 1-24h.

Test-event verification checklist

  • Event name MUST be exactly `Order Completed` (case, spacing, singular) per Segment E-commerce Spec V2 -- downstream destinations (Amplitude, Mixpanel, GA4 via Segment) map on this exact string. The pre-2018 legacy name `Completed Order` still works but many downstream mappings have been retired. Verify in the Segment Debugger which name your destinations expect before shipping.
  • Verify the event lands in the Segment Debugger (Sources > <your source> > Debugger) within 30 seconds of a test purchase. If it appears with `channel: 'client'` but destinations show 0 deliveries, check Destinations > (each) > Event Tester -- the event may be dropping on a filter or missing a required property.
  • Duplicate-check: if you have Segment's Shopify Source connected (source type = shopify, not shopify-headless), Segment already receives orders/paid webhooks server-side and fires Order Completed. Adding Variant B on top duplicates every purchase. Choose Variant A OR the Segment Shopify Source OR Variant B -- never two of the three. Variant A is safe alongside the Shopify Source because messageId dedup only applies within one source; distinct sources = distinct funnels.
  • Verify live against the platform's own test-event tool: https://segment.com/docs/connections/sources/debugger/

Related paste-ready snippets

Product-analytics + CDP + CRM · HubSpot, Segment, Amplitude, Mixpanel, PostHog — every DTC brand ships at least one of these and all break the same way Aug 26.