Integrations

Paddle revenue attribution with checkout custom data

Paddle Billing can carry analytics IDs alongside a transaction. Connect its signed notifications and pass custom data at checkout to connect an acquisition source to the money actually collected.

Before you connect

Install the tracker on your verified website and confirm the first event. Open that site’s Settings → Revenue as a workspace owner or admin, choose Paddle Billing, and copy the webhook URL shown there. Your deployment’s settings are the authority for its origin.

Configure the webhook

  1. In Paddle → Events → Notifications, create a new notification destination (older dashboards may group Notifications under Developer tools). Use the sandbox account for initial testing. This integration supports Paddle Billing; Paddle Classic uses a different contract.
  2. For hosted tracking, the endpoint has this form:
    https://t.analyticfast.com/api/webhooks/paddle/YOUR_SITE_ID
    Replace YOUR_SITE_ID with this site’s ID; use the exact URL from Settings if its origin differs.
  3. Subscribe to these events:
    • transaction.completed
    • adjustment.created
    • adjustment.updated
  4. Copy the destination’s endpoint secret key exactly as provided and save it in AnalyticFast. The receiver checks Paddle-Signature against the raw body and uses a five-second timestamp tolerance. A signature error is a reason to inspect delivery and timing, not to remove verification.
  5. Save. Optionally enter product IDs to filter transactions. A matching product includes the entire transaction, so a filter is not product-level revenue allocation.
Screenshot placeholder: Paddle Billing webhook destination with the site URL and required events selected; hide all signing secrets.

Carry the visitor into checkout

Pass the optional IDs in customData when calling Paddle.Checkout.open, or in custom_data on a server-created transaction. Merge with your application’s existing custom fields. Paddle copies transaction custom data to a resulting subscription and subscription custom data to later transactions. See Paddle’s custom-data guide.

// Browser: read IDs immediately before asking your server to create checkout.
const attribution = window.analyticfast?.attribution?.() ?? {};
// Send these optional IDs with your existing checkout request.
// Server: validate them and copy only the present values into provider metadata.
// Keep prices, products and all payment credentials under server control.
// Add to your existing Paddle.Checkout.open options.
// Include only attribution IDs that are present.
customData: { ml_visitor_id, ml_session_id }
// Server API equivalent:
custom_data: { ml_visitor_id, ml_session_id }

Do not add made-up metadata query parameters to a hosted checkout URL. Your existing checkout configuration still supplies the items and prices.

What creates revenue and refunds

A completed transaction is keyed by its transaction ID. Earlier transaction.paid notifications do not create revenue in this integration. Recurring transactions are recognized from origin=subscription_recurring. Only approved adjustments whose action is refund subtract revenue; credits and adjustments awaiting approval do not. Both partial and full refunds refer back to the original transaction.

Verify with a real signed test delivery

  1. On your separate test site, arrive with a unique UTM campaign and complete a sandbox payment through your actual checkout flow.
  2. Inspect the provider’s delivery log, then check the payment, its currency and its attributed visit in AnalyticFast. Test mode data should stay out of your production analytics site.
  3. Retry the same delivery and confirm no duplicate revenue. Issue a successful partial or full refund and confirm the net amount falls once. For subscriptions, test a later renewal.

The settings test button is a local parser preview. It does not contact Paddle Billing, verify signatures over the network or persist revenue.

Limits to check before going live

There is no automatic arbitrary-metadata tagging of plain Paddle hosted links. Use Paddle.js customData, data-custom-data, or API custom_data. Product filters include the whole transaction when any delivered product matches; they do not split mixed-cart revenue between products.

No universal historical import runs when you save a webhook. Validate new deliveries first. Keep currencies separate and compare like date ranges; an analytics revenue total is not a bank payout statement.

Official references

Setup reviewed against the current adapter and official documentation on October 31, 2026. This is an implementation guide, not a claim that a live checkout was exercised.

Add your website to AnalyticFast, then open Settings → Revenue to copy its webhook URL.

Questions, answered.

Does this integration work with Paddle Classic?

No. The current receiver expects Paddle Billing notifications and Paddle-Signature. Classic has a different event and signature contract. Do not point Classic notifications at this endpoint and assume that they will be recorded.

Does the test button send a real payment?

No. It is a local parser preview: it contacts no provider, verifies no signed delivery, and records no revenue. Use a separate AnalyticFast test site and your provider sandbox to check payment, renewal, retry and refund delivery.

Do I need to expose payment credentials in my website?

No. The Site ID is public. Webhook signing secrets belong in the Revenue settings, and payment API keys belong on your server. Only optional visitor and session IDs travel from the browser to your checkout code.