Skip to main content
Back to Blog
analytics

E-Commerce Tracking Setup: Revenue, Products & Enhanced Conversions in GA4

RedClaw Performance Team
3/9/2026
13 min read

E-Commerce Tracking Setup: Revenue, Products & Enhanced Conversions in GA4

Revenue tracking is the most critical analytics implementation for any e-commerce business. If your GA4 purchase events are misconfigured -- wrong currency, missing transaction IDs, incorrect product data -- every report, every optimization decision, and every ROAS calculation is wrong. And unlike a missing page view, a broken purchase event directly misrepresents your business performance.

This guide provides a complete, production-tested e-commerce tracking implementation for GA4 using Google Tag Manager. It covers every event in the e-commerce funnel, from product list views to purchase confirmation, with exact data layer schemas, GTM tag configurations, and validation procedures.

Why This Matters: GA4 e-commerce tracking feeds directly into Google Ads Smart Bidding optimization. When your purchase events send accurate revenue data, Google's algorithms optimize for actual ROAS. When your data is incomplete or inaccurate, Smart Bidding optimizes toward the wrong targets, wasting budget on unprofitable conversions.


Table of Contents

  1. E-Commerce Event Hierarchy
  2. Data Layer Schema
  3. Product List and Item Views
  4. Cart and Checkout Events
  5. Purchase Event Implementation
  6. Enhanced Conversions Setup
  7. GTM Tag Configuration
  8. Revenue Validation
  9. Common Mistakes
  10. FAQ

E-Commerce Event Hierarchy

GA4 defines a specific set of recommended e-commerce events. Implementing all of them enables the full monetization reporting suite and provides the data needed for Smart Bidding and audience building.

The Complete E-Commerce Event Flow

Product Discovery:
  view_item_list → select_item → view_item

Cart & Checkout:
  add_to_cart → remove_from_cart → view_cart →
  begin_checkout → add_shipping_info → add_payment_info

Conversion:
  purchase

Post-Purchase:
  refund

Event Priority

Not all events are equally important. Prioritize implementation in this order:

PriorityEventWhy
P0 (Critical)purchaseRevenue tracking, ROAS, Smart Bidding
P0 (Critical)begin_checkoutFunnel analysis, checkout abandonment
P1 (High)add_to_cartCart abandonment, retargeting audiences
P1 (High)view_itemProduct interest signals, retargeting
P2 (Medium)view_item_listCategory page engagement
P2 (Medium)select_itemProduct click-through rates
P2 (Medium)add_shipping_infoCheckout step analysis
P2 (Medium)add_payment_infoPayment method analysis
P3 (Low)remove_from_cartCart edit behavior
P3 (Low)refundReturns tracking

Data Layer Schema

The Items Array

Every e-commerce event uses a standardized items array. Consistency across all events is critical -- the same product must have the same item_id and item_name everywhere.

// Standard item object used across all e-commerce events
const itemSchema = {
  item_id: 'SKU_12345',              // Required: Your product ID/SKU
  item_name: 'Tracking Audit Kit',    // Required: Product name
  affiliation: 'RedClaw Store',       // Optional: Store or affiliate name
  coupon: 'SPRING20',                 // Optional: Coupon applied
  discount: 10.00,                    // Optional: Discount amount
  index: 0,                           // Optional: Position in list
  item_brand: 'RedClaw',              // Optional: Brand name
  item_category: 'Templates',         // Optional: Primary category
  item_category2: 'Analytics',        // Optional: Sub-category
  item_category3: 'GA4',              // Optional: Sub-sub-category
  item_list_id: 'featured_products',  // Optional: List identifier
  item_list_name: 'Featured Products',// Optional: List name
  item_variant: 'Premium',            // Optional: Variant
  location_id: 'section_hero',        // Optional: Physical/page location
  price: 49.99,                       // Required for revenue: Unit price
  quantity: 1                          // Required for revenue: Quantity
};

Data Type Requirements

