13 KiB
Ecommerce Events Implementation Guide
Complete Ecommerce Journey Tracking
This guide covers implementing the full customer journey from product discovery through purchase and refund handling.
Ecommerce Event Flow
1. view_item_list (User sees product listing)
2. select_item / view_item (User views product details)
3. add_to_cart (User adds product to cart)
4. view_cart (User reviews cart)
5. begin_checkout (User starts checkout - CRITICAL METRIC)
6. add_shipping_info (User selects shipping)
7. add_payment_info (User enters payment)
8. purchase (Transaction complete - MAIN GOAL)
9. refund (Optional: Product refunded)
Step-by-Step Implementation
Step 1: Product Listing Page
Event: view_item_list
Purpose: Track when user views product search results, category pages, or product collections
Implementation:
gtag('event', 'view_item_list', {
'items': [
{
'item_id': 'SKU_001',
'item_name': 'Blue T-Shirt',
'item_category': 'Apparel',
'price': 29.99
},
{
'item_id': 'SKU_002',
'item_name': 'Red T-Shirt',
'item_category': 'Apparel',
'price': 29.99
}
],
'item_list_id': 'search_results',
'item_list_name': 'Search Results for T-Shirts'
});
Trigger Points:
- User lands on category page
- Search results load
- Related products section appears
- Collection/sale page loads
Reporting Use:
- "Items" report - view count by product
- Funnel analysis - how many users view products
- Product performance metrics
Step 2: Product Detail Page
Event: view_item
Purpose: Track individual product views
Implementation:
// Extract product data from page
var productData = {
id: document.getElementById('product-id').textContent,
name: document.getElementById('product-name').textContent,
price: parseFloat(document.getElementById('product-price').textContent),
category: document.getElementById('product-category').textContent
};
gtag('event', 'view_item', {
'items': [{
'item_id': productData.id,
'item_name': productData.name,
'item_category': productData.category,
'item_brand': 'Your Brand',
'item_variant': 'Blue/Large',
'price': productData.price,
'quantity': 1
}],
'value': productData.price,
'currency': 'USD'
});
Advanced Implementation (Multiple Variants):
gtag('event', 'view_item', {
'items': [{
'item_id': 'SKU_123',
'item_name': 'Premium T-Shirt',
'item_category': 'Apparel',
'item_category2': 'Shirts',
'item_category3': 'Premium',
'item_brand': 'Brand Name',
'item_variant': 'Blue',
'item_list_name': 'Search Results',
'price': 49.99,
'quantity': 1
}],
'value': 49.99,
'currency': 'USD'
});
Trigger Points:
- Product detail page loads
- User arrives via search or category link
- Product page ready (after lazy-loading images)
Step 3: Add to Cart
Event: add_to_cart
Purpose: Track when items are added to shopping cart
Implementation:
document.getElementById('add-to-cart-btn').addEventListener('click', function() {
var quantity = parseInt(document.getElementById('quantity-input').value) || 1;
var price = parseFloat(document.getElementById('product-price').textContent);
var itemId = document.getElementById('product-id').textContent;
gtag('event', 'add_to_cart', {
'items': [{
'item_id': itemId,
'item_name': 'Product Name',
'item_category': 'Apparel',
'price': price,
'quantity': quantity
}],
'value': price * quantity,
'currency': 'USD'
});
// Proceed with cart addition
addToCart(itemId, quantity);
});
Important Notes:
- Value should be
price * quantity - Send immediately when user clicks add button
- Don't wait for backend confirmation
- Always include items array
Reporting Use:
- Add-to-cart rate metrics
- Funnel drop-off analysis
- Cart value trending
Step 4: View Cart
Event: view_cart
Purpose: Track when user reviews shopping cart
Implementation:
// On cart page load
var cartItems = getCartItemsFromStorage(); // Your cart data
var totalValue = 0;
var itemsArray = cartItems.map(function(item) {
totalValue += item.price * item.quantity;
return {
'item_id': item.id,
'item_name': item.name,
'item_category': item.category,
'price': item.price,
'quantity': item.quantity
};
});
gtag('event', 'view_cart', {
'items': itemsArray,
'value': totalValue,
'currency': 'USD'
});
Trigger Points:
- User navigates to cart page
- User views mini-cart
- Cart updates after removing item
Step 5: Begin Checkout (CRITICAL)
Event: begin_checkout
Purpose: Track when user initiates checkout (most important funnel metric)
Implementation:
document.getElementById('checkout-btn').addEventListener('click', function() {
var cartItems = getCartItems();
var totalValue = calculateCartTotal();
gtag('event', 'begin_checkout', {
'items': cartItems.map(function(item) {
return {
'item_id': item.id,
'item_name': item.name,
'item_category': item.category,
'price': item.price,
'quantity': item.quantity
};
}),
'value': totalValue,
'currency': 'USD'
});
// Navigate to checkout
redirectToCheckout();
});
Why It's Critical:
- Baseline funnel metric
- Identifies cart abandonment
- Used for conversion modeling
- Compare begin_checkout to purchase ratio
Trigger Points:
- User clicks "Checkout" button
- User navigates to checkout page
- One-page checkout form loads
Step 6: Add Shipping Info
Event: add_shipping_info
Purpose: Track when user selects shipping method
Implementation:
document.querySelectorAll('input[name="shipping"]').forEach(function(option) {
option.addEventListener('change', function() {
var selectedShipping = this.value;
var cartItems = getCartItems();
var subtotal = calculateSubtotal();
var shippingCost = getShippingCost(selectedShipping);
var total = subtotal + shippingCost;
gtag('event', 'add_shipping_info', {
'items': cartItems,
'value': total,
'currency': 'USD',
'shipping_tier': selectedShipping // 'standard', 'express', 'overnight'
});
});
});
Shipping Tier Values:
standard- Standard deliveryexpress- Express deliveryovernight- Overnight deliverypickup- Store pickupfree_shipping- Free shipping option
Reporting Use:
- Shipping method selection analysis
- Funnel drop-off by shipping option
Step 7: Add Payment Info
Event: add_payment_info
Purpose: Track when user enters payment information
Implementation:
document.getElementById('payment-form').addEventListener('submit', function(e) {
e.preventDefault();
var paymentMethod = document.querySelector('input[name="payment"]:checked').value;
var cartItems = getCartItems();
var totalValue = calculateTotal();
gtag('event', 'add_payment_info', {
'payment_type': paymentMethod,
'items': cartItems,
'value': totalValue,
'currency': 'USD'
});
// Process payment
processPayment(paymentMethod);
});
Payment Type Values:
credit_carddebit_cardpaypalapple_paygoogle_paybank_transfercrypto
Reporting Use:
- Payment method distribution
- Payment method-to-purchase completion rate
Step 8: Purchase (MOST IMPORTANT)
Event: purchase
Purpose: Track completed transactions (highest priority event)
Implementation:
// After payment confirmation
function trackPurchase(transactionData) {
gtag('event', 'purchase', {
'transaction_id': 'TXN_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9),
'affiliation': 'Online Store',
'value': transactionData.total,
'currency': 'USD',
'tax': transactionData.tax,
'shipping': transactionData.shipping,
'coupon': transactionData.coupon || undefined,
'items': transactionData.items.map(function(item) {
return {
'item_id': item.id,
'item_name': item.name,
'item_category': item.category,
'item_brand': item.brand,
'item_variant': item.variant,
'price': item.price,
'quantity': item.quantity,
'affiliation': 'Online Store'
};
})
});
}
Transaction ID Requirements:
✅ GOOD:
TXN_1731234567890_abc123def456 // Unique, timestamp-based
TXN_20241110_001_ABC123 // Order ID based
user_123_purchase_1234567890 // User + timestamp based
❌ BAD:
purchase // Not unique
order_123 // Can be reused
TXN_12345 // Too short, likely duplicated
Critical Points:
- Uniqueness: Each transaction gets ONE unique ID
- Non-reusable: Never use same ID twice
- Consistency: Use same ID in all systems (website, backend, reports)
- Timing: Send immediately upon payment confirmation
- Items Array: Must include all products purchased
Backend Implementation (Node.js):
app.post('/api/purchase', async (req, res) => {
const { orderData } = req.body;
const transactionId = `TXN_${Date.now()}_${generateRandomString(12)}`;
// Save order
await Order.create({
transactionId: transactionId,
items: orderData.items,
total: orderData.total,
// ...
});
// Return transaction ID for client-side tracking
res.json({ transactionId: transactionId });
});
// Client receives transaction ID and sends to GA4
gtag('event', 'purchase', {
'transaction_id': response.transactionId,
'items': cartItems,
'value': total,
'currency': 'USD'
});
Reporting Impact:
- Revenue tracking
- Transaction count
- Google Ads conversion tracking
- Attribution modeling
- Ecommerce reports
- Key Event (automatic)
Step 9: Refund (Optional)
Event: refund
Purpose: Track refunded purchases
Implementation:
// When refund is processed
gtag('event', 'refund', {
'transaction_id': orderData.transactionId, // Same ID as original purchase
'value': refundAmount,
'currency': 'USD',
'items': [
{
'item_id': 'SKU_123',
'quantity': 1 // Quantity refunded
}
]
});
Important:
- Use SAME transaction_id as original purchase
- Value is the refund amount
- Only include refunded items
Multiple Product Variants
Scenario: Product available in multiple sizes/colors
// Product: "T-Shirt" available in Blue/Large, Red/Small, etc.
gtag('event', 'add_to_cart', {
'items': [{
'item_id': 'SKU_TSHIRT_BLUE_LARGE', // Unique per variant
'item_name': 'Blue T-Shirt - Large',
'item_category': 'Apparel',
'item_variant': 'Blue/Large',
'price': 49.99,
'quantity': 1
}],
'value': 49.99,
'currency': 'USD'
});
Multi-Quantity Purchases
Scenario: Customer buys multiple products in one transaction
gtag('event', 'purchase', {
'transaction_id': 'TXN_12345678',
'value': 329.97,
'currency': 'USD',
'items': [
{
'item_id': 'SKU_001',
'item_name': 'Product A',
'price': 99.99,
'quantity': 2 // Two units
},
{
'item_id': 'SKU_002',
'item_name': 'Product B',
'price': 130.00,
'quantity': 1 // One unit
}
]
});
Value Calculation:
- Product A: 99.99 × 2 = 199.98
- Product B: 130.00 × 1 = 130.00
- Total: 329.98 ✓
Coupons and Discounts
Scenario: Customer applies coupon code
Single Coupon (Purchase Level):
gtag('event', 'purchase', {
'transaction_id': 'TXN_12345678',
'value': 89.99, // Already discounted
'currency': 'USD',
'coupon': 'SUMMER20', // Coupon code
'tax': 5.00,
'shipping': 10.00,
'items': [{
'item_id': 'SKU_001',
'item_name': 'Product',
'price': 100.00, // Pre-discount price
'quantity': 1
}]
});
Item-Level Coupon:
gtag('event', 'purchase', {
'transaction_id': 'TXN_12345678',
'value': 329.97,
'currency': 'USD',
'items': [
{
'item_id': 'SKU_001',
'item_name': 'Product A',
'price': 99.99,
'quantity': 2,
'coupon': 'SUMMER20', // Item-specific coupon
'discount': 20.00 // Discount amount
}
]
});
Funnel Analysis
View the complete ecommerce funnel:
view_item_list → 1000 users (100%)
view_item → 450 users (45%)
add_to_cart → 120 users (12%)
begin_checkout → 95 users (9.5%) ← CRITICAL METRIC
purchase → 75 users (7.5%)
Drop-off Points:
- view_item → add_to_cart: 73% drop (improve product pages)
- add_to_cart → begin_checkout: 21% drop (simplify cart)
- begin_checkout → purchase: 21% drop (optimize checkout)
Testing Ecommerce Events
- Product Page: Verify view_item fires with correct product data
- Add to Cart: Check add_to_cart with accurate quantity/price
- Checkout: Enable DebugView before begin_checkout
- Purchase: Validate transaction_id is unique
- Items Array: Confirm all items include item_id or item_name
Use DebugView to verify:
✓ Event name correct (purchase, add_to_cart, etc.)
✓ Required parameters present
✓ Items array structured correctly
✓ Values match actual amounts
✓ Transaction ID is unique