How to run a Stripe affiliate program, from click to payout

A 9-step Stripe affiliate program setup: tag each referral in Checkout, create commission when invoices are paid, handle refunds, then pay affiliates.

Muzahid Maruf — Founder of TrackRev.io

Muzahid Maruf

Affiliate programs · 12 min read
On this page
  1. 01What Stripe records and where an affiliate ID can live
  2. 02How to set up a Stripe affiliate program in 9 steps
  3. 03Build it yourself or use an affiliate tool
  4. 04How TrackRev handles the Stripe side

Explore with AI

Opens this article inside the chosen assistant with a ready-made prompt.

A Stripe affiliate program comes down to four jobs: capture the referral when someone clicks, carry the affiliate's ID into Stripe Checkout or onto the subscription, create commission from money Stripe has collected (invoice.paid for Stripe Billing subscriptions), and take it back when a charge is refunded.

Stripe stores the payment, but nothing on a charge says who sent the customer.

Key takeaways

  • Stripe copies metadata between objects in only four cases, so decide early which object holds the affiliate ID: the Checkout Session, the subscription or the customer.
  • A Payment Link or Buy Button needs a handler that copies the ID onto the subscription, or the second month's invoice has no affiliate on it.
  • Pay commission on paid invoices and before tax. At 20% on a $49 plan the right base pays $9.80, and a 19% VAT-inclusive base pays $11.66.
  • Hold payouts longer than your 30-day refund window, because card chargebacks typically arrive within 120 days.
  • Paying 40 affiliates $150 each costs $120 on Stripe Connect and $60 on Global Payouts with US bank transfers.

What Stripe records and where an affiliate ID can live

Stripe gives you three places to attach a referral. A Checkout Session takes a client_reference_id. Payment Links, Buy Buttons and pricing tables accept the same value as a URL parameter or an HTML attribute.

Customers, subscriptions and PaymentIntents take metadata, which Stripe's metadata guide caps at 50 key-value pairs, with keys up to 40 characters and values up to 500.

The same guide says metadata does not copy automatically between related objects, with four exceptions, so an ID set on the wrong object never arrives on the invoice you will pay commission on.

Where you set itReaches renewal invoices?What Stripe does with it
Checkout Session: client_reference_idNoStays on the Checkout Session and appears in checkout.session.completed
Payment Link, Buy Button or pricing table: client_reference_idNoPassed to the session as a URL parameter or attribute of up to 200 characters; invalid values are silently dropped
Subscription: metadata via subscription_dataYesCopied to each new invoice as parent.subscription_details.metadata
Customer: metadataBy lookupNothing is copied; you fetch the customer from the invoice
PaymentIntent: metadata via payment_intent_dataOne-time payments onlySnapshotted onto the Charge once; later edits are not

Sources: Stripe documentation on metadata, Payment Links URL parameters, pricing tables and Buy Buttons, October 2026.

How to set up a Stripe affiliate program in 9 steps

Step 1: Set the terms your Stripe data has to support

Four numbers decide what the rest of the setup must record: the commission rate, how long renewals keep earning it, the hold before commission becomes payable, and the click-to-purchase window.

The affiliate benchmark tables list 20% for 12 months as the median B2B SaaS program and 60 days as the median cookie window.

Monthly planMonthly commissionCommission over 12 monthsGross profit left
$19$3.80$45.60$136.80
$49$9.80$117.60$352.80
$99$19.80$237.60$712.80
$199$39.80$477.60$1,432.80

20% for 12 months, customer retained all 12, 80% gross margin assumed.

Write the commission base into the terms as well: the invoice amount after discounts and before tax.

Step 2: Capture the click on your own domain

Set the referral cookie from your server, on your own domain.

WebKit documents that Intelligent Tracking Prevention deletes cookies created in JavaScript after 7 days without user interaction, so a 60-day window written by a script shrinks to a week for Safari visitors who do not return.

A cookie on your domain is also invisible on buy.stripe.com, so the ID has to travel in the URL or through your checkout code. The cookie side has its own guide: affiliate tracking without third-party cookies.

Step 3: Pass the affiliate ID into Stripe

When your server creates the Checkout Session, read the cookie and set two fields in one call. client_reference_id labels the Checkout Session. subscription_data.metadata writes the ID onto the subscription Stripe creates, which is what lets renewals find their affiliate.

Server code that creates the session (Node)
// aff_id was set when the visitor clicked the affiliate linkconst affiliateId = (await cookies()).get("aff_id")?.value; const session = await stripe.checkout.sessions.create({  mode: "subscription",  line_items: [{ price: "price_123", quantity: 1 }],  client_reference_id: affiliateId,  subscription_data: { metadata: { affiliate_id: affiliateId } },  success_url: "https://example.com/welcome",});

For a Payment Link, append ?client_reference_id= and the affiliate's ID to the URL, and Stripe sends the value in checkout.session.completed after payment. Pricing tables and Buy Buttons take a client-reference-id attribute.

A link-level subscription_data.metadata is set once when you create the link, so it names an affiliate only if you create one Payment Link per affiliate through the API. Stripe Payment Links attribution covers that flow.

A podcast read has no clickable link, so give that affiliate a promotion code. Stripe's Promotion Code object has a metadata field and a max_redemptions limit, so one code per affiliate can name its owner and cap its use.

Coupon code tracking for affiliate programs covers the rest.

Step 4: Make the ID survive to renewals

A Payment Link or Buy Button puts the ID on the Checkout Session only, so the month-2 invoice arrives with no trace of the referral.

Close the gap in your checkout.session.completed handler by writing the ID to the subscription and the customer.

Webhook handler for checkout.session.completed
const session = event.data.object;const affiliateId = session.client_reference_id; if (affiliateId && session.subscription) {  await stripe.subscriptions.update(session.subscription, {    metadata: { affiliate_id: affiliateId },  });}if (affiliateId && session.customer) {  await stripe.customers.update(session.customer, {    metadata: { affiliate_id: affiliateId },  });}

Stripe's webhook guide says not to depend on event order, so the first invoice.paid can arrive before this write lands. For an invoice with a billing_reason of subscription_create, list the Checkout Sessions with a subscription filter and read client_reference_id there.

For later invoices, check parent.subscription_details.metadata, then the subscription, then the customer.

Step 5: Create commission from collected money

Create the commission for a subscription on invoice.paid, which Stripe's subscription webhook guide describes as sent when an invoice is successfully paid.

Skip any invoice with an amount_paid of 0, and use the invoice ID as the commission row's unique key so a replayed event changes nothing.

Stripe eventWhat it tells youWhat to do
invoice.paidAn invoice, first or renewal, was paidCreate commission if amount_paid is above 0
checkout.session.completedCheckout finished; payment_status is paid, unpaid or no_payment_requiredCopy the affiliate ID (step 4); commission only on one-time Checkout Sessions marked paid
checkout.session.async_payment_succeededA bank debit or voucher settled, which Stripe says can take 2 to 14 daysCreate the one-time commission
charge.refundedA refund, partial ones includedRecompute commission (step 7)
charge.dispute.createdA cardholder opened a disputeFreeze the commission (step 7)
customer.subscription.updatedA renewal, plan change or discountUpdate the base for future invoices
customer.subscription.deletedThe subscription endedStop accruing

Event names and descriptions from Stripe's subscription webhook, refund, Checkout fulfillment and Payment Links guides, October 2026.

A free trial can look like a sale

Stripe's Checkout reference says a free-trial session reports payment_status paid once the $0 trial invoice is processed. A handler that creates commission on checkout.session.completed without checking the amount pays for trial signups that never convert.

Verify the signature and return a 2xx before slow work. Stripe's webhook documentation says failed deliveries are retried for up to three days in live mode and the same event can arrive twice, so log event IDs.

Then choose one amount per invoice and keep to it. total_excluding_tax is the invoice total after discounts and before tax; subtotal is before invoice-level discounts. Take a $49.00 plan billed to a customer in Germany with 19% VAT added.

Commission on the VAT-inclusive total overpays by the tax rate on every renewal.

Commission baseInvoice amount20% commissionOverpayment
Before tax (total_excluding_tax)$49.00$9.80None
Invoice total with 19% VAT$58.31$11.66$1.86 a renewal

A $49.00 monthly plan; $58.31 is $49.00 plus $9.31 of VAT.