FieldTypeCommon MistakeCorrect Format
priceNumber"49.99" (string)49.99 (number)
quantityInteger"1" (string)1 (integer)
valueNumberMissing entirely49.99 (sum of items)
currencyStringMissing entirely"USD" (ISO 4217)
transaction_idStringMissing or duplicate"TXN_20260309_001"
discountNumberNegative number10.00 (positive)
indexIntegerString or missing0 (zero-based)

Product List and Item Views

view_item_list Event

Fires when a user sees a list of products (category page, search results, featured products section).

// Clear previous ecommerce data
window.dataLayer.push({ ecommerce: null });

// Push view_item_list event
window.dataLayer.push({
  event: 'view_item_list',
  ecommerce: {
    item_list_id: 'category_templates',
    item_list_name: 'Templates Category Page',
    items: [
      {
        item_id: 'SKU_001',
        item_name: 'Tracking Audit Kit',
        item_brand: 'RedClaw',
        item_category: 'Templates',
        item_category2: 'Analytics',
        item_list_id: 'category_templates',
        item_list_name: 'Templates Category Page',
        index: 0,
        price: 49.99
      },
      {
        item_id: 'SKU_002',
        item_name: 'UTM Builder Spreadsheet',
        item_brand: 'RedClaw',
        item_category: 'Templates',
        item_category2: 'Campaign Management',
        item_list_id: 'category_templates',
        item_list_name: 'Templates Category Page',
        index: 1,
        price: 29.99
      }
      // ... more items
    ]
  }
});

view_item Event

Fires when a user views a product detail page.

window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: 'view_item',
  ecommerce: {
    currency: 'USD',
    value: 49.99,
    items: [{
      item_id: 'SKU_001',
      item_name: 'Tracking Audit Kit',
      item_brand: 'RedClaw',
      item_category: 'Templates',
      item_category2: 'Analytics',
      item_variant: 'Premium',
      price: 49.99,
      quantity: 1
    }]
  }
});

select_item Event

Fires when a user clicks on a product from a list.

window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: 'select_item',
  ecommerce: {
    item_list_id: 'category_templates',
    item_list_name: 'Templates Category Page',
    items: [{
      item_id: 'SKU_001',
      item_name: 'Tracking Audit Kit',
      item_brand: 'RedClaw',
      item_category: 'Templates',
      index: 0,
      price: 49.99
    }]
  }
});

Cart and Checkout Events

add_to_cart Event

window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: 'add_to_cart',
  ecommerce: {
    currency: 'USD',
    value: 49.99,           // Total value of items added
    items: [{
      item_id: 'SKU_001',
      item_name: 'Tracking Audit Kit',
      item_brand: 'RedClaw',
      item_category: 'Templates',
      item_variant: 'Premium',
      price: 49.99,
      quantity: 1
    }]
  }
});

begin_checkout Event

window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: 'begin_checkout',
  ecommerce: {
    currency: 'USD',
    value: 79.98,           // Total cart value
    coupon: 'SPRING20',     // Cart-level coupon (if applied)
    items: [
      {
        item_id: 'SKU_001',
        item_name: 'Tracking Audit Kit',
        price: 49.99,
        quantity: 1,
        coupon: 'SPRING20',
        discount: 10.00
      },
      {
        item_id: 'SKU_002',
        item_name: 'UTM Builder Spreadsheet',
        price: 29.99,
        quantity: 1
      }
    ]
  }
});

add_shipping_info and add_payment_info

// Shipping step
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: 'add_shipping_info',
  ecommerce: {
    currency: 'USD',
    value: 79.98,
    shipping_tier: 'express',  // Shipping method selected
    items: [/* same items array */]
  }
});

// Payment step
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
  event: 'add_payment_info',
  ecommerce: {
    currency: 'USD',
    value: 79.98,
    payment_type: 'credit_card',  // Payment method selected
    items: [/* same items array */]
  }
});

Purchase Event Implementation

The purchase event is the most important e-commerce event. Every field must be correct because revenue data flows directly into GA4 reports and Google Ads optimization.

