Skip to main content

Why track purchases?

Tracking purchases lets you answer:
  • How much revenue did we make this week?
  • Which marketing channel drives the most purchases?
  • What’s the average order value?
  • How many users bought after clicking a specific CTA?
  • What’s the conversion rate from signup to purchase?

The basic purchase event

Use the event name purchase with an amount property:
track('purchase', {
  amount: 49.99,       // in your currency (number, not string)
  currency: 'USD',     // optional but recommended
  plan: 'pro',         // what they bought
  method: 'stripe'     // payment method
})

Where to fire the purchase event

Fire it after the payment API confirms success — not when the user clicks the pay button.
// Wrong — fires before payment is confirmed
track('purchase', { amount: 49 })
await stripe.confirmPayment(...)

// Correct — fires after payment is confirmed
const result = await stripe.confirmPayment(...)
if (result.paymentIntent.status === 'succeeded') {
  track('purchase', { amount: 49 })
}

Stripe integration example

components/Checkout.jsx
import { track } from '../analytics.jsx'    // Import from your hub!
import { useStripe, useElements } from '@stripe/react-stripe-js'

export function CheckoutForm({ plan, price }) {
  const stripe = useStripe()
  const elements = useElements()

  async function handleSubmit(e) {
    e.preventDefault()

    // Track that checkout started
    track('checkout_started', { plan, amount: price })

    const { error, paymentIntent } = await stripe.confirmPayment({
      elements,
      confirmParams: { return_url: window.location.origin + '/success' },
      redirect: 'if_required'
    })

    if (error) {
      // Track failed payment
      track('payment_failed', {
        plan,
        amount: price,
        reason: error.message
      })
    } else if (paymentIntent?.status === 'succeeded') {
      // Track successful purchase
      track('purchase', {
        plan,
        amount: price,
        currency: 'USD',
        payment_id: paymentIntent.id
      })
      navigate('/dashboard?upgraded=true')
    }
  }

  return <form onSubmit={handleSubmit}>...</form>
}

Tracking the full purchase funnel

To understand where users drop off, track every step:
// Step 1: User clicks "Upgrade" button
track('upgrade_clicked', { plan: 'pro', source: 'settings_page' })

// Step 2: User opens checkout modal / page
track('checkout_started', { plan: 'pro', amount: 49 })

// Step 3a: Payment succeeds
track('purchase', { plan: 'pro', amount: 49, currency: 'USD' })

// Step 3b: Payment fails
track('payment_failed', { plan: 'pro', amount: 49, reason: 'card_declined' })

// Step 4: User confirms on success page
track('purchase_confirmed', { plan: 'pro', amount: 49 })
On your dashboard you can see how many users made it through each step — and where the majority drop off.

Subscription events

For recurring subscriptions, track both the initial purchase and renewals:
// First-time subscription
track('subscription_started', {
  plan: 'pro_monthly',
  amount: 29,
  currency: 'USD',
  billing: 'monthly'
})

// Plan upgrade (from lower to higher tier)
track('plan_upgraded', {
  from_plan: 'basic',
  to_plan: 'pro',
  amount: 49
})

// Plan downgrade
track('plan_downgraded', {
  from_plan: 'pro',
  to_plan: 'basic'
})

// Cancellation — very important to track
track('subscription_cancelled', {
  plan: 'pro',
  reason: 'too_expensive'  // if you ask for a reason
})

E-commerce cart tracking

// User adds item to cart
track('add_to_cart', {
  product_id: 'prod_abc123',
  product_name: 'Premium Plan',
  price: 49,
  quantity: 1
})

// User views cart
track('cart_viewed', {
  items: 3,
  total: 147
})

// User removes item
track('remove_from_cart', {
  product_id: 'prod_abc123',
  price: 49
})

// Cart abandoned (user leaves without buying)
// — usually tracked via a server-side webhook or timeout
track('cart_abandoned', {
  items: 3,
  total: 147
})

PropertyTypeDescription
amountnumberPurchase total — use a number, not a string
currencystring3-letter currency code: 'USD', 'EUR', 'INR'
planstringWhat they bought: 'pro', 'enterprise'
payment_idstringStripe/Razorpay payment intent ID
methodstringPayment method: 'stripe', 'razorpay'
billingstring'monthly' or 'annual'

Verifying purchases are tracked

  1. Make a test purchase (use Stripe’s test card 4242 4242 4242 4242)
  2. Go to Analytiq dashboard, click Events
  3. Filter by event name purchase
  4. Verify all properties appear correctly