585 lines
13 KiB
Markdown
585 lines
13 KiB
Markdown
# 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:**
|
||
```javascript
|
||
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:**
|
||
```javascript
|
||
// 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):**
|
||
```javascript
|
||
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:**
|
||
```javascript
|
||
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:**
|
||
```javascript
|
||
// 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:**
|
||
```javascript
|
||
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:**
|
||
```javascript
|
||
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 delivery
|
||
- `express` - Express delivery
|
||
- `overnight` - Overnight delivery
|
||
- `pickup` - Store pickup
|
||
- `free_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:**
|
||
```javascript
|
||
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_card`
|
||
- `debit_card`
|
||
- `paypal`
|
||
- `apple_pay`
|
||
- `google_pay`
|
||
- `bank_transfer`
|
||
- `crypto`
|
||
|
||
**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:**
|
||
```javascript
|
||
// 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:**
|
||
1. **Uniqueness:** Each transaction gets ONE unique ID
|
||
2. **Non-reusable:** Never use same ID twice
|
||
3. **Consistency:** Use same ID in all systems (website, backend, reports)
|
||
4. **Timing:** Send immediately upon payment confirmation
|
||
5. **Items Array:** Must include all products purchased
|
||
|
||
**Backend Implementation (Node.js):**
|
||
```javascript
|
||
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:**
|
||
```javascript
|
||
// 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
|
||
|
||
```javascript
|
||
// 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
|
||
|
||
```javascript
|
||
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):**
|
||
```javascript
|
||
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:**
|
||
```javascript
|
||
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
|
||
|
||
1. **Product Page:** Verify view_item fires with correct product data
|
||
2. **Add to Cart:** Check add_to_cart with accurate quantity/price
|
||
3. **Checkout:** Enable DebugView before begin_checkout
|
||
4. **Purchase:** Validate transaction_id is unique
|
||
5. **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
|
||
```
|