Server-side attribution
Attribute sales without Stripe Checkout: read the referral cookie and pass one metadata field.
Three lines of server code attribute a sale for a merchant who never uses Stripe Checkout.
The tracking script stores the referral in a cookie called rail_referral on your registrable
domain (acme.com, so app.acme.com and www.acme.com both see it). The cookie's value is a
JSON object; the field you need is clickId. Pass that click id to Stripe as
metadata.rail_referral when you create the customer, the subscription, or the checkout
session, and we bind the customer to the partner when Stripe tells us about it.
We read it from four events, in whichever order they arrive:
| Stripe object | Event we bind on | Where to put it |
|---|---|---|
| Customer | customer.created | metadata.rail_referral |
| Subscription | customer.subscription.created | metadata.rail_referral |
| Checkout Session | checkout.session.completed | metadata.rail_referral or client_reference_id |
| Payment Link, Pricing Table, Buy Button | checkout.session.completed | nothing: the script stamps client_reference_id for you |
Binding is idempotent on the Stripe customer id. The first event that carries a click id wins; a later one for the same customer changes nothing. A click id from another program, or one we never issued, binds nothing, and the sale shows on the attribution health panel with that reason.
Pick your stack:
- Node (Express or any handler that sees the request)
- Next.js App Router (a server action)
- Python (Flask, Django, FastAPI: anything with a request object)
Reading the cookie by hand
If your framework is not listed, the rule is the same everywhere: URL-decode the cookie, parse
the JSON, take clickId. The value is null when the visitor arrived without a partner link, and
you should create the customer without the metadata in that case rather than sending an empty
string.
rail_referral=%7B%22clickId%22%3A%22clk_01J...%22%2C%22partnerId%22%3A%22part_...%22%2C...%7DChecking that it works
Stripe test mode works the same way as live. Create a customer with the metadata, pay an invoice, and the sale appears under Insights, Attribution health, with the path shown as "Metadata". If it appears under "Unattributed" instead, the row says what was missing.