Verify webhook signatures
Check that webhooks are genuinely sent by Paddle by verifying webhook signatures.
For security, we recommend that you verify webhook signatures to make sure that webhook events are genuinely sent by Paddle. This helps you to be sure that they haven't been tampered with in-transit.
How does it work
Webhooks let you subscribe to events in Paddle. When a subscribed event occurs, Paddle sends a notification to a webhook endpoint that you specify.
All webhooks sent by Paddle include a signature that you can use to verify that they were genuinely sent by Paddle.
To verify, you can compare the signature included with each webhook with a signature that you generate. Both signatures are generated using a secret key that only you and Paddle know, so if they match it means you can be sure events came from Paddle.
Get started
Verify webhook signatures from Paddle in six steps:
Get the secret key for your notification destination using the API or Paddle web app.
Get the
Paddle-Signature
header from an incoming webhook sent by Paddle.Extract timestamp and signature from the header
Parse the header to extract its timestamp and signature values.
Concatenate the extracted timestamp with the raw body of the request to build a signed payload.
Hash the signed payload you built to generate a signature that you can use for comparison.
Compare the
Paddle-Signature
header to the signature you just computed.
Get your webhook secret key
First, get the secret key for your notification destination.
Paddle creates a secret key for each notification destination that you create. If you've created more than one notification destination, get keys for each notification destination that you'd like to verify signatures for.
Treat your endpoint secret key like a password. Keep it safe and never share it with apps or people you don't trust.
Edit destination
Go to Paddle > Developer Tools > Notifications.
Click the … next to a notification destination in the list, then choose Edit destination from the menu.

Copy secret key
Click the copy icon in the secret key field to copy it.

Get Paddle-Signature header
Next, get the Paddle-Signature
header from an incoming webhook sent by Paddle.
All webhook events sent by Paddle include a Paddle-Signature
header. For example:
11ts=1671552777;h1=eb4d0dc8853be92b7f063b9f3ba5233eb920a09459b6e6b2c26705b4364db151
Signatures include two parts, separated by a semicolon:
Timestamp as a Unix timestamp.
Webhook event signature. Signatures contain at least one h1
.
Extract timestamp and signature from header
Now you have the Paddle-Signature
header, parse it to extract the timestamp (ts
) and signature values (h1
).
You can do this by splitting using a semicolon character (;
) to get elements, then splitting again using an equals sign character (=
) to get key-value pairs.
Build signed payload
Paddle creates a signature by first concatenating the timestamp (ts
) with the body of the request, joined with a colon (:
).
Build your own signed payload by concatenating:
- The extracted timestamp (
ts
) + - A colon (
:
) + - The raw body of the request
Don't transform or process the raw body of the request, including adding whitespace or applying other formatting. This results in a different signed payload, meaning signatures won't match when you compare.
Hash signed payload
Next, hash your signed payload to generate a signature.
Paddle generates signatures using a keyed-hash message authentication code (HMAC) with SHA256 and a secret key.
Compute the HMAC of your signed payload using the SHA256 algorithm, using the secret key for this notification destination as the key.
This should give you the expected signature of the webhook event.
Compare signatures
Finally, compare the Paddle-Signature
header to the signature you just computed.
If they don't match, you should reject the webhook event. Someone may be sending malicious requests to your webhook endpoint.