Documentation

Attribute revenue

Connecting Stripe on its own only gets you totals and MRR. To trace a specific payment back to the page or referrer that earned it, didthey.click needs to know which visitor became which paying customer — that’s what identify() is for.

Why identify matters

Every pageview is tied to a pseudonymous visitor. Once you call identify(), all of that visitor’s events — past and future in the session — get tied to a stable user ID instead. When a payment comes in for that same user ID, it can be traced back to the referrer or landing page that first brought them in.

Identify a user

window.__dtc.identify('user_123', { email: 'jane@acme.com' });

Call this once you know who they are

Typically right after signup or login — pass your own internal user ID, not an email, as the first argument.

The strong path: match on user ID

The most reliable match ties a Stripe customer to the same user ID you passed to identify(). Set it as metadata.userId when you create the Stripe customer:

Tag the Stripe customer

const customer = await stripe.customers.create({
	email: 'jane@acme.com',
	metadata: { userId: 'user_123' }
});

When a payment for that customer comes in, didthey.click looks for an identify() event with a matching user ID and attributes the payment to whatever referrer or landing page that visitor first arrived from.

The fallback: email matching

If a Stripe customer has no metadata.userId, didthey.click falls back to matching on email — comparing the customer’s email against the email trait passed to identify(). This only kicks in when the stronger user-ID match isn’t available.

Email matching can misfire

Shared inboxes, forwarding addresses, or a customer paying with a different email than the one they signed up with can all produce a false match. Prefer `metadata.userId` whenever you control the checkout flow.

Matching is retroactive

You don’t need to backfill anything by hand. Re-running attribution from the Connections page re-evaluates existing payments against your current identify() history, so identifying users going forward still attributes payments that already came in.