Skip to content
Create account or Sign in
The Stripe Docs logo
/
Ask AI
Create accountSign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
APIs & SDKsHelp
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseUse Managed Payments
Use Payment Links
Use a prebuilt checkout page
    Overview
    Quickstart guides
    How Checkout works
    Customize look and feel
    Collect additional information
    Collect taxes
    Dynamically update checkout
    Manage your product catalog
    Subscriptions
    Manage payment methods
    Let customers pay in their local currency
    Add discounts, upsells, and optional items
    Set up future payments
    Save payment details during payment
    After the payment
      Fulfill orders
      Send receipts and paid invoices
      Customize redirect behavior
      Recover abandoned carts
      Analyze conversion funnel
      Track analytics events in Embedded Checkout
    Migrate from legacy Checkout
    Migrate Checkout to use Prices
Build a custom integration with Elements
Build an in-app integration
In-person payments
Terminal
Payment methods
Add payment methods
Manage payment methods
Faster checkout with Link
Payment scenarios
Handle multiple currencies
Custom payment flows
Flexible acquiring
Orchestration
Beyond payments
Incorporate your company
Crypto
Agentic commerce
Financial Connections
Climate
Understand fraud
Radar fraud protection
Manage disputes
Verify identities
United States
English (United States)
HomePaymentsUse a prebuilt checkout pageAfter the payment

Track analytics events in Embedded Checkout

Use analytics events from Embedded Checkout to monitor user behavior.

Private preview

Embedded Checkout analytics is in private preview. Request access to Embedded Checkout analytics.

Stripe Embedded Checkout supports real-time analytics events, allowing you to track user behavior, optimize conversion rates, and attribute sales to marketing campaigns.

Overview

With the analytics feature, you can:

  • Receive real-time events during the checkout process
  • Link events to specific funnels or campaigns using client metadata
  • Integrate with popular analytics platforms or your own systems

Available events

Embedded Checkout send the following analytics events throughout the checkout lifecycle:

EventWhen we send itKey data
deviceDataWhen the checkout UI rendersDevice category, language, platform, viewport
checkoutRenderedWhen the checkout UI rendersLine items, currency, amount
promotionCodeAppliedWhen a promotional code is successfully appliedPromotion code
lineItemChangeWhen items, quantities, or currency changeLine items, currency, amount
checkoutSubmittedWhen a customer submits payment informationPayment method type, line items, currency, amount

Event structure

All analytics events follow this structure:

