Affihub
DocsIntegration GuidesPaddle Integration

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:

  1. Go to Developer Tools → Notifications
  2. Click New destination
  3. Enter the URL:
https://api.affihub.com/webhooks/paddle?program_id=YOUR_PROGRAM_ID
  1. Select these event types:

    • transaction.completed
    • subscription.canceled
    • adjustment.updated
  2. Save the destination

  3. Copy the Webhook Secret Key

Step 2: Save the webhook secret

In your Affihub provider dashboard:

  1. Go to Settings
  2. Paste the secret into the Paddle Webhook Secret field
  3. 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:

  1. Verifies the Paddle signature (HMAC-SHA256)
  2. Reads custom_data.affihub_ref from the transaction
  3. Looks up the partner by slug in your program
  4. Evaluates your commission flow rules
  5. 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_HASH

Affihub verifies this by:

  1. Extracting the timestamp and hash
  2. Computing HMAC-SHA256 of timestamp:request_body using your webhook secret
  3. 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:

  1. Set up the webhook destination with your sandbox credentials
  2. Create a test partner in Affihub
  3. Complete a sandbox checkout with affihub_ref set to your test partner's slug
  4. Verify the commission appears in your Affihub dashboard
⚠️

Use separate webhook secrets for sandbox and production environments.