E-Commerce Tracking Setup: Revenue, Products & Enhanced Conversions in GA4
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
- E-Commerce Event Hierarchy
- Data Layer Schema
- Product List and Item Views
- Cart and Checkout Events
- Purchase Event Implementation
- Enhanced Conversions Setup
- GTM Tag Configuration
- Revenue Validation
- Common Mistakes
- 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:
| Priority | Event | Why |
|---|---|---|
| P0 (Critical) | purchase | Revenue tracking, ROAS, Smart Bidding |
| P0 (Critical) | begin_checkout | Funnel analysis, checkout abandonment |
| P1 (High) | add_to_cart | Cart abandonment, retargeting audiences |
| P1 (High) | view_item | Product interest signals, retargeting |
| P2 (Medium) | view_item_list | Category page engagement |
| P2 (Medium) | select_item | Product click-through rates |
| P2 (Medium) | add_shipping_info | Checkout step analysis |
| P2 (Medium) | add_payment_info | Payment method analysis |
| P3 (Low) | remove_from_cart | Cart edit behavior |
| P3 (Low) | refund | Returns 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
| Field | Type | Common Mistake | Correct Format |
|---|---|---|---|
price | Number | "49.99" (string) | 49.99 (number) |
quantity | Integer | "1" (string) | 1 (integer) |
value | Number | Missing entirely | 49.99 (sum of items) |
currency | String | Missing entirely | "USD" (ISO 4217) |
transaction_id | String | Missing or duplicate | "TXN_20260309_001" |
discount | Number | Negative number | 10.00 (positive) |
index | Integer | String or missing | 0 (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
- Enable the GA4 Debugger Chrome extension
- Navigate through a purchase flow on your site
- In GA4 Admin > DebugView, verify:
purchaseevent appearsvalueparameter shows correct numbercurrencyparameter is settransaction_idis uniqueitemsarray 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
- Price as string:
"49.99"instead of49.99. GA4 ignores string values for revenue. - Missing currency: Without currency, GA4 cannot calculate revenue correctly.
- No transaction_id: Every page refresh fires another purchase event (duplicate revenue).
- Inconsistent item_id: Same product has different IDs in different events (breaks product reports).
- Not clearing ecommerce object: Previous event data bleeds into the next event.
- Tax/shipping in value: Including tax and shipping in
valuebut also initemsprice (double-counting). - Missing items array: Purchase event without items means no product-level analysis.
- Wrong event names: Using
Purchaseinstead ofpurchase(case-sensitive in GA4). - GTM preview not tested: Publishing without verifying in Preview mode.
- 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
Related Posts
Ad Data Analysis for Beginners 2026 | Essential Guide to Data Interpretation
Learn ad data analysis from scratch. Master core metrics like CTR, CPC, ROAS, and conversion tracking. Understand what the data means and make smarter advertising decisions with our comprehensive beginner's guide.
Reporting Automation Guide 2026 | Essential Efficiency Tips for Digital Marketers
Learn reporting automation to save 80% of data processing time. This guide covers Meta Ads, Google Analytics automation tools, and practical tutorials to build efficient data dashboards.
UTM Parameters Guide 2026: Track Every Campaign Click
Master UTM parameters for accurate campaign tracking. Naming conventions, GA4 attribution, URL builder tips, and common mistakes to avoid.