Implementation GuidesIntermediateUpdated June 25, 2026

How to pass attribution to Stripe Checkout

Capture AttribIQ visitor context in the browser, send it to your backend, and copy it into Stripe Checkout metadata.

TL;DR

The checkout server should not guess attribution. Capture the browser attribution object before the user starts checkout, send it to your backend, validate it, and copy the stable identifiers into Stripe metadata.

What you will learn
  • Read attribution from the AttribIQ browser API
  • Send visitor and session identifiers to your checkout endpoint
  • Copy attribution safely into Stripe Checkout Session metadata
  • Understand what to validate before creating checkout

Stripe Checkout attribution starts before the user leaves your app for checkout.

The important rule is simple: the browser knows the visit context, but the server creates the Stripe Checkout Session. Your frontend should read attribution from AttribIQ and pass it to your backend. Your backend should validate it and write it into Stripe metadata.

Install the tracker

Install AttribIQ on your marketing site and app pages where the checkout can begin.

<script async src="https://edge.attribiq.com/i/a7K4mN2qR8tP.js"></script>

When a visitor lands on the site, the tracker records source, referrer, UTM values, visitor ID, session ID, and landing page context.

Capture attribution before checkout

When the user clicks the upgrade or checkout button, read the attribution object and send it to your backend.

async function startCheckout(priceId) {
  const attribution = window.attribiq?.getAttribution?.()

  const response = await fetch("/api/create-checkout-session", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ price_id: priceId, attribution })
  })

  const { url } = await response.json()
  window.location.href = url
}

This is a transport step. The browser is not deciding the plan, the price, or the payment amount.

Validate on the backend

On the server, validate the input before calling Stripe:

  • The requested price ID is allowed for the authenticated user or public checkout.
  • The attribution object has the expected shape.
  • The project ID belongs to the AttribIQ project you expect for this site.
  • String lengths are bounded.
  • Unknown fields are ignored or stored only as debug metadata.

Do not allow the browser to decide revenue amount, currency, plan entitlements, or account ownership.

Create the Checkout Session

Use Stripe's server-side Checkout Sessions API. Stripe supports metadata on Checkout Sessions and documents client_reference_id as a reconciliation field.

const attribution = req.body.attribution || {}

const session = await stripe.checkout.sessions.create({
  mode: "subscription",
  line_items: [{ price: priceId, quantity: 1 }],
  success_url: "https://example.com/billing/success?session_id={CHECKOUT_SESSION_ID}",
  cancel_url: "https://example.com/pricing",
  client_reference_id: attribution.visitor_id,
  metadata: {
    attribiq_project_id: attribution.project_id,
    attribiq_visitor_id: attribution.visitor_id,
    attribiq_session_id: attribution.session_id,
    attribiq_landing_page: attribution.landing_page,
    attribiq_utm_source: attribution.utm_source,
    attribiq_utm_campaign: attribution.utm_campaign
  },
  subscription_data: {
    metadata: {
      attribiq_project_id: attribution.project_id,
      attribiq_visitor_id: attribution.visitor_id,
      attribiq_session_id: attribution.session_id
    }
  }
})

Keep metadata small and predictable. Store the identifiers that let AttribIQ join payment events to visits. Use the dashboard for reporting rather than trying to put every marketing field into Stripe.

Test the path

Run a checkout from a URL with UTMs:

https://example.com/pricing?utm_source=newsletter&utm_campaign=launch

After checkout completes, inspect the Checkout Session and Subscription metadata in Stripe. Then confirm the AttribIQ dashboard shows the revenue under the campaign and landing page you used.

If the first payment is attributed but renewals are not, subscription metadata is usually missing.

Next steps

After Checkout metadata is working, connect Stripe to AttribIQ. For the broader model, read Stripe revenue attribution for SaaS.

FAQ

Can I create the Stripe Checkout Session directly from the browser?

No. Create Checkout Sessions on your server. The browser can send attribution context to your server, but your Stripe secret key must stay server-side.

Should I trust all attribution fields from the browser?

Treat browser data as client-provided context. Validate project IDs, accepted hostnames, and expected shapes before storing or forwarding it.

What fields are required?

The minimum useful fields are project_id, visitor_id, and session_id. Landing page, referrer, and UTM fields improve debugging and reporting.

Where should I put subscription metadata?

For subscription checkouts, put the same attribution identifiers into subscription_data.metadata so renewals and subscription lifecycle events keep the attribution bridge.

Connect payments to the dashboard

Install the tracker, pass attribution into checkout, and report revenue by source, campaign, landing page, and path.

Related guides