Affiliate tracking
How a partner's click becomes a referral, and how that referral follows the person into Stripe so the partner is paid for every invoice.
You need three things in place:
- The affiliate program turned on in the dashboard (Affiliates), with Stripe connected.
- The browser script on your marketing site and your app (the same one-line install as Instrument your product).
- One of the checkout hand-offs below.
No redirects and no link shortener: a partner's link is your own URL with ?via=<token>.
1. Partner links
Every partner gets a link like:
https://yourapp.com/?via=janeWhen someone lands on any page carrying ?via= (or ?ref=), the script records the click and remembers the referral in a first-party cookie for the campaign's window (60 days by default). Clicks from search engines and from domains you blocked are not counted.
- Sub-ids:
https://yourapp.com/?via=jane&sub=youtubetags the referral for the partner's own reporting. - Vanity links: a partner can have more than one token, each landing on a different page (
/pricing?via=jane-yt). Create them in the dashboard or withPOST /affiliates/{id}/links. - First or last click: set per program. With first click, a second partner's link does not take over a referral that is still inside its window.
Extra parameter names
Moving from another affiliate tool whose links use a different parameter? Keep old links working by listing the names on the script tag:
<script async src="https://app.ranla.ai/t.js?key=stxk_…" data-key="stxk_…"
data-ref-params="fpr,aff"></script>Several domains
Marketing site on yourapp.com and checkout on app.yourapp.io? List the other domains and the script adds ?referral=<id> to links pointing there, so the visit carries over:
<script async src="https://app.ranla.ai/t.js?key=stxk_…" data-key="stxk_…"
data-ref-domains="app.yourapp.io"></script>Pages without a link
To credit a partner on a page they did not link to (a dedicated landing page, a partner-specific pricing page), call:
stx.referralSource('jane')2. Record the signup
After someone signs up, tell the script who they are. This turns the anonymous click into a lead tied to their email:
stx.identify({ email: user.email })
// or, the same thing under the name other affiliate tools use:
stx.referralSignup(user.email)Call it on signup (and on login, which is harmless). If the campaign pays a lead bounty, the partner earns it when this signup makes their first payment.
No browser in the loop — a mobile app, an invite flow, a form handled entirely on your server? Record the referral with the API instead:
curl -X POST https://api.ranla.ai/affiliate-referrals \
-H "Authorization: Bearer $RANLA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"token":"jane","email":"[email protected]"}'See Affiliates API → Server-side referral tracking.
3. Hand the referral to Stripe
Once the person pays, Stripe is where the commission comes from. Any one of these links a Stripe customer to the referral. They are checked in this order, and the first partner to claim a customer keeps them.
Stripe Payment Links — automatic
Links to https://buy.stripe.com/… on a page with the script get client_reference_id added for you. Nothing to wire.
Stripe Checkout — client_reference_id
window.stx.referral holds the current referral id (an empty string when there is none). Pass it when you create the Checkout Session. Wait for it with stx.ready:
stx.ready(async () => {
const res = await fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ priceId, referral: window.stx.referral }),
})
window.location = (await res.json()).url
})// server
const session = await stripe.checkout.sessions.create({
mode: 'subscription',
line_items: [{ price: priceId, quantity: 1 }],
client_reference_id: referral || undefined,
success_url: 'https://yourapp.com/welcome',
})Custom subscriptions — metadata.ranla_referral
Creating customers or subscriptions yourself? Put the referral id (or the partner's link token) in metadata on the customer, subscription or invoice:
await stripe.customers.create({
email,
metadata: { ranla_referral: referral },
})Server-rendered forms — hidden inputs
The script fills any input marked data-stx-referral with the referral id, so it arrives with the form post:
<form method="post" action="/signup">
<input type="email" name="email" />
<input type="hidden" name="referral" data-stx-referral />
<button>Start free trial</button>
</form>Store it and pass it to Stripe as client_reference_id or metadata.ranla_referral.
Same email
If none of the above is present, a Stripe customer whose email matches a lead's email is attributed to that lead.
Coupon codes
Each partner can have their own promotion code (JANE20). A customer who pays with it is attributed to that partner even without a click — useful for podcasts, videos and offline mentions. On a page the partner linked to, stx.coupon holds the partner's code as { id, code, label } (stx.coupon.code is the text to show) and stx.affiliate their name, so you can show "Jane's 20% discount is applied".
Excluding payments
Add metadata.ranla = "false" to a Stripe customer, subscription or invoice and it never earns a commission — for internal accounts, partner deals you pay separately, or refunds you settle by hand.
What gets flagged
A referral is still recorded, but earns nothing, when:
- the person has the partner's own email, or the same company email domain (self-referral);
- the customer is already attributed to another partner (duplicate);
- the signup arrived after the cookie window ended (expired);
- the partner is suspended.
Flagged referrals show in the dashboard for review.
Checking it works
- Open
https://yourapp.com/?via=<a partner's token>in a private window. - In the console,
stx.referralshould be a non-empty id. - Sign up with a test email. The partner's page in the dashboard shows the lead within a few seconds.
- Pay with a Stripe test card. The commission appears after the next Stripe sync (every 15 minutes),
pendinguntil its hold ends.
Also see: Affiliates API · Webhooks