Type something to search...
How to Set Up E-commerce Tracking in Google Analytics 4

How to Set Up E-commerce Tracking in Google Analytics 4

If you run an online store, pageviews alone won't tell you much about the health of your business. You need to know which products people view, which ones they add to their cart, where they abandon checkout, and which ones actually convert into revenue. That's exactly what GA4's e-commerce tracking is built for, but unlike Universal Analytics, it isn't something you get for free — you have to explicitly send the right events with the right parameters.

This guide covers the full e-commerce event set, how to implement it with gtag.js and Google Tag Manager, and how to verify it's actually working.

The GA4 E-commerce Event Set

GA4 recognizes a specific list of e-commerce events, each with an expected items array and event-specific parameters:

  • view_item_list — a list of products was shown (category or search results page)
  • select_item — a user clicked a product from a list
  • view_item — a product detail page was viewed
  • add_to_cart — a product was added to the cart
  • remove_from_cart — a product was removed from the cart
  • view_cart — the cart page was viewed
  • begin_checkout — checkout was started
  • add_shipping_info — shipping details were entered
  • add_payment_info — payment details were entered
  • purchase — an order was completed
  • refund — an order was refunded

You don't have to implement all of them on day one, but view_item, add_to_cart, and purchase are the minimum set that gives you a usable funnel.

Enabling E-commerce Data Collection

E-commerce reporting in GA4 is automatically available once you start sending e-commerce events — there's no separate toggle to flip like there was in Universal Analytics. The prerequisite is simply that your items arrays and event names match Google's schema exactly, since GA4 uses those to populate the standard e-commerce reports.

Implementing with gtag.js

Here's what a product detail page view looks like:

gtag("event", "view_item", {
  currency: "USD",
  value: 49.99,
  items: [
    {
      item_id: "SKU_12345",
      item_name: "Wireless Mouse",
      item_category: "Electronics",
      price: 49.99,
      quantity: 1,
    },
  ],
});

And an add-to-cart event, fired on the button's click handler:

function handleAddToCart(product) {
  gtag("event", "add_to_cart", {
    currency: "USD",
    value: product.price * product.quantity,
    items: [
      {
        item_id: product.sku,
        item_name: product.name,
        item_category: product.category,
        price: product.price,
        quantity: product.quantity,
      },
    ],
  });
}

The purchase event is the most important one, since it's what populates revenue reporting. It requires a transaction_id to prevent duplicate counting:

gtag("event", "purchase", {
  transaction_id: order.id,
  value: order.total,
  tax: order.tax,
  shipping: order.shipping,
  currency: "USD",
  items: order.lineItems.map((item) => ({
    item_id: item.sku,
    item_name: item.name,
    price: item.price,
    quantity: item.quantity,
  })),
});

Fire this once, on the order confirmation page, after the order has actually been created server-side — never on the checkout form submit, or you'll record purchases that fail.

Implementing with Google Tag Manager

If you're using GTM instead of hardcoded gtag calls, push e-commerce data to the dataLayer before your GA4 event tag fires:

window.dataLayer = window.dataLayer || [];

dataLayer.push({ ecommerce: null }); // clear the previous ecommerce object
dataLayer.push({
  event: "add_to_cart",
  ecommerce: {
    currency: "USD",
    value: 49.99,
    items: [
      {
        item_id: "SKU_12345",
        item_name: "Wireless Mouse",
        item_category: "Electronics",
        price: 49.99,
        quantity: 1,
      },
    ],
  },
});

Then in GTM:

  1. Create a Custom Event trigger that fires on the event name add_to_cart.
  2. Create a GA4 Event tag, set the event name to add_to_cart, and configure it to send the e-commerce data.
  3. Under Event Parameters, add items with the value {{DLV - ecommerce.items}} (a Data Layer Variable pointing at ecommerce.items).
  4. Repeat for each e-commerce event you plan to track.

Clearing the ecommerce object before each push (dataLayer.push({ ecommerce: null })) matters — without it, GTM can merge stale data from a previous event into the new one.

Verifying Your Implementation

Before trusting the data, verify it two ways:

  1. GTM Preview mode — confirm the right dataLayer events fire in the right order, with the expected items array attached.
  2. GA4 DebugView — go to Admin → DebugView in your GA4 property. With debug mode enabled (either via the GA4 DebugView Chrome extension or a debug_mode: true parameter), you can watch events arrive in real time and inspect every parameter GA4 actually received.