{ eventType: string; // Event name (for example, 'checkoutRendered') checkoutSession: string; // Checkout Session ID details: object; // Event-specific data (see below) clientMetadata: {[key: string]: string}; // Your custom metadata timestamp: number; // Unix timestamp in seconds }

Event details

Each event includes specific details in the details object:

deviceData

Sent when the checkout UI loads and renders to the customer. Provides information about the user’s device and browser.

{ device: { category: 'mobile' | 'tablet' | 'desktop'; language?: string; platform?: string; viewport?: {width: number; height: number}; } }

checkoutRendered

Sent when the checkout UI loads and renders to the customer.

{ items?: Array<{ quantity?: number; // metered items won't show quantity product?: string; amount?: number; // in smallest currency unit (for example, cents) rateCard?: string; pricingPlan?: string; price?: string; }>; currency?: string; amount?: number; // in smallest currency unit (for example, cents) }

promotionCodeApplied

Sent when a promotion code is successfully applied.

{ code: string; }

lineItemChange

Sent when line items, quantities, or currency are updated. This includes quantity changes, currency changes, optional items, cross-sells, and upsells.

{ items?: Array<{ quantity?: number; product?: string; amount?: number; // total (not unit amount) rateCard?: string; pricingPlan?: string; price?: string; }>; currency?: string; amount?: number; // total in smallest currency unit (for example, cents) }

checkoutSubmitted

Sent when the customer submits their payment information.

{ items?: Array<{ quantity?: number; product?: string; amount?: number; // total (not unit amount) rateCard?: string; pricingPlan?: string; price?: string; }>; currency?: string; amount?: number; // total in smallest currency unit (for example, cents) paymentMethodType: string; // for example, 'card', 'klarna', and so on. }

Warning

All amounts are provided in the smallest currency unit (for example, cents for USD). Always use the amounts provided in the event details—don’t recalculate them on the client side. These analytics events are a best effort, and provide behavioral tracking and conversion analytics.

Implementation

  1. Create a Checkout Session with client metadata

    When creating your Checkout Session, include client_metadata to link events to specific funnels or campaigns:

    const session = await stripe.checkout.sessions.create({ ui_mode: 'embedded', line_items: [{ price: '{{PRICE_ID}}', quantity: 1, }], mode: 'payment', return_url: 'https://example.com/return?session_id={CHECKOUT_SESSION_ID}', client_metadata: { funnel_id: 'summer_sale_2025', campaign: 'email_promo', variant: 'version_A' }, });

    Warning

    Any data included in client_metadata is accessible on the client. Avoid sharing sensitive or confidential information through these fields.

  2. Initialize Embedded Checkout with an analytics event handler

    When initializing Embedded Checkout, include the onAnalyticsEvent handler:

    const checkout = await stripe.initEmbeddedCheckout({ clientSecret: session.client_secret, onAnalyticsEvent: (event: StripeCheckoutAnalyticsEvent) => { // Handle the event here console.log('Received event:', event); }, });
  3. Handle analytics events

    In your onAnalyticsEvent handler, you can process events and send them to your analytics platform.

    Here’s an example using Segment:

    const checkout = await stripe.initEmbeddedCheckout({ clientSecret: session.client_secret, onAnalyticsEvent: (event) => { const { eventType, details, clientMetadata, checkoutSession, timestamp } = event; switch (eventType) { case 'deviceData': // Custom Segment e-commerce event analytics.track('Checkout Device Data Collected', { device_category: details.device.category, language: details.device.language, platform: details.device.platform, viewport_width: details.device.viewport?.width, viewport_height: details.device.viewport?.height, checkout_id: checkoutSession, ...clientMetadata }); break; case 'checkoutRendered': // Standard Segment e-commerce event analytics.track('Checkout Started', { checkout_id: checkoutSession, currency: details.currency?.toUpperCase(), value: details.amount ? details.amount / 100 : 0, products: details.items?.map(item => ({ product_id: item.product, price: item.amount ? item.amount / 100 : 0, quantity: item.quantity })), ...clientMetadata }); break; case 'promotionCodeApplied': // Standard Segment e-commerce event analytics.track('Coupon Applied', { checkout_id: checkoutSession, coupon_id: details.code, ...clientMetadata }); break; case 'lineItemChange': // Custom Segment event analytics.track('Checkout Items Updated', { checkout_id: checkoutSession, currency: details.currency?.toUpperCase(), value: details.amount ? details.amount / 100 : 0, products: details.items?.map(item => ({ product_id: item.product, price: item.amount ? item.amount / 100 : 0, quantity: item.quantity, ...(item.price && { sku: item.price }) })), ...clientMetadata }); break; case 'checkoutSubmitted': // Standard Segment e-commerce event analytics.track('Payment Info Entered', { checkout_id: checkoutSession, payment_method: details.paymentMethodType, currency: details.currency?.toUpperCase(), value: details.amount ? details.amount / 100 : 0, products: details.items?.map(item => ({ product_id: item.product, price: item.amount ? item.amount / 100 : 0, quantity: item.quantity, ...(item.price && { sku: item.price }) })), ...clientMetadata }); break; } }, });

    You can also send events to your own back end for processing:

    const checkout = await stripe.initEmbeddedCheckout({ clientSecret: session.client_secret, onAnalyticsEvent: async (event) => { const { eventType, details, clientMetadata, checkoutSession, timestamp } = event; // Send to your backend analytics endpoint await fetch('/api/analytics', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ event_type: eventType, checkout_session: checkoutSession, details, client_metadata: clientMetadata, timestamp }) }); }, });

Use webhooks for conversion tracking

Use the checkout.session.completed webhook event to record successful payments:

// Server-side webhook handler app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => { const payload = req.body; const sig = req.headers["stripe-signature"]; let event; try { event = stripe.webhooks.constructEvent( payload, sig, process.env.STRIPE_WEBHOOK_SECRET ); } catch (err) { return res.status(400).send(`Webhook Error: ${err.message}`); } if (event.type === 'checkout.session.completed') { const session = event.data.object; // Track successful conversion with Segment analytics.track({ userId: session.customer, event: 'Purchase Completed', properties: { checkout_id: session.id, amount: session.amount_total / 100, currency: session.currency, funnel_id: session.client_metadata?.funnel_id, campaign: session.client_metadata?.campaign, } }); } res.status(200); });

This approach gives you both real-time behavioral tracking (through analytics events) and accurate conversion data (through webhooks) to understand your checkout funnel performance.

TypeScript Types

If you’re using TypeScript, you can import the event types:

import type {StripeCheckoutAnalyticsEvent} from '@stripe/stripe-js'; const checkout = await stripe.initEmbeddedCheckout({ clientSecret: session.client_secret, onAnalyticsEvent: (event: StripeCheckoutAnalyticsEvent) => { // TypeScript will provide full type checking }, });
Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc