TraceKitTraceKit Docs
Analytics

Stripe revenue attribution

Connect a restricted Stripe key and attribute successful Stripe payments to analytics sessions.

Keep your Stripe key private

The key stays on the server. Never place a complete Stripe key in client code, documentation, or screenshots.

Connect Stripe

Stripe connection is optional. Only project owners can connect, replace, configure, or remove Stripe. TraceKit accepts one rk_live_... key. It rejects test, secret, publishable, and whitespace-modified keys.

Create a restricted key with these permissions:

Create your read-only Stripe key

Create a read-only Stripe API key

  1. Scroll down and select Create key.
  2. Do not change the selected permissions.
  3. Copy the key and paste it into TraceKit.
  4. Keep the key active so TraceKit can refresh revenue.

Replace an existing TraceKit key if it lacks Charges: Read or Invoices: Read access.

Stripe resourcePermissionValidation callPurpose
Account dataReadGET /v1/accountValidate the connected Stripe account.
ChargesReadGET /v1/charges?limit=1Import successful payments from supported Stripe payment flows.
Checkout SessionsReadGET /v1/checkout/sessions?limit=1Add attribution metadata and product details when available.
InvoicesReadGET /v1/invoices?limit=1Identify renewals and products for invoice payments.
ProductsReadGET /v1/products?limit=1Support saved product filters.
All other resourcesNoneNo preflight callApply least privilege.

Enter the restricted key in the project owner Stripe settings. TraceKit validates the Account, Charges, Checkout Sessions, Invoices, and Products calls.

Add Checkout metadata

Put attribution identifiers directly on Checkout Session.metadata. Read the host-only cookies in a same-origin Next.js server route.

import { cookies } from 'next/headers';

const cookieStore = await cookies();
const visitorId = cookieStore.get('tracekit_visitor_id')?.value;
const sessionId = cookieStore.get('tracekit_session_id')?.value;

if (!visitorId || !sessionId) {
  return new Response('TraceKit analytics IDs are unavailable', { status: 400 });
}

const session = await stripe.checkout.sessions.create({
  mode: 'payment',
  line_items: [{ price: 'price_...', quantity: 1 }],
  success_url: 'https://example.com/success',
  cancel_url: 'https://example.com/cancel',
  metadata: {
    tracekit_visitor_id: visitorId,
    tracekit_session_id: sessionId,
  },
});

Same-origin Checkout route

Use this example only when the Checkout route shares the browser hostname.

The Browser SDK exposes no public visitor or session identity getter. Host-only cookies use Path=/ and SameSite=Lax. HTTPS adds Secure. The visitor cookie lasts 365 days. The session cookie expires after 30 minutes of inactivity. Host-only cookies do not reach another API host. Blocked cookies prevent the server route from reading attribution IDs. Payments without readable IDs remain visible as unmatched.

Metadata fieldStatusMeaning
tracekit_visitor_idRequired for attributionBrowser visitor ID with 32 lowercase hexadecimal characters, and not all zeroes.
tracekit_session_idRequired for attributionBrowser session ID with 32 lowercase hexadecimal characters, and not all zeroes.
tracekit_trace_idOptionalEnables View checkout trace when the trace exists.
tracekit_user_idOptionalStores an opaque internal user ID for future use.

Verify sync and attribution

No analytics webhook

TraceKit polls successful Charges every five minutes. Analytics revenue needs no webhook setup.

TraceKit imports only successful, paid, captured, live-mode Charges. Checkout Sessions enrich matching Charges with attribution metadata and product details. TraceKit does not count Checkout Sessions as separate payments. Revenue uses the gross captured amount. Refunds do not reduce reported revenue. Renewals are included by default. Excluding renewals changes reports only. TraceKit does not import subscription cancellations. TraceKit performs no foreign-exchange conversion. The selected dashboard currency controls which imported revenue appears.

The first import covers the 30-day analytics retention window. Later syncs resume from a cursor and reconcile the prior 24 hours. Unmatched payments stay visible. Removing Stripe deletes its connection settings and imported payments.

Continue

On this page