16 min read · CRO · Last updated July 2026
Quick answer: GA4 ecommerce tracking requires pushing a structured data layer event to GTM before firing the GA4 purchase tag. The most common implementation error is missing the
itemsarray or sendingvalueas a string instead of a number — both cause revenue data to appear as zero in GA4 reports despite events firing correctly.
Introduction
Revenue data is the most critical metric in any ecommerce analytics setup. A GA4 ecommerce implementation that fires events but captures zero revenue, misses items, or fails the checkout funnel completely is arguably worse than no ecommerce tracking at all — because it creates the illusion of data while producing decisions based on broken numbers.
This guide covers the complete GA4 ecommerce event model: every event, every required parameter, the exact data layer structure for GTM implementation, platform-specific notes for Shopify and WooCommerce, and the verification process in DebugView.
What you’ll learn:
– The complete GA4 ecommerce event hierarchy and when each event fires
– Exact parameter requirements for the purchase event (including items array)
– Data layer push implementation with copy-pasteable code
– How to verify ecommerce tracking with DebugView and Realtime reports
Table of Contents
- The GA4 Ecommerce Event Model
- Required Parameters for Each Event
- The Purchase Event Deep Dive
- The Items Array: Structure and Requirements
- Implementing via Google Tag Manager Data Layer
- Shopify GA4 Integration Options
- WooCommerce GA4 Implementation
- GA4 Ecommerce Reports
- Refund Events
- Revenue Attribution in GA4
- Ecommerce Event Implementation Checklist
- GA4 Purchase Event Parameter Builder
- FAQ
- Conclusion
1. The GA4 Ecommerce Event Model
GA4’s ecommerce tracking follows a sequential funnel model. Each event maps to a stage in the purchase journey:
| Event | When It Fires | Funnel Stage |
|---|---|---|
view_item_list |
User sees a product list/category page | Discovery |
select_item |
User clicks a product from a list | Discovery → Product |
view_item |
User views a product detail page | Consideration |
add_to_cart |
User adds item to cart | Intent |
remove_from_cart |
User removes item from cart | Intent (negative) |
view_cart |
User views cart page | Intent → Purchase |
begin_checkout |
User initiates checkout | Purchase |
add_shipping_info |
User enters/selects shipping method | Purchase |
add_payment_info |
User enters payment details | Purchase |
purchase |
Transaction confirmed | Conversion |
refund |
Order refunded (full or partial) | Post-purchase |
Which events to implement first:
Not all events are equal priority. Start with the events that most directly impact business decisions:
purchase— Non-negotiable. Revenue data is your primary KPI.add_to_cart— Identifies intent. Cart abandonment rate = 1 – (purchases/add_to_carts).begin_checkout— Checkpoint abandonment analysis.view_item— Product performance analysis.view_item_list— Category and search performance.
Implement in this priority order. Running without purchase tracking is a business analytics failure. Running without add_to_cart means you’re blind to cart abandonment rates.
2. Required Parameters for Each Event
GA4 ecommerce events use two types of parameters:
Event-level parameters: Apply to the entire event (total cart value, currency, coupon applied)
Item-level parameters: Apply to each product in the transaction (within the items array)
Minimum viable parameters by event:
view_item: { currency, value, items: [{ item_id, item_name, price }] }
add_to_cart: { currency, value, items: [{ item_id, item_name, price, quantity }] }
begin_checkout: { currency, value, items: [...] }
purchase: { transaction_id, value, currency, items: [...] }
Critical type rules:
– value and price must be numbers, not strings. value: 49.99 is correct. value: "49.99" causes revenue to appear as zero.
– currency must be a 3-letter ISO 4217 code: “USD”, “AUD”, “EUR”, “NPR”. Not “dollars”, not “$”.
– transaction_id must be a unique string for each order. Use your order ID from your platform. GA4 uses this for deduplication — the same transaction_id will only be counted once, so sending your order confirmation page event multiple times (page refreshes) won’t double-count revenue.
– quantity must be a number: 1, 2, 3. Not "1".
3. The Purchase Event Deep Dive
The purchase event is the most important event in ecommerce GA4. Here is the complete event structure with all parameters:
gtag("event", "purchase", {
transaction_id: "ORDER-12345", // Required: unique order ID
value: 149.97, // Required: total revenue (number)
tax: 12.50, // Recommended: tax amount (number)
shipping: 9.99, // Recommended: shipping cost (number)
currency: "USD", // Required: ISO 4217 code
coupon: "SUMMER20", // Optional: discount code applied
items: [
{
item_id: "SKU-001", // Required: product ID/SKU
item_name: "Running Shoes Pro",// Required: product name
item_brand: "Nike", // Recommended
item_category: "Footwear", // Recommended
item_category2: "Running", // Optional: sub-category
item_variant: "Blue / Size 10",// Optional: variant
price: 99.99, // Required: unit price (number)
quantity: 1, // Required: quantity (number)
discount: 20.00, // Optional: discount per item
coupon: "MEMBER10" // Optional: item-level coupon
},
{
item_id: "SKU-002",
item_name: "Running Socks Pack",
item_brand: "Nike",
item_category: "Accessories",
price: 24.99,
quantity: 2
}
]
});
How value is calculated:
value should equal the actual revenue received — after discounts, before tax and shipping (unless your business model counts tax/shipping as revenue). Most implementations set value to the order subtotal. Tax and shipping are reported separately in their own parameters so GA4 can accurately calculate net revenue.
The deduplication guarantee:
GA4 will only count a purchase event with a given transaction_id once per property. If the order confirmation page is visited twice (user refreshes, email confirmation link), the second event is silently ignored. This means your GA4 revenue data should be duplicate-free without additional deduplication logic — as long as your transaction_id is genuinely unique per order.
4. The Items Array: Structure and Requirements
The items array is an array of objects, one per product in the transaction. Multi-item orders pass all products in a single items array on the purchase event.
Required item parameters:
– item_id OR item_name (at least one required; both recommended)
– price (number, unit price)
– quantity (number, for add_to_cart and purchase)
Highly recommended item parameters:
– item_brand — enables Brand analysis in GA4 Ecommerce reports
– item_category — enables Category performance reports
– item_variant — essential for businesses with size/color variants
Items array for a single product purchase:
items: [{ item_id: "SKU-123", item_name: "Blue Widget", price: 49.99, quantity: 1 }]
Items array for cart with multiple products:
items: [
{ item_id: "SKU-001", item_name: "Product A", price: 30.00, quantity: 2 },
{ item_id: "SKU-002", item_name: "Product B", price: 45.00, quantity: 1 }
]
Category hierarchy: GA4 supports up to 5 category levels via item_category, item_category2, item_category3, item_category4, item_category5. Use these for detailed product taxonomy reports.
5. Implementing via Google Tag Manager Data Layer
The standard pattern for GTM-based GA4 ecommerce implementation uses the data layer push method. Your ecommerce platform pushes structured data to window.dataLayer, and GTM reads that data to fire the GA4 event.
Step 1: Push to the data layer from your platform code
On your order confirmation page (triggered after successful payment):
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null }); // Clear previous ecommerce data
window.dataLayer.push({
event: "purchase",
ecommerce: {
transaction_id: "{{ ORDER_ID }}",
value: {{ ORDER_SUBTOTAL }},
tax: {{ ORDER_TAX }},
shipping: {{ SHIPPING_COST }},
currency: "{{ CURRENCY_CODE }}",
items: [
{% for item in order.items %}
{
item_id: "{{ item.sku }}",
item_name: "{{ item.name }}",
item_category: "{{ item.category }}",
price: {{ item.price }},
quantity: {{ item.quantity }}
}{% if not loop.last %},{% endif %}
{% endfor %}
]
}
});
Replace template variables with your platform’s actual variable syntax (Liquid for Shopify, PHP for WooCommerce, etc.).
Step 2: Configure GTM Tag
In GTM:
1. Create a new Tag → GA4 Event
2. Select your GA4 Configuration Tag
3. Set Event Name to: {{DLV - ecommerce.event}} or simply type “purchase”
4. Under “More Settings” → “E-commerce” → enable “Send Ecommerce data” → Source: “Data Layer”
5. Trigger: Custom Event → Event name equals “purchase”
6. Save and Preview
The “Clear Previous Ecommerce Data” rule:
Always push { ecommerce: null } immediately before pushing new ecommerce data. If you don’t, parameters from the previous event (e.g., an add_to_cart) may bleed into the next event, causing incorrect items or values on the purchase event.
Step 3: Verify in Preview Mode
In GTM Preview, complete a test purchase. In the Preview panel, find the “purchase” event → verify the GA4 Event tag fired → verify the ecommerce object shows all expected values. Then check GA4 DebugView for the event and its parameters.
6. Shopify GA4 Integration Options
Option 1: Shopify Native GA4 (via Google & YouTube App)
Shopify’s official Google & YouTube app (available in Shopify App Store) installs a GA4 web data stream and automatically fires all standard ecommerce events, including purchase with the items array. This is the fastest setup option and requires no custom code.
Limitation: The native integration provides limited customization. You cannot easily add custom parameters, modify event naming, or implement non-standard tracking.
Option 2: GTM via Shopify Theme Code
Install GTM’s <head> and <body> snippets into your Shopify theme (Online Store → Themes → Edit code → theme.liquid). Then implement custom data layer pushes in theme files:
– product.liquid — view_item event
– cart.liquid — view_cart event
– checkout/thank_you section (via Shopify’s “Additional scripts” in Settings → Checkout) — purchase event
The Shopify thank_you page has access to the Liquid order object, making it straightforward to populate the purchase event’s items array.
Option 3: Third-Party Shopify Apps
Apps like “Elevar” and “Littledata” provide enterprise-level GA4 ecommerce tracking for Shopify, including server-side tracking for higher data accuracy (bypassing ad blockers), enhanced ecommerce with all funnel events, and pre-built GTM containers. These range from $99–500/month depending on order volume.
7. WooCommerce GA4 Implementation
Option 1: WooCommerce Google Analytics Integration Plugin
The official WooCommerce Google Analytics Integration plugin supports GA4 and automatically fires all standard ecommerce events. Install from WordPress plugin directory → configure with your Measurement ID.
Accuracy note: This plugin fires events client-side only and may miss purchases when users have JavaScript disabled, ad blockers, or connection issues. For high-volume stores, this can cause 10–25% revenue discrepancy vs actual sales.
Option 2: GTM + Data Layer via Code
For maximum control, add custom PHP hooks to your WooCommerce theme’s functions.php:
// Fire purchase event on order confirmation page
add_action('woocommerce_thankyou', 'ga4_purchase_event', 10, 1);
function ga4_purchase_event($order_id) {
$order = wc_get_order($order_id);
$items = [];
foreach($order->get_items() as $item) {
$product = $item->get_product();
$items[] = [
'item_id' => $product->get_sku() ?: $product->get_id(),
'item_name' => $item->get_name(),
'item_category' => wp_get_post_terms($product->get_id(), 'product_cat')[0]->name ?? '',
'price' => (float) $order->get_item_total($item, false),
'quantity' => $item->get_quantity()
];
}
?>
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });
window.dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: '<?= esc_js($order->get_order_number()) ?>',
value: <?= floatval($order->get_subtotal()) ?>,
tax: <?= floatval($order->get_total_tax()) ?>,
shipping: <?= floatval($order->get_shipping_total()) ?>,
currency: '<?= esc_js(get_woocommerce_currency()) ?>',
items: <?= json_encode($items) ?>
}
});
</script>
<?php
}
8. GA4 Ecommerce Reports
Where to find ecommerce reports in GA4:
Reports → Life Cycle → Monetization → Ecommerce purchases
Key reports available:
– Item purchase quantity — units sold per product
– Item revenue — revenue by product
– Item brand — revenue and quantity by brand
– Item category — revenue by category hierarchy
– Checkout journey — funnel from begin_checkout to purchase
Explore → Funnel Exploration:
Build a custom checkout funnel: view_cart → begin_checkout → add_shipping_info → add_payment_info → purchase. This shows drop-off at each step. If 70% of users who begin checkout never reach the payment step, your payment entry form has friction worth optimizing.
Revenue metric definitions in GA4:
– Gross purchase revenue: Sum of all value parameters on purchase events
– Net purchase revenue: Gross minus refunds
– These are both reported — check which your reports are showing
9. Refund Events
GA4 supports partial and full refunds via the refund event:
// Full refund
gtag("event", "refund", {
transaction_id: "ORDER-12345",
value: 149.97,
currency: "USD"
});
// Partial refund (specific items)
gtag("event", "refund", {
transaction_id: "ORDER-12345",
value: 30.00,
currency: "USD",
items: [{ item_id: "SKU-002", quantity: 1 }]
});
Refunds subtract from your GA4 revenue metrics. For most ecommerce businesses, triggering the refund event programmatically when a refund is processed in your backend (via a webhook) is the most reliable approach.
10. Revenue Attribution in GA4
GA4 attributes purchase revenue to the session source/medium — the channel that drove the session in which the purchase occurred.
Default Channel Groups for revenue attribution:
– Direct, Organic Search, Paid Search, Email, Referral, Social, Affiliates
Attribution model used:
By default, GA4 uses Data-Driven Attribution (DDA) for conversion credit, but revenue in the Monetization reports is attributed using Last Non-Direct Click for session-level source/medium.
To see multi-touch revenue attribution:
Advertising → Attribution → Conversion paths → filter by purchase event → see all touchpoints that contributed to purchases in your date range.
11. Ecommerce Event Implementation Checklist
GA4 Ecommerce Implementation Checklist
Verify your complete ecommerce tracking implementation
12. GA4 Purchase Event Parameter Builder
Purchase Event Code Generator
Build a purchase event code snippet with your actual values
FAQ
Q1: What is the difference between value in the purchase event and the sum of item prices?
They can differ. value is the total revenue received by your business (subtotal after discounts). The sum of price * quantity across all items is the gross item value before any order-level discounts. For example, if you apply a 10% order discount, value = (sum of items) * 0.90. Both are important but GA4 uses value for revenue reporting.
Q2: Why does my GA4 revenue not match my actual sales revenue?
Common causes: (1) value is sent as a string — fix: ensure it’s a number. (2) Duplicate events — fix: verify transaction_id deduplication. (3) Purchase event fires before payment confirmation — fix: only fire after successful payment webhook. (4) Ad blockers preventing event sending — fix: consider server-side tracking. (5) Currency mismatch — fix: ensure currency matches your GA4 property currency.
Q3: How do I track cart abandonment in GA4?
Build a funnel in GA4 Explore: step 1 = add_to_cart event, step 2 = begin_checkout event, step 3 = purchase event. The drop from step 1 to step 2 is add-to-cart abandonment. The drop from step 2 to step 3 is checkout abandonment. Benchmark: average checkout abandonment rate is 70–75% according to Baymard Institute.
Q4: Does GA4 ecommerce support multi-currency stores?
GA4 records the currency parameter with each event. In reporting, GA4 converts all currencies to your property’s reporting currency using daily exchange rates. You can filter reports by currency in Explore. Always send the transaction currency with each event, not a hardcoded currency.
Q5: Can I add custom parameters to ecommerce events?
Yes, and it’s encouraged for business-specific data. Common custom parameters: customer_type (new/returning), discount_applied (true/false), subscription_tier, fulfillment_type. Register custom parameters as custom dimensions in GA4 Admin → Custom Definitions to see them in reports.
Conclusion
GA4 ecommerce tracking done correctly gives you the complete picture: which products drive revenue, where the checkout funnel loses customers, which traffic sources produce the highest-value orders. Done incorrectly, it generates confident-looking dashboards built on inaccurate data — which is more dangerous than no data.
The implementation order: purchase first, then add_to_cart, then the full funnel. Verify every parameter in DebugView before deploying to production. The revenue accuracy of your GA4 property is only as good as the specificity of your implementation.
Need GA4 ecommerce tracking set up correctly? The Ignited Nepal analytics team implements and audits GA4 ecommerce tracking from data layer architecture to DebugView verification. Get started at ignitednepal.com/cro/
Written by the Ignited Nepal team. ignitednepal.com