Stripe Integration
Overview
The Stripe integration connects your Stripe account to Affihub via webhooks. When a referred customer completes a checkout session or pays an invoice, Affihub automatically creates a commission for the referring partner.
Prerequisites
- Affihub tracking script installed on your site
- A Stripe account with Checkout or Billing enabled
- Your Affihub Program ID and API Key (from Settings & Keys)
Step 1: Create the webhook endpoint
In your Stripe Dashboard:
- Go to Developers → Webhooks
- Click Add endpoint
- Enter the URL:
https://api.affihub.com/webhooks/stripe?program_id=YOUR_PROGRAM_ID-
Under Events to send, select:
checkout.session.completedinvoice.paid
-
Click Add endpoint
-
Copy the Signing Secret (starts with
whsec_)
Step 2: Save the signing secret
In your Affihub provider dashboard:
- Go to Settings
- Paste the signing secret into the Stripe Webhook Secret field
- Save
This allows Affihub to verify that incoming webhooks are genuinely from Stripe.
Step 3: Pass the referral at checkout
When creating a Stripe Checkout Session, include the partner's referral slug:
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
app.post("/create-checkout", async (req, res) => {
const session = await stripe.checkout.sessions.create({
mode: "payment",
line_items: [
{
price: "price_xxx",
quantity: 1,
},
],
success_url: "https://yoursite.com/success",
cancel_url: "https://yoursite.com/cancel",
// Pass the Affihub referral
client_reference_id: req.body.affihub_ref || undefined,
});
res.json({ url: session.url });
});On the frontend, read the referral from the tracking script:
const ref = window.AffiHub.getRef();
fetch("/create-checkout", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
affihub_ref: ref?.ref || "",
}),
});Using metadata instead of client_reference_id
If you're already using client_reference_id for something else, you can pass the referral in metadata:
const session = await stripe.checkout.sessions.create({
// ...
metadata: {
affihub_ref: req.body.affihub_ref || "",
},
});Affihub checks both client_reference_id and metadata.affihub_ref when processing webhooks.
Step 4: Subscriptions and invoices
For subscription-based products, Affihub also listens for invoice.paid events. To attribute subscription renewals:
const subscription = await stripe.subscriptions.create({
customer: customerId,
items: [{ price: "price_xxx" }],
metadata: {
affihub_ref: req.body.affihub_ref || "",
},
});When an invoice is paid, Affihub extracts the referral from:
- The subscription's
metadata.affihub_ref - The invoice line item metadata
Set the affihub_ref metadata on the subscription at creation time. All future invoices will carry the attribution.
How attribution works
When Affihub receives a checkout.session.completed webhook:
- Verifies the Stripe signature using your webhook secret
- Reads
client_reference_idormetadata.affihub_ref - Looks up the partner by slug in your program
- Evaluates your commission flow rules to determine the rate
- Creates a commission with:
txn_amount_cents: The total payment amountamount_cents: The calculated commissionstatus:pendingprovider:stripeprovider_event_id: The Stripe event ID (for deduplication)
Deduplication
Each Stripe event has a unique ID (e.g., evt_xxx). Affihub stores this as provider_event_id and checks for duplicates before creating a commission. If Stripe retries a webhook delivery, no duplicate commission is created.
Testing with Stripe test mode
Stripe test mode webhooks work with Affihub. To test:
- Set up the webhook endpoint as described above (Stripe sends test events to the same URL)
- Create a test partner with slug
test-partner - Use Stripe's test card (
4242 4242 4242 4242) to complete a checkout withclient_reference_id: "test-partner" - Check your Affihub dashboard for the new commission
Remember to use your live webhook signing secret when switching to production. Test and live secrets are different.
Stripe Connect for payouts
Affihub can pay partners directly via Stripe Connect. See Payouts for setup details.