Connect Stripe revenue
Once connected, every payment is matched to the visitor who made it — so you see revenue per channel, not just visits.
1. Find your webhook URL
Open your site's page in EarnedFrom and scroll to "Revenue Connection" — you'll see a webhook URL that looks like:
https://earnedfrom.com/api/webhooks/stripe/YOUR_SITE_ID2. Create an event destination in Stripe
Stripe replaced the old Developers dashboard with Workbench, so webhooks moved and the button is no longer called "Add endpoint". Open the Webhooks tab and:
- Click Create an event destination
- Choose Your account, and leave the API version as it is
- Select the
checkout.session.completedevent - Click Continue, then pick Webhook endpoint as the destination type
- Click Continue, then paste your URL into Endpoint URL
Note the order: you pick the events before you enter the URL. If you are looking for a field to paste the URL into on the first screen, you are on the right page but one step early.
3. Paste the signing secret back
On the endpoint's page Stripe shows a signing secret that starts with whsec_ — click Reveal secret to see it. Copy it and paste it into the "Revenue Connection" box on your EarnedFrom site page, then click Save.
Test mode and live mode have different secrets for the same endpoint. This is the most common setup mistake: the secret gets copied in test mode and pasted while live payments run through live mode, so every event fails signature verification. To measure real payments, copy the live-mode secret.
4. Pass the visitor ID when you create the checkout
Using Stripe Payment Links or the Buy Button? Skip this step — it’s automatic. The EarnedFrom snippet finds links to buy.stripe.com on your pages and adds the visitor ID for you when someone clicks. Nothing to change on your side. (If you already put your own value in client_reference_id, EarnedFrom leaves it alone.)
For a checkout you create yourself in code, this is the step that connects a payment to a channel. EarnedFrom stores a visitor ID in the browser under askiraz_vid; read it and send it with the Checkout Session:
const visitorId = localStorage.getItem("askiraz_vid") || "";
// server side, when creating the session:
stripe.checkout.sessions.create({
// ...your usual options
metadata: { visitorId },
});Already using client_reference_id for your own order ID? Then usemetadata.visitorId as shown above — EarnedFrom reads it first. If you have nothing else in client_reference_id, you can put the visitor ID there instead; both work.
Skip this step and payments still get recorded — they just show up asUnmatched Revenue, with no channel attached.
How attribution works
EarnedFrom remembers the very first channel that brought each visitor (Google Ads, Meta Ads, SEO, referral, etc.) and keeps using it for that visitor's entire journey — including their eventual payment. So a payment that happens days after the first visit is still correctly credited to the original channel, not "Direct".
If it isn't working
Your site page in EarnedFrom tells you which of these it is — you don't have to guess:
- No events from Stripe yet. Stripe sends nothing until a payment happens. To check immediately, send a test event from the endpoint's page in Stripe.
- Signature doesn't verify. The secret you pasted doesn't belong to this endpoint — usually a test-mode secret used against live mode. Copy it again from the endpoint page.
- Events arrive but the type is wrong. The endpoint exists, but
checkout.session.completedisn't in its event list. Add that one event; you don't need to recreate the endpoint. - Payments arrive but show as Unmatched Revenue. Step 4 is missing — the payments carry no visitor ID, so there is nothing to attribute them to.
Don't use Stripe?
If your business uses Razorpay, PayTabs, iyzico, or another payment system instead, see the Revenue API guide — same result, any processor.