Step 6: Follow upgrades, downgrades and cancellations

Commission follows invoices, so most plan changes need no special code: an upgrade makes the next invoice larger and a cancellation stops invoices. What needs a rule is the recurring window.

Count paid invoices per subscription using billing_reason (subscription_create for the first, subscription_cycle for each renewal, subscription_update for a mid-cycle change) and stop at your term.

Decide whether proration invoices earn commission, and whether the term counts months or invoices; annual plans make that difference visible.

ScenarioPaid invoicesAffiliate earns
Stays on the $49 plan all year12 invoices of $49.0012 × $9.80 = $117.60
Upgrades to $99 after month 44 of $49.00, then 8 of $99.00$39.20 + $158.40 = $197.60
Cancels after month 33 invoices of $49.003 × $9.80 = $29.40
Starts a trial and cancels before the first chargeOne $0.00 invoice$0.00

Worked example: $49 monthly plan, 20% commission for 12 months, proration ignored.

Step 7: Reverse refunds and hold for chargebacks

Stripe sends charge.refunded for every refund, partial ones included. Recompute the commission from the charge's cumulative refunded amount so a replayed event cannot subtract twice.

If the original commission was already paid, carry the difference as a negative balance on the next payout; the refunds and upgrades guide walks through the ledger states.

CaseEventCommission beforeCommission after
Full refund of a $49 renewalcharge.refunded$9.80$0.00
$100 partial refund on a $300 annual chargecharge.refunded$60.00$40.00
Dispute opened on a $49 renewalcharge.dispute.created$9.80Frozen until charge.dispute.closed, then reversed if lost

At a 20% rate. The partial refund leaves $200 of net revenue, and 20% of $200 is $40.

Holds and chargebacks run on different clocks

Stripe's dispute documentation says card networks typically let a cardholder file within 120 days of the payment, and a dispute can take 2 to 3 months to resolve. A 30-day hold covers refund requests; a chargeback filed in month 3 or 4 arrives after it. Hold as long as your affiliates will accept, and state the hold length in the terms before the first payout.

Step 8: Pay the affiliates

Stripe settles your customers' payments to you. Getting part of that money to affiliates is a separate job, and the rails differ in reach and cost.

Payout railWho it reachesCost for 40 affiliates at $150Catch
CSV export, then PayPal or WiseWherever PayPal or Wise operatesProvider fees onlyYou run each payout cycle by hand
Stripe Connect transfersAffiliates in your platform's region, with limited cross-border reach$80 account fees + $25 payout fees + $15 routing = $120 (2.0%)Each affiliate onboards with Stripe; a transfer fails if your balance is short
Stripe Global PayoutsRecipients without Stripe accounts; the sender must be a US or UK business40 US bank payouts at $1.50 = $60 (1.0%)Requires Stripe Treasury; you manage your own compliance, which Stripe says can call for a Money Transmitter License
Rewardful Managed PayoutsOptional on every Rewardful plan3% of $6,000 = $180 (3.0%)Affiliates may also pay withdrawal fees
Tolt auto payoutsPayPal, Wise, local bank, crypto and wire2% of $6,000 = $120 (2.0%)Growth plan ($99) or higher

Forty payouts of $150 is $6,000 in a month. Connect rates from Stripe's Connect pricing page: $2 per monthly active account, 0.25% + $0.25 per payout, plus the 0.25% of payout volume funds-routing line in its feature table. Global Payouts rate from Stripe's Global Payouts pricing. Vendor rates from Rewardful and Tolt, October 2026.

Stripe Connect pays out of your own Stripe balance: Stripe's separate charges and transfers guide says a transfer fails when it exceeds your available balance, with no automatic retry.

Transfers cross borders only between the US, Canada, the UK, the EEA and Switzerland. Stripe's docs now call Standard, Express and Custom accounts legacy and model a payee as a v2 Account with a recipient configuration.

Stripe restricts transfers to permitted use cases, and its cross-border payouts page lists affiliate payouts under Global Payouts, so ask Stripe whether your program fits before you build.

For a first program I would start with the CSV route: Stripe Connect's $2 monthly account fee alone is 1.3% of a $150 payout, and every affiliate must finish Stripe onboarding.

