Paddle
Attribute completed Paddle Billing transactions using customData — no backend required for the attribution handoff.
- 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
| Event | What it signals | Growth Rail action |
|---|---|---|
transaction.completed | Paddle 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.
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.
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.
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.
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
},
});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.
| Outcome | Meaning |
|---|---|
| Completed | Purchase proof and SDK attribution token matched. The referral reward has been triggered. |
| Awaiting attribution | The 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. |
| Ignored | The event was verified but no matching attribution claim exists and the hold window has expired, or the event type is out of scope. |
- 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.