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

GA4 gtag('event', 'purchase') in checkout.liquid

Google Analytics 4 · Web Pixels API replacement · confidence: high

Dies 2026-08-26

Paste-ready snippet
analytics.subscribe('checkout_completed', (event) => {
  const { checkout } = event.data;
  if (!checkout || !checkout.totalPrice) return;

  const items = checkout.lineItems.map((item) => ({
    item_id: item.variant && item.variant.sku ? item.variant.sku : (item.variant && item.variant.id),
    item_name: item.title,
    price: item.variant ? item.variant.price.amount : undefined,
    quantity: item.quantity,
  }));

  // gtag() does not exist in the Web Pixels sandbox (no window global).
  // Forward the event to GA4's Measurement Protocol instead — this is the
  // sandbox-correct equivalent of a browser gtag('event','purchase') call.
  // Replace MEASUREMENT_ID and API_SECRET (GA4 Admin > Data Streams >
  // Measurement Protocol API secrets).
  fetch(`https://www.google-analytics.com/mp/collect?measurement_id=MEASUREMENT_ID&api_secret=API_SECRET`, {
    method: 'POST',
    keepalive: true,
    body: JSON.stringify({
      client_id: event.clientId,
      events: [{
        name: 'purchase',
        params: {
          transaction_id: checkout.order ? checkout.order.id : checkout.token,
          value: checkout.totalPrice.amount,
          currency: checkout.totalPrice.currencyCode,
          tax: checkout.totalTax ? checkout.totalTax.amount : undefined,
          shipping: checkout.shippingLine ? checkout.shippingLine.price.amount : undefined,
          items,
        },
      }],
    }),
  });
});

Legacy pattern detected via: gtag\(\s*['"]event['"]\s*,\s*['"]purchase['"]

What this does NOT cover

What this does NOT cover: GA4 events earlier in the funnel — page_view, add_to_cart, begin_checkout — which fired off the same legacy gtag script and need their own analytics.subscribe() replacements, not this purchase-only snippet. It also does not preserve any custom dimensions/parameters the merchant had bolted onto the original gtag('event','purchase', ...) call beyond the standard ecommerce fields.

Test-event verification checklist

  • client_id uses event.clientId (Shopify-provided, stable per visitor) so GA4 can stitch this server-sent Measurement Protocol event to the same session as prior page_viewed events.
  • transaction_id prefers checkout.order.id (only non-null on checkout_completed); falls back to checkout.token if the order relationship is unavailable.
  • items[].item_id uses variant SKU when present, else variant.id — matches GA4 Enhanced Ecommerce item-identification convention. Fires exactly once per order — verify in GA4 DebugView that no duplicate purchase event appears from a leftover checkout.liquid gtag call still running.
  • Verify live against the platform's own test-event tool: https://developers.google.com/analytics/devguides/collection/protocol/ga4/validating-events

Related paste-ready snippets

Google Analytics / Ads / GTM family · GA4, Google Ads conversion, GTM dataLayer, and the legacy Universal Analytics enhanced-ecommerce path.