GrowthRailDocs
Prerequisites
  • A Paddle Billing account (sandbox for testing, production for live).
  • A product and price created in Paddle Catalog.
  • A Default payment link configured in Paddle → Checkout → Checkout Settings (required at the account level for Paddle.Checkout.open to work).

Webhook events

EventWhat it signalsGrowth Rail action
transaction.completedPaddle has captured payment and the transaction status is completed.Record purchase proof; join to pending SDK attribution claim.

How attribution works

A verified provider event proves the purchase happened — but not that the user was referred. Growth Rail completes a referral only when that event joins to the opaque attribution claim previously captured by the SDK on the referring user's device.

Identity rule: Growth Rail joins events to claims using stable IDs and opaque tokens. It never correlates users by email, name, phone number, or billing address.
1

Create the Growth Rail connection

Open Dashboard → Integrations → Purchases, choose Paddle, and create a Sandbox or Production connection. Copy the generated webhook endpoint URL — you will paste it into Paddle in the next step.

2

Register the webhook in Paddle

In Paddle → Developer tools → Notifications, add the copied endpoint and subscribe to transaction.completed.

Return to Growth Rail and save the Paddle notification destination secret. Growth Rail encrypts and stores it — the raw value is never returned by the API after saving.

Security: Never commit webhook secrets to source control or log them. If a secret is compromised, rotate it in both Paddle and Growth Rail immediately.
3

Pass attribution data from your app

Pass gr_attribution (the opaque SDK token) and gr_user_id (your stable app user ID) in Paddle customData. Growth Rail reads these from the webhook and joins them to the pending SDK claim.

ts
Paddle.Initialize({ token: clientToken });

Paddle.Checkout.open({
  items: [{ priceId, quantity: 1 }],
  customData: {
    gr_attribution: GrowthRail.getAttributionToken(),
    gr_user_id: currentUser.id,
  },
  settings: {
    successUrl: window.location.href, // required — avoids checkout validation error
  },
});
4

Verify end-to-end in test mode

Use a Paddle sandbox account. Complete a checkout with test card 4242 4242 4242 4242 (exp 12/26, CVC 100). Verify the transaction.completed delivery appears in Paddle → Developer tools → Notifications log, then check Growth Rail for the outcome.

OutcomeMeaning
CompletedPurchase proof and SDK attribution token matched. The referral reward has been triggered.
Awaiting attributionThe webhook signature was valid, but the SDK claim has not arrived yet — or the stable user ID did not match a pending claim. The event is held; Growth Rail completes the referral when the claim arrives.
IgnoredThe event was verified but no matching attribution claim exists and the hold window has expired, or the event type is out of scope.
Provider-specific notes
  • Do not treat checkout.loaded or a browser success redirect as payment proof. Growth Rail only acts on the server-side transaction.completed webhook.
  • Paddle.Checkout.open() requires either a Default payment link set in Paddle → Checkout → Checkout Settings, or successUrl in the settings object — omitting both throws a transaction_default_checkout_url_not_set validation error.
  • Use a separate Notification destination and Growth Rail connection for Paddle live mode vs. sandbox.
  • Refund and chargeback events do not automatically reverse issued rewards in the current version.