Custom Payment Provider Integration
This guide shows you how to integrate Affonso with any payment provider (Lemon Squeezy, Gumroad, Razorpay, Paystack, or others) using our REST API. This approach gives you full control over commission tracking.
Note: With custom integrations, you calculate and submit commission amounts manually. Commission rates configured in Affonso settings won't be applied automatically.
Prerequisites
Before starting, make sure you have:
- Affonso tracking script installed on your website
- API key from your Affonso dashboard
Integration Overview
Install Tracking Script
Add the Affonso tracking script to your website's <head> tag:
<!-- Place in <head> tag -->
<script
async
defer
src="https://cdn.affonso.io/js/pixel.min.js"
data-affonso="YOUR_PUBLIC_PROGRAM_ID"
data-cookie_duration="YOUR_COOKIE_DURATION"
></script>Configuration:
- Replace
YOUR_PUBLIC_PROGRAM_IDwith your program ID from the Affonso dashboard - Set
YOUR_COOKIE_DURATIONto how many days the tracking should persist
This script creates a cookie named affonso_referral containing the referral ID when a visitor arrives via an affiliate link.
Track User Signups (Optional but Recommended)
Add signup tracking after user registration:
// After successful user registration
window.Affonso.signup(userEmail);Why track signups?
- See which affiliates drive the most registrations
- Calculate conversion rates from clicks to signups
- Optimize your funnel based on affiliate performance
Pass Referral ID to Your Payment Provider
When creating a checkout or payment, pass the affonso_referral cookie value to your payment provider's metadata/custom data field.
Frontend (Client-side):
// Get referral ID from window object or cookie
const referralId = window.affonso_referral;
// Pass to your payment provider
createCheckout({
// ... your payment config
metadata: {
affonso_referral: referralId
}
});Backend (Server-side):
// Node.js / Express example
const referralId = req.cookies['affonso_referral'] || '';
// Pass to your payment provider's API
const checkout = await paymentProvider.createCheckout({
// ... your config
metadata: {
affonso_referral: referralId
}
});Provider-Specific Metadata Fields
| Provider | Metadata Field |
|---|---|
| Lemon Squeezy | custom_data or checkout_data.custom |
| Gumroad | custom_fields |
| Razorpay | notes |
| Paystack | metadata |
| Xendit | metadata |
| Flutterwave | meta |
Handle Webhooks & Create Commissions
When your payment provider sends a webhook event (e.g., payment.successful, order.completed), follow these steps:
4.1 Extract the Referral ID
// Example webhook handler
app.post('/webhooks/payment', async (req, res) => {
const event = req.body;
// Extract referral ID from metadata (adjust based on your provider)
const referralId = event.data.metadata?.affonso_referral;
// If no referral ID, this wasn't an affiliate sale
if (!referralId) {
return res.json({ received: true });
}
// Continue with affiliate tracking...
});4.2 Update the Referral
Update the referral with customer information and status:
curl -X PUT "https://api.affonso.io/v1/referrals/{referralId}" \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"email": "customer@example.com",
"customer_id": "cust_123",
"status": "customer",
"name": "John Doe"
}'Available status values:
lead- Initial click, no conversion yettrialing- Customer started a trialcustomer- Paid customeractive- Active subscriptioncanceled- Canceled subscriptionrejected- Rejected referral
4.3 Create the Commission
Create a commission record with the sale and commission amounts:
curl -X POST "https://api.affonso.io/v1/commissions" \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"referral_id": "{referralId}",
"sale_amount": 99.00,
"commission_amount": 19.80,
"sale_amount_currency": "USD",
"commission_currency": "USD",
"payment_intent_id": "pi_unique_payment_id",
"is_subscription": false,
"sales_status": "complete"
}'Important parameters:
| Parameter | Description |
|---|---|
referral_id | The referral ID from the metadata |
sale_amount | Total transaction amount (not commission) |
commission_amount | Commission to pay the affiliate (you calculate this) |
payment_intent_id | Unique payment ID to prevent duplicates |
is_subscription | Set true for recurring payments |
sales_status | complete, trialing, open, failed, refunded, partial_refunded |
Handle Refunds & Updates
When a refund occurs, update the commission accordingly:
Full Refund
curl -X PUT "https://api.affonso.io/v1/commissions/{commissionId}" \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"sale_amount": 0,
"commission_amount": 0,
"sales_status": "refunded"
}'Partial Refund
curl -X PUT "https://api.affonso.io/v1/commissions/{commissionId}" \
-H "Authorization: Bearer sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"sale_amount": 49.50,
"commission_amount": 9.90,
"sales_status": "partial_refunded"
}'Complete Code Example
Here's a full webhook handler example in Node.js/Express:
import express from 'express';
const app = express();
const AFFONSO_API_KEY = process.env.AFFONSO_API_KEY;
app.post('/webhooks/payment', async (req, res) => {
const event = req.body;
try {
// Adjust this based on your payment provider's event structure
if (event.type === 'payment.completed') {
const referralId = event.data.metadata?.affonso_referral;
if (!referralId) {
return res.json({ received: true });
}
const saleAmount = event.data.amount;
const commissionRate = 0.20; // 20% commission
const commissionAmount = saleAmount * commissionRate;
// Update referral status
await fetch(`https://api.affonso.io/v1/referrals/${referralId}`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${AFFONSO_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: event.data.customer_email,
customer_id: event.data.customer_id,
status: 'customer'
})
});
// Create commission
await fetch('https://api.affonso.io/v1/commissions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${AFFONSO_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
referral_id: referralId,
sale_amount: saleAmount,
commission_amount: commissionAmount,
sale_amount_currency: event.data.currency || 'USD',
commission_currency: event.data.currency || 'USD',
payment_intent_id: event.data.payment_id,
sales_status: 'complete'
})
});
}
// Handle refunds
if (event.type === 'payment.refunded') {
const commissionId = event.data.metadata?.affonso_commission_id;
if (commissionId) {
await fetch(`https://api.affonso.io/v1/commissions/${commissionId}`, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${AFFONSO_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
sale_amount: 0,
commission_amount: 0,
sales_status: 'refunded'
})
});
}
}
res.json({ received: true });
} catch (error) {
console.error('Webhook error:', error);
res.status(500).json({ error: 'Webhook processing failed' });
}
});Testing Your Integration
- Visit your site with
?atp=test(our test affiliate parameter) - Check browser DevTools → Application → Cookies → look for
affonso_referral - Complete a test purchase
- Verify in your server logs that the referral ID is present in the webhook payload
- Check your Affonso dashboard for the new referral and commission
API Reference
For complete API documentation, see:
- Referrals API - Create and update referrals
- Commissions API - Create and manage commissions
Need help? Contact our support team - we typically respond within 2 hours during business hours.