Once verified, check the Monetization reports under Reports in GA4 — specifically Ecommerce purchases — to confirm revenue and item data is populating correctly.

Handling Refunds

Refunds are easy to overlook until finance asks why GA4's revenue doesn't match your order management system. Fire a refund event when an order is fully or partially refunded:

gtag("event", "refund", {
  transaction_id: order.id,
  currency: "USD",
  value: refundAmount,
  items: refundedItems.map((item) => ({
    item_id: item.sku,
    item_name: item.name,
    price: item.price,
    quantity: item.quantity,
  })),
});

For a partial refund, only include the specific items and quantities being refunded, along with the partial value — not the full original order total. This keeps GA4's net revenue figure accurate rather than zeroing out an order that was only partly returned.

Server-Side Purchase Tracking

Client-side purchase events break whenever a customer closes the tab right after paying, before the confirmation page fully loads — which, for a high-value event like a purchase, is exactly the kind of data loss you can't afford. A more reliable pattern is to fire the purchase event server-side via the Measurement Protocol, triggered by your payment webhook rather than a page load:

curl -X POST "https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXX&api_secret=YOUR_API_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "'"$CLIENT_ID"'",
    "events": [{
      "name": "purchase",
      "params": {
        "transaction_id": "'"$ORDER_ID"'",
        "value": '"$ORDER_TOTAL"',
        "currency": "USD",
        "items": [{"item_id": "SKU_12345", "item_name": "Wireless Mouse", "price": 49.99, "quantity": 1}]
      }
    }]
  }'

You'll need the client_id GA4 assigned the browser session (read it from the _ga cookie, or capture it client-side and pass it to your backend at checkout) so the server-side event is correctly attributed to the same user who started the session.

Common Mistakes to Avoid

  • Missing transaction_id on the purchase event, which causes GA4 to treat every reload of the confirmation page as a new order.
  • Sending price as a string instead of a number — GA4 expects numeric values for price, value, and quantity.
  • Firing purchase on page load without checking whether the order was already recorded, leading to duplicate revenue on refresh.
  • Inconsistent item_id values between view_item and purchase for the same product, which breaks funnel and product-performance reports.

FAQ about How to Set Up E-commerce Tracking in Google Analytics 4

faq

Do I need a separate e-commerce toggle in GA4 settings?

No. Unlike Universal Analytics, GA4 doesn't have a manual e-commerce on/off switch — reports populate automatically once you send correctly formatted e-commerce events.

What happens if I only implement the purchase event?

You'll get revenue reporting, but you'll miss the rest of the funnel — product views, add-to-carts, and checkout starts — which is what lets you diagnose where customers drop off before buying.

Can I track e-commerce on a site without a custom checkout, like Shopify?

Yes — most e-commerce platforms (Shopify, WooCommerce, BigCommerce) have official or well-supported GA4 integrations that handle this event set for you, though it's worth verifying the events in DebugView regardless.

Why don't my purchases show up in the Monetization report?

The most common causes are a missing or malformed items array, a missing transaction_id, or the event firing before the GA4 configuration tag has loaded.

How do I avoid double-counting purchases on page refresh?

Store a flag (in sessionStorage or a URL parameter) once the purchase event fires for a given transaction_id, and check it before firing again.

Can I track e-commerce events in a mobile app?

Yes, using the same event names and parameters through the Firebase SDK for GA4, which shares the same underlying event schema as the web implementation.

Conclusion

E-commerce tracking is where Google Analytics stops being a traffic dashboard and starts being a revenue tool. Implement the core event set, verify every event in DebugView before trusting the numbers, and keep your item_id values consistent across the funnel. Once it's wired up correctly, GA4's Monetization reports become one of the most useful dashboards on your entire website.

Tags :
Share :

Related Posts

A Beginner's Guide to the GA4 Interface

A Beginner's Guide to the GA4 Interface

If you opened Google Analytics 4 for the first time and felt a little lost, you're not alone. GA4 looks nothing like the old Universal Analytics inte

Continue Reading
A Deep Dive into the Next Generation of Google Analytics

A Deep Dive into the Next Generation of Google Analytics

Google Analytics has long been a staple tool for countless businesses, enabling them to track, measure, and analyze data to gain insightful feedback

Continue Reading
A Practical Guide to Custom Events in Google Analytics 4

A Practical Guide to Custom Events in Google Analytics 4

GA4's automatic and Enhanced Measurement events cover a lot of ground, but sooner or later almost every site needs to track something specific to its

Continue Reading