Skip to main content
Imagine you’re running an online store — users browse products, add items to a cart, check out, and come back to buy again. This guide walks through that full journey, showing which events to fire at each step, what data to capture, and how to use it to understand user behavior, trigger campaigns, and measure revenue.

Core E-commerce Events

1. Product Catalog Events

Product Viewed

When: User lands on product detail page
track('Product Viewed', {
  product_id: 'prod_nike_air_max_90',
  sku: 'NIK-AM90-BLK-10',
  name: 'Nike Air Max 90 - Black',
  category: 'Footwear > Sneakers > Lifestyle',
  price: 129.99,
  currency: 'USD',
  brand: 'Nike',
  variant: 'Black / Size 10',
  image_url: 'https://cdn.acme.com/products/nike-am90-blk.jpg',
  inventory_status: 'in_stock',
  inventory_quantity: 47,
  url: '/products/nike-air-max-90-black'
});
Analytics use cases:
  • Product performance: Views by product, conversion rate (viewed → purchased)
  • Browse abandonment: Users who viewed but didn’t add to cart
  • Inventory insights: High-demand products (views vs stock)
Query example (top viewed products this week):
SELECT 
  properties->>'name' AS product_name,
  properties->>'category' AS category,
  COUNT(*) AS views,
  COUNT(DISTINCT user_id) AS unique_viewers
FROM profile_events
WHERE event_name = 'Product Viewed'
AND workspace_id = 'ws_123'
AND timestamp >= DATE_TRUNC('week', NOW())
GROUP BY product_name, category
ORDER BY views DESC
LIMIT 20;

Product List Viewed

When: User views category page, search results, or collection
track('Product List Viewed', {
  list_id: 'category_sneakers',
  category: 'Footwear > Sneakers',
  filters: {
    brand: ['Nike', 'Adidas'],
    price_range: '100-200',
    size: [10, 10.5, 11]
  },
  sort_by: 'price_low_to_high',
  products: [
    {
      product_id: 'prod_nike_air_max_90',
      position: 1,
      price: 129.99
    },
    {
      product_id: 'prod_adidas_ultraboost',
      position: 2,
      price: 149.99
    }
    // ... (include all products in viewport, max 50)
  ],
  total_products: 247  // Total matching products (pagination)
});
Analytics use cases:
  • Filter effectiveness: Which filters lead to purchases
  • Sort behavior: Does “price low-to-high” convert better?
  • Zero-results search: Queries with no results (product gap analysis)

Product Searched

When: User submits search query
track('Product Searched', {
  query: 'black running shoes size 10',
  results_count: 34,
  filters_applied: {
    brand: ['Nike'],
    price_max: 150
  },
  sort_by: 'relevance',
  search_type: 'full_text',  // vs autocomplete, voice
  results: [
    { product_id: 'prod_123', position: 1 },
    { product_id: 'prod_456', position: 2 }
    // Top 10 results
  ]
});
Analytics use cases:
  • Search effectiveness: Click-through rate by query
  • Failed searches: Queries with 0 results or no clicks
  • Search → Purchase attribution: Revenue by search query

2. Cart Management Events

Product Added

When: User clicks “Add to Cart”
track('Product Added', {
  cart_id: 'cart_abc-123',
  product_id: 'prod_nike_air_max_90',
  sku: 'NIK-AM90-BLK-10',
  name: 'Nike Air Max 90 - Black',
  price: 129.99,
  quantity: 1,
  category: 'Footwear > Sneakers',
  variant: 'Black / Size 10',
  position: 1,  // Position in product list where added from
  source: 'product_page'  // vs 'search_results', 'recommendations', 'quick_add'
});
Trigger campaign:
Campaign: Cart Abandonment Sequence
Trigger: Product Added + NOT Purchased within 2 hours
Channel: Email + Push
Message: "You left {product_name} in your cart. Complete checkout now!"

Product Removed

When: User removes item from cart
track('Product Removed', {
  cart_id: 'cart_abc-123',
  product_id: 'prod_nike_air_max_90',
  name: 'Nike Air Max 90 - Black',
  price: 129.99,
  quantity: 1,
  reason: 'user_action'  // vs 'out_of_stock', 'price_change'
});
Analytics: Cart removal reasons, products frequently removed

Cart Viewed

When: User opens cart page or mini-cart
track('Cart Viewed', {
  cart_id: 'cart_abc-123',
  products: [
    { product_id: 'prod_123', name: 'Nike Air Max 90', price: 129.99, quantity: 1 },
    { product_id: 'prod_456', name: 'Adidas Ultraboost', price: 149.99, quantity: 2 }
  ],
  subtotal: 429.97,
  tax: 34.40,
  shipping: 0.00,
  discount: -50.00,  // Coupon applied
  total: 414.37,
  cart_age_minutes: 45,  // Time since first item added
  item_count: 3
});
Analytics: Cart value distribution, abandoned cart value, time to purchase

3. Checkout Flow Events

Checkout Started