Complete Purchase Event

// CRITICAL: Clear previous ecommerce data
window.dataLayer.push({ ecommerce: null });

// Push the purchase event
window.dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'TXN_20260309_001',  // REQUIRED: Unique order ID
    value: 85.97,                         // REQUIRED: Total revenue
    tax: 6.00,                            // Tax amount
    shipping: 5.99,                       // Shipping cost
    currency: 'USD',                      // REQUIRED: ISO 4217 currency
    coupon: 'SPRING20',                   // Order-level coupon
    items: [
      {
        item_id: 'SKU_001',
        item_name: 'Tracking Audit Kit',
        affiliation: 'RedClaw Store',
        coupon: 'SPRING20',
        discount: 10.00,
        item_brand: 'RedClaw',
        item_category: 'Templates',
        item_category2: 'Analytics',
        item_variant: 'Premium',
        price: 49.99,
        quantity: 1
      },
      {
        item_id: 'SKU_002',
        item_name: 'UTM Builder Spreadsheet',
        affiliation: 'RedClaw Store',
        item_brand: 'RedClaw',
        item_category: 'Templates',
        item_category2: 'Campaign Management',
        price: 29.99,
        quantity: 1
      }
    ]
  }
});

Revenue Calculation Rules

value = Sum of (price × quantity) for all items
      - Sum of all discounts
      + tax
      + shipping

Example:
  Item 1: $49.99 × 1 = $49.99
  Item 2: $29.99 × 1 = $29.99
  Subtotal: $79.98
  Discount: -$10.00
  Tax: +$6.00
  Shipping: +$5.99
  Total (value): $81.97

NOTE: GA4 uses the `value` field for revenue reporting.
      Items' price × quantity is used for item-level analysis.
      These should be mathematically consistent.

Preventing Duplicate Purchases

Duplicate purchase events are the most common e-commerce tracking error:

// Server-side: Generate the transaction_id once and embed in the page
// The confirmation page template should include this only ONCE

// Method 1: Check if purchase already fired this session
(function() {
  const txnId = '{{SERVER_TRANSACTION_ID}}';
  const firedKey = 'purchase_fired_' + txnId;

  if (sessionStorage.getItem(firedKey)) {
    console.warn('Purchase event already fired for:', txnId);
    return; // Do not fire again
  }

  window.dataLayer.push({ ecommerce: null });
  window.dataLayer.push({
    event: 'purchase',
    ecommerce: {
      transaction_id: txnId,
      value: 85.97,
      currency: 'USD',
      items: [/* ... */]
    }
  });

  sessionStorage.setItem(firedKey, 'true');
})();

For understanding how purchase data flows into conversion tracking, see our Conversion Tracking Complete Guide.


Enhanced Conversions Setup

Enhanced Conversions send hashed first-party customer data (email, phone, address) alongside conversion events, improving conversion measurement accuracy by 5-15%.

Enhanced Conversions for Google Ads

// Method 1: Via GTM (recommended)
// In your Google Ads Conversion tag, enable Enhanced Conversions
// Map user data from data layer variables

// Push user data to data layer at checkout
window.dataLayer.push({
  event: 'purchase',
  user_data: {
    email: 'customer@example.com',    // GTM auto-hashes
    phone_number: '+11234567890',
    address: {
      first_name: 'John',
      last_name: 'Doe',
      street: '123 Main St',
      city: 'New York',
      region: 'NY',
      postal_code: '10001',
      country: 'US'
    }
  },
  ecommerce: {
    transaction_id: 'TXN_001',
    value: 85.97,
    currency: 'USD',
    items: [/* ... */]
  }
});

// Method 2: Via gtag.js (alternative)
gtag('set', 'user_data', {
  email: 'customer@example.com',
  phone_number: '+11234567890',
  address: {
    first_name: 'John',
    last_name: 'Doe',
    street: '123 Main St',
    city: 'New York',
    region: 'NY',
    postal_code: '10001',
    country: 'US'
  }
});

