Skip to main content
The Stripe revenue analytics integration brings server-verified charges, refunds, and lost disputes into your Revenue report. Connecting the key is step one; to see which channel, campaign, or country produced each sale, you also add one line of metadata to the payments you create — see how to attribute Stripe revenue to a marketing channel.

Before you connect

Create a Stripe restricted key that starts with rk_live_ or rk_test_. Grant only:
  • Webhook Endpoints: Write
  • Charges: Read
  • Refunds: Read
Test-mode restricted keys are supported.
Never paste a Stripe secret key (sk_…) into tinyanalytics. The integration rejects secret keys. Use a least-privilege restricted key and keep it private.

Connect Stripe

1

Open the integration

In your site, open Settings → Integrations, find Stripe, and select Connect.
2

Enter the restricted key

Paste the restricted key you created in Stripe. Turn on Email fallback if you want tinyanalytics to match a charge’s customer email to an already identified user when no analytics ID is present. You can switch this on or off at any time after connecting.
3

Save the connection

tinyanalytics validates the key and creates the webhook automatically when the key has Webhook Endpoints: Write access.
Connecting Stripe also adds stripe.com to the site’s referrer exclusions, so a return from Stripe does not start a new acquisition session.

Set up the webhook manually

If the restricted key cannot create webhook endpoints, tinyanalytics shows a webhook URL and accepts a signing secret instead:
1

Create the Stripe webhook

In Stripe, open Developers → Webhooks, add the URL shown by tinyanalytics, and listen for charge.succeeded, refund.created, refund.failed, and charge.dispute.closed.
2

Copy the signing secret

Reveal the new endpoint’s signing secret in Stripe. It starts with whsec_.
3

Finish the connection

Paste the signing secret into tinyanalytics and save.

How do I attribute Stripe revenue to a marketing channel?

Write the visitor’s identified user ID into Stripe metadata as ta_identified_user_id when you create the payment. A Stripe charge arrives on your server with no knowledge of the browser that caused it, so this ID is the link tinyanalytics uses to credit the sale to the visitor’s entry channel, campaign, referrer, and country. Payments with no link are reported under (no session). You can find the same snippet in the app under Settings → Integrations → Stripe → Attribution.
1

Identify signed-in visitors

Call identify() with your own user ID after login or signup. Pass the email trait too if you plan to use email fallback for guest checkouts:
The ID you choose here is the attribution key. It is stored in the browser’s localStorage, so it survives reloads and is still available when the visitor reaches checkout.
2

Read the ID on your checkout page

getUserId() returns the identified ID, or null for a visitor who has not been identified. Send it to your backend alongside whatever your checkout call already posts:
Read the ID at checkout time — in your click handler or on page load — not in a synchronous script in <head>. Before the tracking script finishes loading, getUserId() returns null.
3

Set the metadata where you create the payment

Add ta_identified_user_id to the Stripe call your backend already makes. Use the pattern that matches your integration:
Omit the key when the ID is null rather than writing an empty string. An empty value is not a link, and it stops the email fallback from running.
4

Turn on email fallback for guest checkouts (optional)

In Settings → Integrations → Stripe, switch on Email fallback. tinyanalytics then matches the charge’s email against your identified users when the payment carries no ta_* metadata at all. It matches an identified user whose ID is that email address, or who has a matching email trait from identify().The email is used only during matching and is never written to your analytics events.

Which metadata keys does tinyanalytics read?

tinyanalytics looks for these keys on the charge, payment intent, and Checkout Session, in that order. The first one it finds wins, so setting the metadata in one place is enough.
ta_session_id and ta_user_id are still honored when a payment carries them, but the tracking script never hands those values to your page. ta_identified_user_id is the key to use.

What appears in the Revenue report?

The report separates revenue into three tabs: Stripe charges add revenue. Refunds and lost disputes subtract revenue. A failed refund restores the amount that an earlier refund event subtracted. The Stripe view includes Total Revenue, Net Revenue, Refunds, Avg. Order Value, Paying Sessions, and Orders. Net revenue subtracts refunds and lost disputes; it does not subtract Stripe fees, taxes, or other accounting costs.
tinyanalytics does not deduplicate a purchase reported by both your client event and Stripe. If both sources record the same sale, All counts it twice. Use the Stripe tab as your source of truth, or stop sending the duplicate client revenue event.