When: User clicks “Proceed to Checkout” from cart
track('Checkout Started', {
  checkout_id: 'chk_xyz-789',
  cart_id: 'cart_abc-123',
  products: [...],  // Same structure as Cart Viewed
  subtotal: 429.97,
  tax_estimated: 34.40,
  shipping_estimated: 0.00,
  total_estimated: 414.37,
  checkout_step: 1,  // Step in multi-step checkout
  checkout_url: '/checkout/shipping'
});
Funnel definition:
Checkout funnel:
1. Cart Viewed         (5,000 users)
2. Checkout Started    (2,500 users)  → 50% drop-off
3. Payment Info Added  (2,000 users)  → 20% drop-off
4. Order Completed     (1,800 users)  → 10% drop-off

Overall conversion: 36% (1,800 / 5,000)

Checkout Step Viewed/Completed

When: User progresses through checkout steps Step 1: Shipping Info
track('Checkout Step Viewed', {
  checkout_id: 'chk_xyz-789',
  step: 1,
  step_name: 'shipping_info'
});

// After entering address
track('Checkout Step Completed', {
  checkout_id: 'chk_xyz-789',
  step: 1,
  step_name: 'shipping_info',
  shipping_method: 'standard',
  shipping_price: 0.00,
  estimated_delivery_date: '2026-05-10'
});
Step 2: Payment Info
track('Checkout Step Viewed', {
  checkout_id: 'chk_xyz-789',
  step: 2,
  step_name: 'payment_info'
});

track('Checkout Step Completed', {
  checkout_id: 'chk_xyz-789',
  step: 2,
  step_name: 'payment_info',
  payment_method: 'credit_card',  // vs 'paypal', 'apple_pay', 'affirm'
  card_type: 'visa'  // Don't store card numbers!
});
Analytics: Drop-off by step, completion time by step, payment method conversion rates

Order Completed

When: Payment successful, order created
track('Order Completed', {
  order_id: 'ord_1234567890',
  checkout_id: 'chk_xyz-789',
  cart_id: 'cart_abc-123',
  revenue: 414.37,  // Total paid (after discounts, including tax/shipping)
  subtotal: 429.97,
  tax: 34.40,
  shipping: 0.00,
  discount: -50.00,
  coupon: 'SPRING2026',
  currency: 'USD',
  products: [
    {
      product_id: 'prod_nike_air_max_90',
      sku: 'NIK-AM90-BLK-10',
      name: 'Nike Air Max 90 - Black',
      price: 129.99,
      quantity: 1,
      category: 'Footwear > Sneakers',
      brand: 'Nike'
    },
    {
      product_id: 'prod_adidas_ultraboost',
      sku: 'ADI-UB-WHT-10',
      name: 'Adidas Ultraboost - White',
      price: 149.99,
      quantity: 2,
      category: 'Footwear > Running',
      brand: 'Adidas'
    }
  ],
  payment_method: 'credit_card',
  shipping_method: 'standard',
  is_first_purchase: true,  // Important for LTV analysis
  attribution: {
    source: 'google',
    medium: 'cpc',
    campaign: 'spring_sale_2026',
    referring_domain: 'google.com'
  }
});
Critical: Update user profile attributes:
setProfileAttributes({
  lifetime_orders: 1,
  lifetime_revenue: 414.37,
  first_purchase_date: '2026-05-04T10:30:00Z',
  last_purchase_date: '2026-05-04T10:30:00Z',
  average_order_value: 414.37,
  preferred_payment_method: 'credit_card',
  favorite_category: 'Footwear > Sneakers'
});
Trigger campaigns:
  • Post-purchase thank-you email
  • Product review request (7 days later)
  • Upsell campaign (complementary products)
  • Repeat purchase incentive (30 days later)

4. Post-Purchase Events

Order Fulfilled

When: Order ships (server-side event from fulfillment system)
track('Order Fulfilled', {
  order_id: 'ord_1234567890',
  shipped_at: '2026-05-05T14:00:00Z',
  tracking_number: 'USPS-1Z999AA10123456784',
  carrier: 'USPS',
  estimated_delivery: '2026-05-10',
  products: [...]  // Same as Order Completed
});
Trigger: Shipping confirmation email with tracking link

Order Delivered

When: Carrier confirms delivery
track('Order Delivered', {
  order_id: 'ord_1234567890',
  delivered_at: '2026-05-09T16:45:00Z',
  delivery_time_days: 5,
  on_time: true  // vs late delivery
});
Trigger: Review request email (product arrived, ask for feedback)

Product Reviewed

When: User submits product review
track('Product Reviewed', {
  order_id: 'ord_1234567890',
  product_id: 'prod_nike_air_max_90',
  rating: 5,
  review_text: 'Best sneakers I've ever owned!',
  recommend: true,
  verified_purchase: true
});
Analytics: Average rating by product, review completion rate

Order Refunded

