Stripe Webhook / API Revenue Attribution Recipe
Stitch subscription and payment events with marketing campaigns using Stripe metadata and webhook listener configurations.
Beta — test mode. Stripe revenue ingestion is a webhook adapter you configure yourself, not a native Stripe app, and it is still test-mode beta. Stripe test-mode events are ignored by design, so confirm the conversions land with a real low-value live purchase (then refund it).
Who This Is For
This recipe is for developers and founders running SaaS or subscription-based sites on Stripe who want to link user checkouts, paid subscriptions, and order amounts back to marketing channels (like Google Ads clicks or organic referrers).
Key Terms Defined:
- Webhook — a server-to-server HTTP message sent by Stripe to SourceTrack whenever a billing event occurs.
- Signing secret — the value Stripe shows for your webhook endpoint; SourceTrack uses it to confirm each event really came from your Stripe account.
- Checkout Session — Stripe's system for collecting payment details and managing customer transactions.
- Visitor ID (st_aid) — the anonymous tracking identifier that maps the customer's click journey.
What You Will Set Up
You will configure your backend server code to retrieve the visitor ID from local storage (or a browser cookie) and pass it into Stripe's checkout session metadata. You will then set up a webhook endpoint inside Stripe to forward completed checkout session events to SourceTrack.
Which Stripe Method Are You Using?
Pick the entry that matches how your site takes payment. You can use more than one.
- Payment Links (
buy.stripe.com): add the SourceTrack tracker to the page that holds the link. On the standard install, the tracker addsclient_reference_idto the link when a visitor clicks it, if tracking is allowed for that visitor. A link that already has its ownclient_reference_idis left as it is, and the cookieless install does not add it. Then do Step 2 below. - Checkout Sessions created by your backend: do Step 1 and Step 2 below.
- Payment Intents without Checkout: this webhook does not read
payment_intent.succeeded, so it does not record these sales. Use the Offline Conversions API linked under Next Step.
Steps: Stripe Integration
Step 1: Forward Visitor ID in Stripe Metadata
When creating a Stripe Checkout Session on your backend, read the visitor ID (stored in the browser as st_aid) from the client's request payload and pass it as client_reference_id or inside themetadata block asanonymous_id or visitor_id.
// Example of passing st_aid in Stripe Checkout Session creation (Node.js backend)
const session = await stripe.checkout.sessions.create({
payment_method_types: ['card'],
line_items: [{ price: 'price_H5gg...', quantity: 1 }],
mode: 'subscription',
success_url: 'https://yoursite.com/success',
cancel_url: 'https://yoursite.com/cancel',
// Method A: Pass directly as client_reference_id (Recommended)
client_reference_id: req.body.st_aid,
// Method B: Pass inside metadata object
metadata: {
anonymous_id: req.body.st_aid
}
});Step 2: Configure Stripe Webhook
Route event messages from Stripe directly to the SourceTrack ingestion URL:
- Log in to your Stripe Dashboard and navigate to Developers → Webhooks.
- Click Add Endpoint.
- Enter your customized webhook endpoint URL:https://api.srctk.com/api/webhooks/stripe/YOUR_SITE_KEYReplace
YOUR_SITE_KEYwith the Site Key found under settings in your dashboard. - Under Select events to listen to, add:
checkout.session.completedrefund.createdcheckout.session.async_payment_succeeded— required if you accept delayed payment methods (ACH, SEPA debit, Klarna, bank debits)checkout.session.async_payment_failed— recommended with the above (SourceTrack ignores it safely; nothing is booked until settlement)
- Click Add Endpoint.
refund.created.checkout.session.completed whenpayment_status is already paid. Delayed methods complete the session withpayment_status: unpaid first — SourceTrack waits forcheckout.session.async_payment_succeeded before recording revenue. Without that event subscribed, those sales never appear.whsec_) in your SourceTrack dashboard underIntegrations → Stripe settings. SourceTrack uses it to confirm that each event really came from your Stripe account.How to Verify It Worked
- Make a real, low-value live purchase through your own checkout (use a visit that came from a tagged link, so it has a source), then refund it. Refunds net out of your revenue by source automatically.
- In your Stripe Dashboard under Developers → Webhooks, inspect the event logs for
checkout.session.completed. - Verify that the webhook request returned a HTTP
200 OKresponse. - Verify that the transaction data (revenue and site metadata) appears attributed in the Event Debugger of your SourceTrack dashboard.
Stripe test-mode events (livemode: false, including Stripe’s “Send test webhook”) are ignored by design: Stripe still sees200 OK, but nothing is recorded as revenue, so a test-mode payment will never appear in the Event Debugger.
Common Mistakes
- Incorrect Webhook Event Types: Stripe triggers a variety of events like
payment_intent.succeeded. SourceTrack parsescheckout.session.completed,checkout.session.async_payment_succeeded,refund.created, and subscription lifecycle events; other events are safely ignored. If you use ACH/SEPA/Klarna and only subscribe tocheckout.session.completed, revenue will not be recorded when those payments settle. - Unmatched Metadata Key: If you use custom names like
metadata.st_aid, SourceTrack will not read it. Stick toclient_reference_idormetadata.anonymous_id. - Missing Stripe Signing Secret: If you omit the signing secret under Settings, webhook payload signature checks will fail, returning a
400 Bad Request.
Next Step
Stripe setup is complete! Go to theOffline Conversions APIto learn how to register custom offline sales or updates directly from your server.