Enhanced Conversions for GA4

GA4 uses User-Provided Data collection for similar functionality:

// Send user data with GA4 config
gtag('config', 'G-XXXXXXXXXX', {
  user_id: 'hashed_user_id',
  user_properties: {
    customer_tier: 'premium',
    lifetime_orders: 5
  }
});

For complete server-side tracking to complement enhanced conversions, see our Pixel + CAPI Dual Tracking Setup guide.


GTM Tag Configuration

GA4 E-Commerce Tag Setup

In GTM, you need one GA4 Event tag for each e-commerce event:

Tag: GA4 - Purchase Event
├── Type: [Google Analytics](https://developers.google.com/analytics): GA4 Event
├── Configuration Tag: GA4 Configuration
├── Event Name: purchase
├── E-commerce: Send Ecommerce data ✓
│   └── Data source: Data Layer
├── Trigger: Custom Event = purchase
└── Advanced:
    ├── Tag firing priority: 100
    └── Consent: analytics_storage required

Data Layer Variable Setup

Create these GTM variables to extract e-commerce data:

Variable: DL - Transaction ID
├── Type: Data Layer Variable
├── Name: ecommerce.transaction_id
└── Version: 2

Variable: DL - Revenue
├── Type: Data Layer Variable
├── Name: ecommerce.value
└── Version: 2

Variable: DL - Currency
├── Type: Data Layer Variable
├── Name: ecommerce.currency
└── Version: 2

Variable: DL - Items
├── Type: Data Layer Variable
├── Name: ecommerce.items
└── Version: 2

Revenue Validation

GA4 DebugView Validation

  1. Enable the GA4 Debugger Chrome extension
  2. Navigate through a purchase flow on your site
  3. In GA4 Admin > DebugView, verify:
    • purchase event appears
    • value parameter shows correct number
    • currency parameter is set
    • transaction_id is unique
    • items array contains all products

Automated Revenue Validation Script

// Validate e-commerce data layer pushes
(function() {
  const original = window.dataLayer.push;
  window.dataLayer.push = function(obj) {
    if (obj && obj.event === 'purchase' && obj.ecommerce) {
      const e = obj.ecommerce;
      const errors = [];

      // Required fields
      if (!e.transaction_id) errors.push('Missing transaction_id');
      if (typeof e.value !== 'number') errors.push('value must be a number');
      if (!e.currency) errors.push('Missing currency');
      if (!e.items || !e.items.length) errors.push('Missing items array');

      // Validate items
      if (e.items) {
        let calculatedValue = 0;
        e.items.forEach((item, i) => {
          if (!item.item_id) errors.push(`Item ${i}: missing item_id`);
          if (!item.item_name) errors.push(`Item ${i}: missing item_name`);
          if (typeof item.price !== 'number') errors.push(`Item ${i}: price must be number`);
          if (typeof item.quantity !== 'number') errors.push(`Item ${i}: quantity must be number`);
          calculatedValue += (item.price || 0) * (item.quantity || 1);
        });

        // Check value consistency (allowing for tax/shipping/discounts)
        if (Math.abs(calculatedValue - e.value) > calculatedValue * 0.5) {
          errors.push(`Value mismatch: items sum to ${calculatedValue}, but value is ${e.value}`);
        }
      }

      // Duplicate check
      const txnKey = 'validated_txn_' + e.transaction_id;
      if (sessionStorage.getItem(txnKey)) {
        errors.push(`DUPLICATE: transaction_id ${e.transaction_id} already fired`);
      }
      sessionStorage.setItem(txnKey, 'true');

      if (errors.length > 0) {
        console.error('E-Commerce Validation Errors:', errors);
      } else {
        console.log('E-Commerce Purchase Valid:', e.transaction_id, '$' + e.value);
      }
    }
    return original.apply(this, arguments);
  };
})();

For connecting e-commerce tracking to your broader analytics setup, see our GA4 Setup Complete Guide.


Common Mistakes

Top 10 E-Commerce Tracking Mistakes

  1. Price as string: "49.99" instead of 49.99. GA4 ignores string values for revenue.
  2. Missing currency: Without currency, GA4 cannot calculate revenue correctly.
  3. No transaction_id: Every page refresh fires another purchase event (duplicate revenue).
  4. Inconsistent item_id: Same product has different IDs in different events (breaks product reports).
  5. Not clearing ecommerce object: Previous event data bleeds into the next event.
  6. Tax/shipping in value: Including tax and shipping in value but also in items price (double-counting).
  7. Missing items array: Purchase event without items means no product-level analysis.
  8. Wrong event names: Using Purchase instead of purchase (case-sensitive in GA4).
  9. GTM preview not tested: Publishing without verifying in Preview mode.
  10. No server-side backup: Relying only on browser-side purchase tracking (ad blockers).

For understanding how UTM tracking integrates with e-commerce measurement, see our UTM Parameters Usage Guide.


Is your e-commerce tracking accurate? Revenue data drives every optimization decision. A single misconfigured purchase event can corrupt months of analytics. Get a free tracking audit


FAQ

What is the difference between e-commerce value and item prices?

The value field at the event level represents the total transaction amount that your business actually received. Individual item price fields represent per-unit prices. The value should equal the sum of (price times quantity) for all items, adjusted for discounts, tax, and shipping. GA4 uses value for revenue reports and price for product-level analysis. Both must be accurate, and they must be mathematically consistent.

Should I track revenue inclusive or exclusive of tax?

Choose one approach and be consistent. Most businesses track revenue exclusive of tax (net revenue) because tax varies by location and does not represent actual business revenue. If you track inclusive of tax, your ROAS calculations will be inflated. Document your approach and ensure it matches how you report revenue in other systems (accounting, ERP). The key is consistency across GA4, Google Ads, and your backend.

How do I handle subscription or recurring revenue in GA4?

Track each subscription payment as a separate purchase event with a unique transaction_id (e.g., sub_userid_202603). Use item parameters to distinguish subscription types: item_category: 'Subscription', item_variant: 'Monthly'. For LTV analysis, use a custom user property (lifetime_value) that you update on each payment. Consider also tracking subscribe as a separate custom event for funnel analysis.

Why is my GA4 revenue different from my payment processor?

Common causes: duplicate purchase events (missing transaction_id deduplication), wrong currency (GA4 defaults to your property's currency), price format errors (strings instead of numbers), refunds not tracked, test orders included, and timing differences (GA4 reports at event time, processors report at settlement time). Start by comparing a single day's transactions line by line to identify the specific discrepancy source.

Do I need enhanced conversions if I already have e-commerce tracking?

Yes. E-commerce tracking and Enhanced Conversions serve different purposes. E-commerce tracking sends product and revenue data for reporting and analysis. Enhanced Conversions sends hashed customer data (email, phone, address) to improve conversion measurement accuracy, especially for users with limited cookie tracking (Safari, ad blockers, iOS). Enhanced Conversions typically recover 5-15% additional conversion data that e-commerce tracking alone cannot capture.


Revenue tracking is too important to get wrong. Our team validates every purchase event, every item parameter, and every revenue calculation to ensure your GA4 data matches reality. Check your ROAS


Related reading: GA4 Setup Complete Guide | Conversion Tracking Complete Guide | Pixel + CAPI Dual Tracking Setup | UTM Parameters Usage Guide | Ad Data Analysis for Beginners


Explore our tracking & analytics services →

Share:

Maximize Your Ad Budget ROI

From account setup to full-funnel tracking, we handle it all.

  • Dedicated account manager with real-time optimization
  • Full tracking infrastructure — every dollar accounted for
  • Cross-platform expertise: Meta, Google, TikTok

📬 Subscribe to Our Newsletter

Weekly insights on ad strategies, industry trends, and practical tips. No fluff.

We never share your email. Unsubscribe anytime.