When: Customer returns product
track('Order Refunded', {
  order_id: 'ord_1234567890',
  refund_amount: 129.99,
  refund_reason: 'wrong_size',  // vs 'defective', 'not_as_described', 'changed_mind'
  products_returned: [
    {
      product_id: 'prod_nike_air_max_90',
      quantity: 1,
      reason: 'wrong_size'
    }
  ],
  refund_method: 'original_payment',  // vs 'store_credit'
  refunded_at: '2026-05-15T10:00:00Z'
});
Update profile attributes:
setProfileAttributes({
  lifetime_orders: 1,  // No change
  lifetime_revenue: 284.38,  // Subtract refund
  total_refunds: 1,
  last_refund_date: '2026-05-15T10:00:00Z'
});
Trigger: Follow-up email (offer size exchange, understand issue)

Advanced Analytics Queries

Revenue Attribution by Channel

SELECT 
  properties->'attribution'->>'source' AS source,
  properties->'attribution'->>'medium' AS medium,
  COUNT(DISTINCT user_id) AS customers,
  COUNT(*) AS orders,
  SUM((properties->>'revenue')::DECIMAL) AS total_revenue,
  AVG((properties->>'revenue')::DECIMAL) AS avg_order_value
FROM profile_events
WHERE event_name = 'Order Completed'
AND workspace_id = 'ws_123'
AND timestamp >= NOW() - INTERVAL 30 DAY
GROUP BY source, medium
ORDER BY total_revenue DESC;

Product Affinity Analysis

-- Products frequently purchased together
SELECT 
  a.product_id AS product_a,
  b.product_id AS product_b,
  COUNT(*) AS co_purchase_count
FROM (
  SELECT 
    properties->>'order_id' AS order_id,
    jsonb_array_elements(properties->'products')->>'product_id' AS product_id
  FROM profile_events
  WHERE event_name = 'Order Completed'
  AND workspace_id = 'ws_123'
  AND timestamp >= NOW() - INTERVAL 90 DAY
) a
JOIN (
  SELECT 
    properties->>'order_id' AS order_id,
    jsonb_array_elements(properties->'products')->>'product_id' AS product_id
  FROM profile_events
  WHERE event_name = 'Order Completed'
  AND workspace_id = 'ws_123'
  AND timestamp >= NOW() - INTERVAL 90 DAY
) b ON a.order_id = b.order_id AND a.product_id < b.product_id
GROUP BY product_a, product_b
ORDER BY co_purchase_count DESC
LIMIT 50;
Use case: “Customers who bought X also bought Y” recommendations

Cohort Retention by First Purchase Month

WITH first_purchases AS (
  SELECT 
    user_id,
    DATE_TRUNC('month', MIN(timestamp)) AS cohort_month,
    MIN(timestamp) AS first_purchase_date
  FROM profile_events
  WHERE event_name = 'Order Completed'
  AND workspace_id = 'ws_123'
  GROUP BY user_id
),
repeat_purchases AS (
  SELECT 
    user_id,
    timestamp AS purchase_date
  FROM profile_events
  WHERE event_name = 'Order Completed'
  AND workspace_id = 'ws_123'
)
SELECT 
  fp.cohort_month,
  COUNT(DISTINCT fp.user_id) AS cohort_size,
  COUNT(DISTINCT CASE WHEN rp.purchase_date >= fp.first_purchase_date + INTERVAL 30 DAY 
                      AND rp.purchase_date < fp.first_purchase_date + INTERVAL 60 DAY 
                      THEN rp.user_id END) AS retained_month_1,
  COUNT(DISTINCT CASE WHEN rp.purchase_date >= fp.first_purchase_date + INTERVAL 60 DAY 
                      AND rp.purchase_date < fp.first_purchase_date + INTERVAL 90 DAY 
                      THEN rp.user_id END) AS retained_month_2,
  COUNT(DISTINCT CASE WHEN rp.purchase_date >= fp.first_purchase_date + INTERVAL 90 DAY 
                      AND rp.purchase_date < fp.first_purchase_date + INTERVAL 120 DAY 
                      THEN rp.user_id END) AS retained_month_3
FROM first_purchases fp
LEFT JOIN repeat_purchases rp ON fp.user_id = rp.user_id
GROUP BY fp.cohort_month
ORDER BY fp.cohort_month DESC;

Implementation Checklist

Phase 1: Core Tracking (Week 1)

  • Product Viewed (PDP)
  • Product Added to Cart
  • Checkout Started
  • Order Completed
  • Set profile attributes on purchase

Phase 2: Funnel Optimization (Week 2)

  • Product List Viewed (category/search pages)
  • Product Searched
  • Cart Viewed
  • Checkout Step Viewed/Completed (all steps)
  • Product Removed from Cart

Phase 3: Lifecycle & Retention (Week 3)

  • Order Fulfilled (server-side)
  • Order Delivered (webhook from carrier)
  • Product Reviewed
  • Order Refunded
  • Cart abandonment campaign
  • Post-purchase email sequence

Phase 4: Advanced Analytics (Week 4)

  • Revenue attribution by channel
  • Product affinity analysis
  • Cohort retention analysis
  • LTV prediction model

Next: Mobile app event tracking patterns → Mobile App Tracking