Stripe Webhook Integration
Connect Stripe to Attro for automatic conversion tracking. Step-by-step webhook setup with code examples.
Prerequisites
- Stripe account with checkout or payment links
- Attro organization created
- Access to Stripe Dashboard webhooks section
Stripe integration is the backbone of Attro's conversion tracking for web purchases. When a customer completes a payment through an affiliate link, Attro automatically records the conversion and calculates commissions - no manual work required.
This guide covers the complete Stripe setup, including webhook configuration, attribution passing, and handling different payment scenarios like subscriptions.
How It Works
- Customer clicks an affiliate's tracking link
- Attro sets a first-party cookie with the click ID
- Customer completes purchase on your site
- Stripe sends a webhook event to Attro
- Attro matches the click ID and records the conversion
- Commission is calculated based on your offer settings
Why webhooks? Webhooks provide real-time, server-to-server communication. Unlike client-side tracking, they can't be blocked by ad blockers and are more reliable.
Create Webhook Endpoint in Stripe
First, you'll add Attro's webhook URL to your Stripe account.
Navigate to Webhooks
- Log into your Stripe Dashboard
- Click "Developers" in the left sidebar
- Select "Webhooks"
- Click "Add endpoint"
Configure the Endpoint
Enter the following details:
Endpoint URL:
https://get-attro.com/api/webhooks/stripeEvents to subscribe:
checkout.session.completed- For Stripe Checkout purchasesinvoice.paid- For subscription renewalscharge.succeeded- For direct charges
Select Your Events
- Click "Select events"
- Search for each event name
- Check the checkbox next to each
- Click "Add events"
- Click "Add endpoint" to save
Tip: Start with checkout.session.completed if you're using Stripe Checkout. Add the others as needed for your payment flows.
Configure Webhook Secret
The webhook signing secret allows Attro to verify that events genuinely come from Stripe, not a malicious third party.
Get Your Signing Secret
- In Stripe Webhooks, click on your new endpoint
- Find "Signing secret" in the endpoint details
- Click "Reveal" to show the secret
- Copy the value (starts with whsec_)
Add to Attro
- In Attro, go to Settings → Integrations
- Find the Stripe section
- Paste your signing secret
- Click "Save"
# Your signing secret looks like this:
whsec_1234567890abcdefghijklmnopqrstuvwxyz
# Never commit this to your code repository!Security: The signing secret should be kept confidential. Attro stores it encrypted and uses it only for webhook verification.
Pass Affiliate Attribution in Metadata
For Attro to attribute a conversion to the correct affiliate, you need to pass the click ID from the tracking cookie to Stripe.
Option 1: Stripe Checkout Session
When creating a Checkout Session, include the click ID in metadata:
// Server-side: Creating a Stripe Checkout Session
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
app.post('/create-checkout', async (req, res) => {
// Get the click ID from the request (passed from client)
const { clickId } = req.body;
const session = await stripe.checkout.sessions.create({
line_items: [
{
price: 'price_1234567890',
quantity: 1,
},
],
mode: 'subscription', // or 'payment' for one-time
success_url: 'https://yourapp.com/success',
cancel_url: 'https://yourapp.com/cancel',
// Pass attribution data in metadata
metadata: {
rd_click_id: clickId || '',
},
// For subscriptions, also add to subscription_data
subscription_data: {
metadata: {
rd_click_id: clickId || '',
},
},
});
res.json({ url: session.url });
});Option 2: Payment Links
If using Stripe Payment Links, you can pass the click ID as a URL parameter:
// Construct payment link with client_reference_id
const paymentLinkUrl = 'https://buy.stripe.com/your_link_id';
const clickId = getAttroClickId(); // Function defined below
const urlWithAttribution = `${paymentLinkUrl}?client_reference_id=${clickId}`;
// Redirect customer to this URL
window.location.href = urlWithAttribution;Option 3: Direct Charges
For PaymentIntent or direct charges:
const paymentIntent = await stripe.paymentIntents.create({
amount: 9900,
currency: 'usd',
metadata: {
rd_click_id: clickId,
},
});Read the Click ID from Cookie
When users click affiliate tracking links, Attro sets a first-party cookie. Here's how to read it on your site.
JavaScript (Browser)
// Get Attro click ID from cookie
function getAttroClickId() {
const cookies = document.cookie.split(';');
for (const cookie of cookies) {
const [name, value] = cookie.trim().split('=');
if (name === 'rd_click_id') {
return decodeURIComponent(value);
}
}
return null;
}
// Usage: Pass to your checkout API
const clickId = getAttroClickId();
if (clickId) {
// Include in your checkout request
fetch('/create-checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ clickId }),
});
}React Hook
import { useEffect, useState } from 'react';
function useAttroClickId() {
const [clickId, setClickId] = useState<string | null>(null);
useEffect(() => {
const cookies = document.cookie.split(';');
for (const cookie of cookies) {
const [name, value] = cookie.trim().split('=');
if (name === 'rd_click_id') {
setClickId(decodeURIComponent(value));
break;
}
}
}, []);
return clickId;
}
// Usage in component
function CheckoutButton() {
const clickId = useAttroClickId();
const handleCheckout = async () => {
const response = await fetch('/api/checkout', {
method: 'POST',
body: JSON.stringify({ clickId }),
});
// ... handle response
};
return <button onClick={handleCheckout}>Checkout</button>;
}Server-Side (Next.js)
// pages/api/checkout.ts or app/api/checkout/route.ts
import { cookies } from 'next/headers';
export async function POST(request: Request) {
const cookieStore = await cookies();
const clickId = cookieStore.get('rd_click_id')?.value;
// Use clickId when creating Stripe session
const session = await stripe.checkout.sessions.create({
// ...
metadata: {
rd_click_id: clickId || '',
},
});
return Response.json({ url: session.url });
}Verify Webhook Connection
Test that your webhook integration is working correctly before going live.
Stripe CLI Testing (Development)
Use the Stripe CLI to forward webhooks to your local environment:
# Install Stripe CLI
brew install stripe/stripe-cli/stripe
# Login to your Stripe account
stripe login
# Forward webhooks to local
stripe listen --forward-to localhost:3000/api/webhooks/stripe
# The CLI will show you a webhook signing secret for testing
# Use this in your local environment
# In another terminal, trigger a test event
stripe trigger checkout.session.completedProduction Testing
- Click an affiliate tracking link (use incognito mode)
- Complete a purchase using Stripe test mode
- Check Attro admin → Conversions
- Verify the conversion shows with correct affiliate
Check Webhook Logs
In Stripe Dashboard → Webhooks → Your endpoint, you can see:
- Recent webhook deliveries
- Response status codes
- Request/response bodies
- Retry attempts for failed deliveries
Troubleshooting: If webhooks fail, check: 1) Signing secret matches, 2) Endpoint URL is correct, 3) Your server returns 200 status.
Handle Recurring Payments
For subscription products, you'll want to track both initial purchases and renewals.
Commission on Initial Purchase
The checkout.session.completed event fires when a customer first subscribes. This captures the initial conversion.
Commission on Renewals
The invoice.paid event fires on each renewal. To track these:
- Ensure you added rd_click_id to subscription_data.metadata
- Subscribe to invoice.paid events
- Configure recurring commissions in your offer settings
Offer Settings for Subscriptions
In Attro, configure how recurring commissions work:
- First Payment Only - Commission on initial purchase only
- Lifetime - Commission on every renewal forever
- Fixed Period - Commission for a set number of months (e.g., 12)
// Example: $99/month subscription, 20% commission, 12-month recurring
// Month 1 (initial): $99 × 20% = $19.80 commission
// Month 2-12 (renewals): $99 × 20% = $19.80 each
// Month 13+: No commission (exceeded 12-month period)
// Total potential commission: $19.80 × 12 = $237.60Handling Upgrades & Downgrades
Subscription changes (upgrades, downgrades) trigger new invoice.paid events. The commission is calculated on the prorated amount or new price, depending on your Stripe configuration.
Integration Complete
Your Stripe integration is now configured for automatic conversion tracking. Every purchase that includes a valid click ID will be attributed to the correct affiliate.
Quick Reference
- Webhook URL:
https://get-attro.com/api/webhooks/stripe - Cookie Name:
rd_click_id - Metadata Key:
rd_click_id
Next Steps
- Commission Structures - Set up tiered rates for top performers
- iOS SDK Integration - Track mobile app purchases
- Fraud Detection - Protect your program from abuse
Questions? Contact us at [email protected].
Related guides
Zapier & Webhook Automations
Automate your affiliate workflow with Zapier or custom webhooks. Trigger actions on signups, conversions, payouts, and more.
White-Label Portal Setup
Give affiliates a branded experience with your own domain, logo, and colors. The white-label portal appears as part of your product.
Need help with integration?
Our support team is here to help you get set up.