Skip to content

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:year

Format 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):

ProductPriceBilling cycleTax mode
Startermonthly1 monthexclusive
Starteryearly1 yearexclusive
Promonthly1 monthexclusive
Proyearly1 yearexclusive
Teammonthly1 monthexclusive
Teamyearly1 yearexclusive

Copy each pri_... ID into RD_PADDLE_PRICES.

3. Webhook (notification destination) ​

  1. Expose the local server: cloudflared tunnel --url http://localhost:3000 (or ngrok).
  2. Paddle sandbox > Developer Tools > Notifications > New destination.
    • Type: webhook
    • URL: https://<tunnel-host>/webhooks/paddle
    • API version: 1
    • Events: see below
  3. Save, then copy the endpoint secret key (pdl_ntfset_...) into RD_PADDLE_WEBHOOK_SECRET.
  4. Restart the server.

Events to select ​

The handler only acts on subscription.* events and ignores the rest. Select:

  • subscription.created
  • subscription.activated
  • subscription.updated
  • subscription.past_due
  • subscription.paused
  • subscription.resumed
  • subscription.canceled
  • subscription.trialing (only if you use trials)

Not needed: transaction, customer, address, business, adjustment, payout events.

How it behaves ​

  • Signature checked via the Paddle-Signature header 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 no orgId and are ignored.

4. Test ​

  1. Start the app and tunnel; open Settings > Plan and start checkout as an org owner.
  2. Pay with test card 4242 4242 4242 4242, any future expiry, CVC 100.
  3. Check Paddle > Notifications > Logs for 2xx responses, and that the org plan updates.
  4. Replay or simulate events from Notifications > Simulations.