Collect a W-9 or W-8 before the first payout on any rail; how to pay affiliates covers methods and tax forms.

Step 9: Test the whole path with test clocks

Stripe's test clocks (called simulations in the current docs) move a test subscription through time, so a month-2 renewal takes minutes.

Run one referred customer through a payment, a renewal, an upgrade, a partial refund and a cancellation, then compare the ledger with the invoice list.

Repeat with a Payment Link and an API-created Checkout Session, which take different paths through steps 3 and 4, and run an unreferred customer to confirm nothing is paid.

Build it yourself or use an affiliate tool

Steps 3 to 7 stay yours to maintain while the program runs: event order, replays, disputes and payout files all land on you.

A tool connects to Stripe, reads the same events and runs the ledger, and those steps are the checklist for judging one: how it finds the affiliate on a renewal, what it pays on, and what it does with a partial refund.

Entry plans differ on what they cap and how they pay.

ToolEntry plan, monthly priceWhat the entry plan capsPayouts
RewardfulStarter, $49$7,500/month of affiliate-attributed revenue, 1 campaignPayPal and Wise mass payouts; Managed Payouts optional at 3%
FirstPromoterStarter, $49$5,000/month of affiliate revenue, 1,000 affiliatesMass payouts through PayPal, Wise, Stripe, crypto and bank transfer
ToltBasic, $69$10,000/month earned through affiliatesManual payouts on Basic; auto payouts from Growth at $99
PromoteKitPro, from $29 (yearly toggle shown); free plan covers 3 referrals$10,000/month from affiliatesOne-click global payouts on Pro
TrackRevStarter, $39$10,000 of commission tracked monthly, 1 workspaceWise or PayPal CSV export, then mark paid

Prices from each vendor's pricing page, October 2026. Rewardful, FirstPromoter and Tolt each offer a 14-day trial.

Caps are measured differently. The first four cap affiliate-driven revenue; TrackRev caps the commission it tracks, so at a 20% rate $10,000 of commission corresponds to $50,000 of affiliate revenue.

The full comparison is in best affiliate software for Stripe in 2026.

How TrackRev handles the Stripe side

TrackRev connects with a restricted Stripe key and syncs paid charges hourly; an optional webhook cuts the delay to seconds. It never writes metadata onto your customers or subscriptions, which removes step 4.

Its pixel sets a first-party visitor ID and adds it as client_reference_id to Payment Links, Buy Buttons and pricing tables on your pages; for Checkout Sessions you create, pass it as client_reference_id or metadata.vid.

Without either, it matches the customer's email, and renewals inherit the affiliate from the first charge on the subscription.

Per program you set a percentage or flat amount, first sale only or renewals too, a 60-day click window by default, a hold of 0 to 180 days (default 0) and a payout schedule from weekly to quarterly.

Paying means exporting a PayPal or Wise CSV and marking each payout paid.

Against the build above, TrackRev reads charges, so the base is the charge amount, including any tax Stripe collected. Any refund, partial ones too, reverses that charge's whole commission with no proration. The program needs a paid plan.

TrackRev planMonthly priceCommission tracked monthlyWorkspaces
Free$0None; link tracking only, with 50 links and 1,000 events1
Starter$39Up to $10,0001
Growth$99Up to $100,000Unlimited
Scale$199UnlimitedUnlimited

Annual billing charges for 9 months and gives 12.

Pick Tolt (Growth, $99) when automatic payouts with 1099 filing matter more than the entry price, PromoteKit when Stripe is your only billing system and price decides it, and TrackRev when the affiliate program should sit beside link tracking and channel attribution on one data model.

The affiliate program page lists what partners see in their portal.

Found this useful? Share it.

PostLinkedIn

Frequently asked questions

Muzahid Maruf — Founder of TrackRev.io

Written by

Muzahid Maruf

Founder, TrackRev.io & Contant.io

Muzahid Maruf is the founder of TrackRev.io and Contant.io. He writes about marketing attribution, link tracking, and revenue analytics for SaaS teams.

Writes about Marketing attribution · Link tracking · Revenue analytics · SaaS growth

Stop guessing where your revenue comes from.

Set up TrackRev in about five minutes. The free plan covers 1,000 events a month, no card needed.

Start free