hooks.bot Docs / Paddle Billing

Paddle Billing webhook signature verification

Paddle Billing signs each webhook and sends the digest in Paddle-Signature. When your check fails, one of a small number of steps is wrong — and guessing which is the slow way to find out. Paste the payload, the secret and the header block into the debugger and it rebuilds the signature every way it could plausibly have been made, then names the step that differs. It runs in your browser: the secret never leaves the page.

The scheme

Exactly what Paddle Billing signs

FieldValue
HeaderPaddle-Signature
Signed string{timestamp}:{body}
AlgorithmHMAC-SHA-256
Digest encodinghex
KeyNotification destination secret key, pdl_ntfset_… — used as-is.
Replay window5s

Official reference: https://developer.paddle.com/webhooks/signature-verification.

Causes

What actually goes wrong

Stripe and Svix both issue secrets that begin whsec_ and derive keys from them completely differently. Stripe uses the whole string, prefix included. Svix and Standard Webhooks strip the prefix and base64-decode the rest. This is the single commonest failure in the category.

Capture it

Get the real bytes, not a copy of a copy

If you are diagnosing from a logged payload you may be debugging the log rather than the webhook. Point Paddle Billing at a disposable URL and work from what actually arrived:

curl -X POST https://www.hooks.bot/api/endpoints
# {"url":"https://www.hooks.bot/h/abc…"}

Paste that URL into your Paddle Billing webhook settings, trigger an event, and the request appears at https://www.hooks.bot the moment it lands — headers, body and all. Press Diagnose this signature and add your secret.

Or let your agent do it

claude mcp add --transport http hooks-bot https://www.hooks.bot/mcp

Claude Code, Cursor and Codex can create the endpoint, block until the webhook lands, and diagnose it against the captured bytes without you copying anything.

Other providers

Stripe · GitHub · Svix / Standard Webhooks · Shopify · Slack · Twilio