How does tinyanalytics decide which channel gets the credit?

Every Stripe payment resolves in this order, and the first match wins:
  1. Linked to a session — the payment is credited to that session’s entry channel, campaign, referrer, and country.
  2. Linked to an identified user — the payment is credited to the entry of that person’s most recent session at or before the payment time. This is last-touch attribution within your reporting window: the visit that immediately preceded the sale gets the credit.
  3. No link — the payment is reported under (no session).
tinyanalytics never guesses. It does not match payments to visits by timing, amount, or any other heuristic, because a confidently wrong channel is worse than an honest (no session).

Tag one payment per customer, not every payment

Links are stored against the Stripe customer, so a customer only needs to be tagged once. Later payments from that customer inherit the link automatically — which means subscription renewals attribute without any repeated work. Tag the subscription at signup and every renewal invoice lands on the channel that won the original sale. Refunds and lost disputes inherit their original charge’s customer, so a negative adjustment subtracts from the same channel the sale was credited to. Attribution is resolved at report time, not frozen at payment time. If you add the metadata to your checkout today, the customers you tag from now on attribute correctly — and their other payments follow the same link the next time the report loads. You do not need to reprocess anything in Stripe.
Stripe data starts when you connect the integration. tinyanalytics does not backfill historical payments. Disconnecting stops new Stripe events but keeps the revenue already collected.

Why does my Stripe revenue show as (no session)?

(no session) means the payment reached tinyanalytics with no link to a visitor, so there is no channel to credit it to. It is a real bucket, not an error. Work through these causes in order:

Where does Stripe revenue apply?

Stripe revenue appears in the Revenue report and in scoped_stripe_revenue queries. Goals, funnels, experiments, and revenue alerts currently use client revenue events only.

Frequently asked questions

Yes. Both rk_test_… and rk_live_… restricted keys are supported. The connection status shows whether the key is in test or live mode.
No. Collection starts when the connection is active; tinyanalytics does not backfill historical Stripe payments.
New Stripe events stop entering tinyanalytics, while the revenue already collected remains in your reports.
No. Net revenue is gross charge revenue minus refunds and lost disputes. It does not subtract Stripe fees, taxes, or other accounting costs.
No. Links are stored against the Stripe customer, so tagging one payment per customer is enough. Later payments from the same customer — including every subscription renewal — inherit the link automatically.
Metadata is still the accurate option, and it takes precedence. Email fallback only runs when a payment carries no ta_* metadata at all, and it can only match buyers you have already identified by email address or with an email trait. Use metadata for signed-in buyers and email fallback to catch guest checkouts.
Paying Sessions counts payments linked to a specific analytics session. Stripe payments attributed through ta_identified_user_id credit revenue to a channel, campaign, and country, but they do not add to Paying Sessions. Use Orders as the Stripe purchase count.
Yes. Connect a rk_test_… restricted key, identify yourself in the browser, and complete a test checkout with Stripe’s 4242 4242 4242 4242 card while your ta_identified_user_id metadata is set. The charge appears on the Stripe tab with your entry channel instead of (no session).

Verify

The connection is working when Settings → Integrations → Stripe shows a connected key, webhook status, and a recent Last event time after a test or live charge. Open Revenue → Stripe and confirm the charge appears; issue a test refund if you also want to verify negative adjustments.
Attribution is working when that charge appears under a real channel — not (no session) — in the Revenue report’s source, campaign, and country breakdowns. If it lands in (no session), check the payment in Stripe: the charge, its payment intent, or its Checkout Session should carry a non-empty ta_identified_user_id in Metadata.

Identify users

Set the user ID that links Stripe payments to visits.

Revenue analytics

Compare client events and Stripe revenue.

Site settings

Find the site’s Integrations and Revenue settings.

SQL query builder

Query raw, signed Stripe revenue rows.

How your data is handled

See what the Stripe integration stores.