Stripe can tell you who paid and how much. Your analytics can tell you where each visitor came from. Neither one can tell you which channel brought in the money, because nothing connects a payment to the visit that led to it.
The fix is one id, carried from the browser into the payment. This guide shows how to do it with Stripe and Spreelytics.
How the join works
When someone lands on your site, the Spreelytics script gives their browser a visitor id. That id is already attached to everything they do, including which channel they arrived from.
If you put the same id into the Stripe payment, the payment can be matched back to the visitor. From there it is credited to a channel, such as Organic Search or a newsletter campaign.
Step 1: connect Stripe
In Spreelytics, open Settings → Revenue and connect Stripe with a restricted key that can write Webhook Endpoints and read Checkout Sessions, PaymentIntents, Invoices and Charges. The Open Stripe button there picks all five for you. Connecting creates the webhook in your Stripe account, so there is no URL or signing secret to copy.
Use a live key. Payments made in test mode would be counted as real revenue.
From then on, each payment arrives on its own as a purchase event. That covers one-off payments,
subscription charges and refunds.
Step 2: pass the visitor id into the checkout
Read the ids in the browser when the checkout starts, and send them to the server code that creates the Checkout Session:
await fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
plan: 'pro',
visitorId: Spreelytics.getVisitorId(),
sessionId: Spreelytics.getSessionId(),
}),
});
On the server, put them in the metadata under these two names. Where they go depends on the kind of payment:
const ids = {
spreelytics_visitor_id: req.body.visitorId,
spreelytics_session_id: req.body.sessionId,
};
// A one-off payment: set both, because either Stripe event can arrive first.
await stripe.checkout.sessions.create({
mode: 'payment',
line_items: [{ price: 'price_123', quantity: 1 }],
metadata: ids,
payment_intent_data: { metadata: ids },
success_url: 'https://example.com/thanks',
});
// A subscription: every renewal inherits it from here.
await stripe.checkout.sessions.create({
mode: 'subscription',
line_items: [{ price: 'price_456', quantity: 1 }],
subscription_data: { metadata: ids },
success_url: 'https://example.com/thanks',
});
Payment Links, Buy Buttons and Pricing Tables cannot take a value per visitor. Payments made through them are still recorded, but they are counted without a channel.
Step 3: choose how credit is split
In Settings → Revenue, pick a model and a lookback window.
Last-touch gives the whole payment to the last channel before it. Linear splits it evenly across every visit inside the window, so a channel that helped earlier gets a share. The window is 30 days by default and can be set from 1 to 90. Set it near the time your customers usually take to buy.
A typed address or a bookmark never takes the credit in either model. Someone who found you on Google and came back later by typing your address is still Google's sale.
We wrote more about this choice in Last-touch or linear, and why we made you pick.
Where the money shows up
- Overview: revenue and revenue per visitor, next to the traffic.
- Acquisition: revenue by channel, source and campaign.
- Goals: each goal carries the revenue its conversions earned.
- A person's timeline: what they paid, and when, after the visits that led to it.
Two mistakes to avoid
Sending the payment twice. If Stripe is connected, do not also post the same payments from your backend. They would be counted twice.
Naming a browser event purchase. If you also track the checkout in the browser, call it
something else, such as checkout_completed. A browser event carries no money, so a second
purchase would show up as a sale of zero.
What it costs
Revenue is on every plan, Free included. Each payment counts as one event toward your allowance. Refunds do not count.
The full reference, including Paddle, Polar and Lemon Squeezy, is in the Revenue docs. If you are weighing other tools for this job, see marketing attribution software compared, and if your revenue lives in Mixpanel, see how to track revenue in Mixpanel. For MRR, ARR and retention on a subscription product, see SaaS analytics.