Paddle Integration
Overview
The Paddle integration connects your Paddle Billing account to Affihub via webhooks. When a referred customer completes a transaction, Affihub creates a commission for the referring partner.
Prerequisites
- Affihub tracking script installed on your site
- A Paddle account (Paddle Billing, not Paddle Classic)
- Your Affihub Program ID (from Settings & Keys)
Step 1: Create the webhook notification
In your Paddle Dashboard:
- Go to Developer Tools → Notifications
- Click New destination
- Enter the URL:
https://api.affihub.com/webhooks/paddle?program_id=YOUR_PROGRAM_ID-
Select these event types:
transaction.completedsubscription.canceledadjustment.updated
-
Save the destination
-
Copy the Webhook Secret Key
Step 2: Save the webhook secret
In your Affihub provider dashboard:
- Go to Settings
- Paste the secret into the Paddle Webhook Secret field
- Save
Affihub uses this secret to verify the Paddle-Signature header on incoming webhooks.
Step 3: Pass the referral at checkout
When opening Paddle Checkout, include the referral data in customData:
Paddle.Checkout.open({
items: [
{
priceId: "pri_xxx",
quantity: 1,
},
],
customData: {
affihub_program: "YOUR_PROGRAM_ID",
affihub_ref: window.AffiHub.getRef()?.ref || "",
},
});Using Paddle.js inline checkout
const ref = window.AffiHub.getRef();
Paddle.Checkout.open({
settings: {
displayMode: "inline",
frameTarget: "checkout-container",
frameInitialHeight: 450,
},
items: [{ priceId: "pri_xxx", quantity: 1 }],
customData: {
affihub_program: "YOUR_PROGRAM_ID",
affihub_ref: ref?.ref || "",
},
});Server-side transaction creation
If you create transactions via the Paddle API:
const response = await fetch("https://api.paddle.com/transactions", {
method: "POST",
headers: {
Authorization: `Bearer ${PADDLE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
items: [{ price_id: "pri_xxx", quantity: 1 }],
custom_data: {
affihub_program: "YOUR_PROGRAM_ID",
affihub_ref: "partner-slug",
},
}),
});How attribution works
When Affihub receives a transaction.completed webhook:
- Verifies the Paddle signature (HMAC-SHA256)
- Reads
custom_data.affihub_reffrom the transaction - Looks up the partner by slug in your program
- Evaluates your commission flow rules
- Creates a commission record
Handled event types
| Event | What Affihub does |
|---|---|
transaction.completed |
Creates a new commission (status: pending) |
subscription.canceled |
Flags related commission for review (status: review) |
adjustment.updated |
Recalculates commission for refunds/adjustments |
Signature verification
Paddle signs webhooks using the Paddle-Signature header. The format is:
ts=TIMESTAMP;h1=HMAC_HASHAffihub verifies this by:
- Extracting the timestamp and hash
- Computing HMAC-SHA256 of
timestamp:request_bodyusing your webhook secret - Comparing the computed hash with the provided hash
If verification fails, the webhook is rejected with a 401 response.
Testing
Paddle's sandbox environment sends webhooks to your configured URL. To test:
- Set up the webhook destination with your sandbox credentials
- Create a test partner in Affihub
- Complete a sandbox checkout with
affihub_refset to your test partner's slug - Verify the commission appears in your Affihub dashboard
Use separate webhook secrets for sandbox and production environments.