What Enhanced Ecommerce Tracking Is

Enhanced ecommerce tracking in GA4 means implementing the full set of recommended ecommerce events - not just the purchase event.

When implemented correctly, GA4 gives you:

The data layer is the mechanism that passes this data from your website to GTM, and from GTM to GA4.


The Ecommerce Events GA4 Recommends

These are the standard ecommerce events with their recommended parameters:

EventWhen to Fire
view_item_listProduct category or search results page
select_itemUser clicks a product from a list
view_itemProduct detail page
add_to_cartUser adds a product to cart
remove_from_cartUser removes a product from cart
view_cartUser views the cart
begin_checkoutUser starts checkout
add_payment_infoUser enters payment details
add_shipping_infoUser enters shipping details
purchaseOrder is confirmed
refundOrder is refunded

You do not have to implement all of them at once. Start with view_item, add_to_cart, begin_checkout, and purchase - these cover the core funnel.


The Items Array

The most important concept in GA4 ecommerce tracking is the items array.

Almost every ecommerce event requires an items array - a structured list of products involved in the event. Each item object contains product details.

Item Object Structure

{
  item_id: "SKU-001",           // required  -  unique product identifier
  item_name: "Blue Running Shoe", // required  -  product name
  affiliation: "Online Store",
  coupon: "SAVE10",
  discount: 10.00,
  index: 0,                     // position in a list (for list events)
  item_brand: "Nike",
  item_category: "Footwear",
  item_category2: "Running",
  item_list_id: "search_results",
  item_list_name: "Search Results",
  item_variant: "Size 10",
  location_id: "warehouse_sydney",
  price: 89.99,                 // price per unit
  quantity: 1
}

Full Data Layer Examples

view_item (Product Detail Page)

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null }); // clear previous ecommerce data

window.dataLayer.push({
  event: "view_item",
  ecommerce: {
    currency: "USD",
    value: 89.99,
    items: [
      {
        item_id: "SKU-001",
        item_name: "Blue Running Shoe",
        item_brand: "Nike",
        item_category: "Footwear",
        item_variant: "Size 10",
        price: 89.99,
        quantity: 1
      }
    ]
  }
});

add_to_cart

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });

window.dataLayer.push({
  event: "add_to_cart",
  ecommerce: {
    currency: "USD",
    value: 89.99,
    items: [
      {
        item_id: "SKU-001",
        item_name: "Blue Running Shoe",
        item_brand: "Nike",
        item_category: "Footwear",
        item_variant: "Size 10",
        price: 89.99,
        quantity: 1
      }
    ]
  }
});

begin_checkout

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });

window.dataLayer.push({
  event: "begin_checkout",
  ecommerce: {
    currency: "USD",
    value: 179.98,
    coupon: "SAVE10",
    items: [
      {
        item_id: "SKU-001",
        item_name: "Blue Running Shoe",
        item_brand: "Nike",
        item_category: "Footwear",
        item_variant: "Size 10",
        price: 89.99,
        quantity: 2
      }
    ]
  }
});

purchase (Most Critical)

window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });

window.dataLayer.push({
  event: "purchase",
  ecommerce: {
    transaction_id: "ORD-20260314-001",  // unique order ID
    value: 161.98,                        // revenue after discounts, before tax/shipping
    tax: 14.40,
    shipping: 9.99,
    currency: "USD",
    coupon: "SAVE10",
    items: [
      {
        item_id: "SKU-001",
        item_name: "Blue Running Shoe",
        item_brand: "Nike",
        item_category: "Footwear",
        item_variant: "Size 10",
        price: 80.99,                     // price after coupon applied per unit
        quantity: 2
      }
    ]
  }
});

The Ecommerce Clear: Why It Matters

Every data layer push for an ecommerce event should be preceded by:

window.dataLayer.push({ ecommerce: null });

This clears any previous ecommerce object from the data layer before pushing a new one.

Without this, GTM may read a stale ecommerce object from a previous event - causing wrong product data to be sent on subsequent events.

Always clear before pushing. No exceptions.


GTM Setup for Ecommerce Events

Once the data layer is in place, configure GTM to send these events to GA4.

Create a GA4 Event Tag for Each Event

  1. GTM → Tags → New
  2. Tag type: Google Analytics: GA4 Event
  3. Configuration Tag: your Google Tag (base configuration)
  4. Event name: {{Event}} (this reads the event name dynamically from the data layer)
  5. Enable Send Ecommerce data → Source: Data Layer
  6. Trigger: Custom Event - Event Name matches regex: view_item|add_to_cart|begin_checkout|purchase

Using a single tag with a regex trigger is more efficient than creating separate tags for each event.

Create a Data Layer Variable

You may need Data Layer Variables to reference ecommerce parameters in other tags (e.g. for Google Ads dynamic remarketing):


Validating Ecommerce Data in GA4

Using GTM Preview Mode

  1. Trigger an ecommerce action on the site
  2. In Tag Assistant, confirm the event fires
  3. Check the Variables tab - confirm ecommerce.items, ecommerce.value, ecommerce.transaction_id are populated correctly

Using GA4 DebugView

  1. Enable GA4 Debug mode (add ?debug_mode=1 to your URL or use the Google Analytics Debugger Chrome extension)
  2. GA4 → Admin → DebugView
  3. Trigger ecommerce events - they appear in real time with all parameters

Checking the Ecommerce Report

After 24 - 48 hours:


Common Ecommerce Tracking Errors

Duplicate transactions: The purchase event fires more than once for the same order. Cause: the confirmation page is refreshable, or the tag fires on multiple triggers. Fix: deduplicate using transaction_id in the tag or use a session-scoped check.

Items array is empty or undefined: The data layer push is happening before the product data is available. Fix: push the data layer event after the page/component has fully loaded the product data.

Revenue discrepancy: GA4 revenue does not match actual revenue. Causes: wrong value calculation (including tax/shipping incorrectly), multiple purchase events firing, or refunds not tracked. Fix: audit the value formula and confirm what is being passed.

Missing item parameters: Item name or ID is blank. Cause: the product data is not structured correctly when building the items array. Fix: log window.dataLayer in the browser console after the event fires and inspect the items array.


Final Thoughts

Ecommerce tracking is the most technically demanding part of GA4 implementation - but it is also the most valuable.

When the data layer is correct, you get reliable revenue tracking, funnel analysis, product-level insights, and the ability to build precise audiences from product behaviour.

Get the items array right. Clear the ecommerce object before every push. Validate in DebugView before going live.

In the next article of this series, we will cover:

GA4 and Consent Mode v2 - how to keep tracking without killing data quality.

Related Posts

Data Layer Values Lost Between Pages - How to Persist Variables Across Navigation Without a Developer

9 min read

GTMData LayerTrackingVariablesGTM Advanced Series

GA4 and Consent Mode v2 - How to Keep Tracking Without Killing Data Quality

9 min read

GA4Consent ModeGDPRPrivacyTrackingGA4 Intro Series

GA4 Conversions vs Key Events - How to Set Them Up and What to Actually Track

8 min read

GA4ConversionsKey EventsGoogle AdsTrackingGA4 Intro Series
Adnan Agic

Adnan Agic

Google Ads Strategist & Technical Marketing Expert with 5+ years experience managing $10M+ in ad spend across 100+ accounts.

Need Help With Your Google Ads?

I help e-commerce brands scale profitably with data-driven PPC strategies.

Get In Touch
Back to Blog