Tracking affiliate conversions means being able to answer one precise question: which affiliate brought the customer who just paid? Get that wrong, and you either pay commissions to the wrong affiliate or pay nothing at all — and the affiliate who sent you a paying customer has no way to prove it.
The hard part is not fraud. In our experience, affiliate programs lose far more money to tracking infrastructure gaps than to fraudulent claims. The loss is silent: no error, no alert, just an attribution that never formed.
This guide covers the three methods for tracking affiliate conversions, how to choose between them, and how to implement each one with concrete code. If you want to understand why tracking breaks — the five failure modes that account for 15–30% of lost conversions — read the diagnostic companion article on affiliate tracking failures first. This article picks up where that one ends: at the implementation.
The three methods for tracking affiliate conversions
Method 1: First-party cookie tracking
A prospect clicks an affiliate link. Your server reads the affiliate code from the URL parameter and writes a first-party cookie — one issued by your own domain, not a third-party platform domain — to the browser. That cookie persists until it expires or the user clears it.
At conversion time, your signup or checkout handler reads the cookie, retrieves the affiliate ID, and stores it against the user record.
This is the baseline method. It works reliably when the buyer uses the same browser on the same device from click to purchase. It breaks under Safari ITP, ad blockers, and cross-device journeys.
Method 2: Server-to-server postback (S2S)
Instead of relying on the browser, the merchant's server sends an HTTP POST directly to the affiliate platform's endpoint when a conversion event fires. No browser is involved. The conversion signal travels server-to-server.
S2S postback is the standard in performance marketing networks. It requires that the affiliate tracking link stamps a unique click ID — clickid or equivalent — into the landing URL, that your server captures and stores that click ID at landing, and that your confirmation logic can look up the click ID at the moment of conversion to build the postback URL.
S2S is immune to ad blockers and ITP because no JavaScript executes on the browser side for the conversion signal. Its weakness is setup complexity and the requirement that click IDs persist server-side through the whole funnel.
Method 3: Payment-processor metadata (Stripe-native)
The most robust method for Stripe-based SaaS products is to carry the affiliate session identifier directly inside the Stripe payment object as metadata, then process conversions from webhook events.
When a prospect lands on your site via an affiliate link, a cookie stores the session ID. When that session reaches checkout, your backend reads the session ID from the cookie and attaches it to the Stripe object — PaymentIntent, Checkout Session, or Subscription — as metadata. Stripe fires a webhook on payment confirmation. Your backend reads the metadata from the webhook payload and creates the commission. The browser's state at payment time is irrelevant.
This is server-side tracking: the attribution lives in Stripe's infrastructure, not in a cookie.
Comparison table
| Method | Reliability | Resistant to Safari ITP and ad blockers | Implementation complexity |
|---|---|---|---|
| First-party cookie | Medium — drops on Safari, ad blockers, cross-device | No | Low |
| Server-to-server postback | High — no browser dependency at conversion | Yes | Medium |
| Stripe metadata (server-side) | High — attribution lives in Stripe | Yes | Low–Medium (with an SDK) |
In practice, the most resilient setup layers the first two signals: a first-party cookie captures the session at click time, and the session ID is written into Stripe metadata at checkout. If the cookie was blocked, a cross-device fallback (see the attribution section below) provides a second path.
Attribution: window, model, and cross-device fallback
The attribution window
The attribution window is the period during which a click can generate a commission. A click on day 1 inside a 90-day window can credit a conversion on day 88. A click on day 1 inside a 30-day window cannot credit a conversion on day 35.
The window must match your sales cycle, not a platform default. The diagnostic article on affiliate tracking reports a 28-day median between first click and first paid transaction in SaaS B2B programs — but that is a median, not a ceiling. 20% of conversions arrive after day 45. A 30-day window structurally loses that tail.
RefCampaign uses a 90-day attribution window. The first-party _rc_sid cookie is set with a 90-day expiry at click time.
The attribution model
The default model is last-click: whichever affiliate link was clicked most recently before conversion receives 100% of the commission. Last-click is simple to implement, easy to audit, and aligns commission with the conversion event. It is the right default for most SaaS programs.
Last-click has a known weakness: it rewards affiliates who intercept at the bottom of the funnel — coupon sites, cashback platforms — at the expense of those who introduced the product. If your affiliate mix includes a significant share of content publishers doing top-of-funnel work, consider whether last-click incentives match the traffic you want.
Cross-device fallback via hashed email
Cross-device attribution addresses the scenario where a user clicks an affiliate link on one device and completes signup or purchase on another. The cookie written on device A does not exist on device B.
The solution is to link the click record to an identity signal that is device-independent. Email is the most practical option. After login or signup, when the user's email is known, your tracking layer hashes the email client-side and attaches it to the original click record. If a conversion arrives on a second device without a cookie, the system can look up prior click records associated with that email hash.
This fallback handles the B2B pattern where prospects research on personal devices and purchase on work devices, which in our experience accounts for 8–12% of unattributed conversions in programs with trials longer than 14 days.
Anti-fraud signals
Anti-fraud in affiliate tracking is a detection problem, not a blocking problem. Automatic blocking creates false positives — legitimate affiliates who drive real traffic from unusual patterns get excluded, and you never know you lost the conversion.
The correct posture is to flag suspicious signals and surface them for human review. The merchant decides.
| Signal | What it indicates |
|---|---|
| Repeated clicks from the same IP within seconds of each other | Bot or click inflation |
| One IP firing dozens of clicks in a short window | Automated traffic |
| Click-to-conversion interval under 5 minutes | Bot completing signup flow |
| Conversion rate far above the program average for a single affiliate | Likely self-referral or paid traffic laundering |
| Near-identical, evenly spaced click intervals | Scripted click generation |
Flagging, not blocking. Every flagged conversion stays in the queue. The merchant reviews and approves or rejects.
Implementing conversion tracking with RefCampaign
This section walks through the four implementation steps. The code is accurate for RefCampaign SDK v2 and current Stripe API versions.
Step 1: Load the tracking script
Place this tag in the <head> of your marketing site and app. It initializes the tracking session on page load, captures the _rc_sid value from affiliate links, and sets the first-party cookie.
<script src="https://sdk.refcampaign.com/v1.js" async></script>
The script is loaded from sdk.refcampaign.com, a first-party subdomain relative to refcampaign.com's infrastructure. Your own tracking domain is separate — the tracking link (https://track.refcampaign.com/AFFILIATE_CODE) is what affiliates share, and it sets the _rc_sid cookie on their behalf on your domain.
Step 2: Pass the session to Stripe at checkout
Read the _rc_sid cookie server-side at checkout creation time and attach it to the Stripe object as refcampaign_session metadata.
For one-time payments via PaymentIntent:
const paymentIntent = await stripe.paymentIntents.create({
amount: 2400,
currency: 'eur',
metadata: sessionId ? { refcampaign_session: sessionId } : {},
})
For subscriptions via Checkout Session, attach the metadata to both the session and subscription_data — the session metadata covers the checkout event, and subscription_data.metadata carries the value forward to every renewal webhook:
const sessionId = req.cookies.get('_rc_sid')?.value
const metadata = sessionId ? { refcampaign_session: sessionId } : {}
const checkout = await stripe.checkout.sessions.create({
line_items: [{ price: priceId, quantity: 1 }],
metadata,
subscription_data: { metadata },
mode: 'subscription',
success_url: `${appUrl}/success`,
cancel_url: `${appUrl}/pricing`,
})
Place refcampaign_session on the Subscription, not the Customer object, for recurring payments. Each subscription is tied to one specific affiliate referral. A customer who cancels and resubscribes via a different affiliate link creates a new subscription — the new link gets credited, not the original one.
RefCampaign processes Stripe webhooks asynchronously. Conversions appear in the dashboard within approximately 10 minutes of the webhook firing, not in real time. The processing queue retries failed deliveries up to 5 times before marking a conversion as unresolvable.
Step 3: Track conversions manually for non-Stripe payments
If you process payments outside Stripe — via PayPal, bank transfer, or a custom billing system — use the server SDK to submit conversions directly:
import { RefCampaignServer } from '@refcampaign/sdk'
const rc = new RefCampaignServer(process.env.REFCAMPAIGN_SECRET_KEY!)
await rc.trackConversion({
orderId: order.id, // required — idempotence key, prevents duplicate commissions
sessionId,
amount: 4999, // in cents
currency: 'EUR',
})
The orderId field is required as of SDK v2. It acts as an idempotence key: if your backend submits the same conversion twice (e.g., due to a retry on a network timeout), RefCampaign deduplicates on orderId and creates only one commission record. Either sessionId or customerEmailHash must be provided for attribution. Without one of these, RefCampaign cannot identify which affiliate to credit.
Step 4: Enable cross-device attribution with identify()
After login or signup, once you know the user's email, call identify() once on the client side. The browser SDK hashes the email using Web Crypto SHA-256 before transmitting anything — the raw email never leaves the browser. The hash is attached to the click record and enables attribution on subsequent devices where no _rc_sid cookie is present.
import { RefCampaignBrowser } from '@refcampaign/sdk'
// Call once after login or signup, when currentUser.email is available
RefCampaignBrowser.identify(currentUser.email)
identify() is fire-and-forget and first-write-wins: the email hash attached to the click record does not change on subsequent calls for the same session. The hash is deleted after 30 days in accordance with GDPR data minimization requirements.
Choosing the right setup for your Stripe integration
If you are deciding between integrating RefCampaign natively via Stripe metadata versus a third-party integration layer, the comparison of Stripe-native affiliate software vs. integration approaches covers the tradeoffs in detail — particularly around webhook reliability and attribution completeness.
The short version: Stripe-native attribution via metadata is more reliable than any approach that depends on a separate webhook pipeline or a browser-side conversion signal, because the attribution travels inside the Stripe payment object itself rather than alongside it.
For a broader comparison of affiliate tracking platforms — including how they handle ITP, postback, and Stripe integration — see the 2026 comparison of affiliate software.
A complete implementation in an afternoon
The implementation described above — CDN script, Stripe metadata handoff, and the identify() call — can be completed in an afternoon for a standard Next.js or Node.js backend. The Stripe metadata step is the critical one: it is what makes attribution survive browser limitations and cross-device journeys.
If your program is generating revenue but you are not confident your tracking is attributing it correctly, the diagnostic article on affiliate tracking failures will help you identify which failure mode is costing you attribution.
To set up affiliate conversion tracking on RefCampaign, start a free trial or review the pricing plans. The tracking infrastructure described in this guide is active on every plan.
Table of contents
Table of contents coming soon