Receive notifications by making sure your webhook event server is configured correctly, and responding within five seconds.
AI summary
This guide shows developers how to configure a webhook handler so Paddle notifications are received reliably, acknowledged within five seconds, and retried correctly when delivery fails.
โขRespond with HTTP 200 within five seconds, before any internal processing, and queue events for asynchronous handling.
โขAllow Paddle's sandbox and live webhook IP addresses separately, and configure WAF rules to bypass bot checks on webhook paths.
โขLive accounts get up to 60 retry attempts over about two days, while sandbox accounts get 3 attempts within about two minutes; use the occurred_at field to handle out-of-order delivery and verify signatures with the Paddle-Signature header.
Once you've created a notification destination, you should properly handle webhook delivery. This includes making sure your webhook server is configured correctly, responding to notifications promptly, and handling retries.
You should make sure that webhooks originate from a Paddle webhook IP address. We recommend adding Paddle webhook IP addresses to your allowlist, and rejecting webhooks that come from other sources.
Allow different IP addresses for sandbox and live accounts:
If you're using a Web Application Firewall (WAF) to protect your web server from bot traffic, requests from Paddle may be blocked incorrectly.
We recommend configuring your firewall to bypass bot checks on webhook endpoint paths. Also use Paddle IP addresses and match Paddle as the user agent string to further restrict your rule.
Configure your webhook handler
To receive webhooks, make sure your webhook event server:
Uses HTTPS
Can accept POST requests with a JSON payload
Returns 200 within five seconds of receiving a request
We recommend configuring your handler to process webhooks asynchronously by queueing received events and processing them in order. This helps prevent a large spike in webhooks from overwhelming your server.
Respond to events
The server that you set to receive events from Paddle should respond with an HTTP 200 status code within five seconds. This lets Paddle know that you successfully received the message.
You should respond before doing any internal processing. For example, if you use a webhook to update a record in a third-party system, respond with a 200 before running any logic to communicate with the third-party solution.
If you're running your webhook handler on Vercel Serverless Functions, AWS Lambda, Google Cloud Functions, or similar serverless platforms, consider pre-warming your function to prevent cold starts that might cause intermittent timeouts.
We can't guarantee the order of delivery for webhooks. They may be delivered in a different order to the order they're generated. Store and check the occurred_at date against a webhook before making changes.
Handle retries
If your server sends another kind of status code or doesn't respond within five seconds, Paddle automatically retries using an exponential backoff schedule:
For sandbox accounts, we make 3 attempts in total, all within about two minutes.
For live accounts, we make up to 60 attempts in total over about two days. Around 10 attempts happen in the first hour, and around 45 in the first day.
On live accounts, the wait before the next attempt is 60 ร n^1.1 seconds, where n is the number of attempts made so far.
Attempt 1 of ยท 0s after the first attempt
Press play to see when each attempt happens.
Live
1h1d1d 18h
Live webhook retry schedule
Attempt
Wait before this attempt
Time since first attempt
1
โ
0s
2
1m
1m
3
2m 9s
3m 9s
4
3m 21s
6m 30s
5
4m 36s
11m 6s
6
5m 52s
16m 58s
7
7m 11s
24m 9s
8
8m 30s
32m 39s
9
9m 51s
42m 30s
10
11m 13s
53m 43s
11
12m 35s
1h 6m
12
13m 59s
1h 20m
13
15m 23s
1h 35m
14
16m 48s
1h 52m
15
18m 14s
2h 10m
16
19m 40s
2h 30m
17
21m 7s
2h 51m
18
22m 34s
3h 14m
19
24m 2s
3h 38m
20
25m 30s
4h 3m
21
26m 59s
4h 30m
22
28m 28s
4h 59m
23
29m 58s
5h 29m
24
31m 28s
6h
25
32m 59s
6h 33m
26
34m 30s
7h 7m
27
36m 1s
7h 43m
28
37m 32s
8h 21m
29
39m 4s
9h
30
40m 37s
9h 41m
31
42m 9s
10h 23m
32
43m 42s
11h 7m
33
45m 15s
11h 52m
34
46m 49s
12h 39m
35
48m 23s
13h 27m
36
49m 57s
14h 17m
37
51m 31s
15h 8m
38
53m 5s
16h 2m
39
54m 40s
16h 56m
40
56m 15s
17h 52m
41
57m 51s
18h 50m
42
59m 26s
19h 50m
43
1h 1m
20h 51m
44
1h 2m
21h 53m
45
1h 4m
22h 58m
46
1h 5m
1d
47
1h 7m
1d 1h
48
1h 9m
1d 2h
49
1h 10m
1d 3h
50
1h 12m
1d 4h
51
1h 13m
1d 5h
52
1h 15m
1d 7h
53
1h 17m
1d 8h
54
1h 18m
1d 9h
55
1h 20m
1d 11h
56
1h 22m
1d 12h
57
1h 23m
1d 13h
58
1h 25m
1d 15h
59
1h 27m
1d 16h
60
1h 28m
1d 18h
Sandbox
1m 3s
Sandbox webhook retry schedule
Attempt
Wait before this attempt
Time since first attempt
1
โ
0s
2
20s
20s
3
43s
1m 3s
Times are approximate. An attempt can happen up to a minute later than shown.
You can check the status of a webhook and see delivery attempts using the Paddle dashboard, or by using the list logs for a notification operation in the Paddle API.
When all attempts to deliver a webhook are exhausted, its status is set to failed. You can attempt to redeliver a notification using the replay a notification operation in the Paddle API.
Verify webhook signatures
Use the Paddle-Signature header included with each webhook to verify that received events are genuinely sent by Paddle.
Test your handler
Send simulated webhooks to your handler
Test your webhook handler by sending simulated events to your endpoint using the webhook simulator. You can customize payloads, inspect event details, and replay simulations as part of your testing process.
Forward events to a local endpoint
Notification destinations require public-facing URLs. If you're developing locally, you can expose your local development server to the internet using a service like Hookdeck CLI:
Run your local server. Note the port your local server is running on.
Run hookdeck listen {PORT} paddle --path {WEBHOOK_ENDPOINT_PATH}, where {PORT} is the port where your local server is running and {WEBHOOK_ENDPOINT_PATH} is the path to your webhook handler. For example: