Appearance
Paddle local setup (sandbox)
1. Env
RD_PADDLE_API_KEY=pdl_sdbx_... # sandbox key
RD_PADDLE_WEBHOOK_SECRET=pdl_ntfset_... # from step 3
RD_PADDLE_ENV=sandbox
RD_PADDLE_PRICES=pri_s:starter:month,pri_t:starter:year,pri_a:pro:month,pri_b:pro:year,pri_c:team:month,pri_d:team:yearFormat of RD_PADDLE_PRICES: priceId:plan:interval, comma separated. Plan is starter, pro or team. Set a 7-day trial period on each price. Price IDs not listed here are ignored by the webhook handler.
2. Products and prices
Create in the sandbox (Catalog > Products, or via the Paddle MCP):
| Product | Price | Billing cycle | Tax mode |
|---|---|---|---|
| Starter | monthly | 1 month | exclusive |
| Starter | yearly | 1 year | exclusive |
| Pro | monthly | 1 month | exclusive |
| Pro | yearly | 1 year | exclusive |
| Team | monthly | 1 month | exclusive |
| Team | yearly | 1 year | exclusive |
Copy each pri_... ID into RD_PADDLE_PRICES.
3. Webhook (notification destination)
- Expose the local server:
cloudflared tunnel --url http://localhost:3000(or ngrok). - Paddle sandbox > Developer Tools > Notifications > New destination.
- Type: webhook
- URL:
https://<tunnel-host>/webhooks/paddle - API version: 1
- Events: see below
- Save, then copy the endpoint secret key (
pdl_ntfset_...) intoRD_PADDLE_WEBHOOK_SECRET. - Restart the server.
Events to select
The handler only acts on subscription.* events and ignores the rest. Select:
subscription.createdsubscription.activatedsubscription.updatedsubscription.past_duesubscription.pausedsubscription.resumedsubscription.canceledsubscription.trialing(only if you use trials)
Not needed: transaction, customer, address, business, adjustment, payout events.
How it behaves
- Signature checked via the
Paddle-Signatureheader against the raw body; invalid returns 401. - Idempotent on
event_id; duplicates return without reapplying. - Out-of-order events older than the stored subscription are ignored.
- The org is matched through
custom_data.orgId, set when ReleaseDesk creates the checkout. Subscriptions created manually in the Paddle dashboard carry noorgIdand are ignored.
4. Test
- Start the app and tunnel; open Settings > Plan and start checkout as an org owner.
- Pay with test card
4242 4242 4242 4242, any future expiry, CVC100. - Check Paddle > Notifications > Logs for 2xx responses, and that the org plan updates.
- Replay or simulate events from Notifications > Simulations.