
Paddle Webhooks
If you're wiring up Paddle payment webhooks, this handles the HMAC-SHA256 signature verification that trips people up. The tricky bit is that Paddle signs over the raw body with a timestamp prefix, and you'll see multiple h1 values during secret rotation. It includes verification snippets for Node and Python, plus pointers to full Express, Next.js, and FastAPI examples. Covers the subscription lifecycle events you actually care about like subscription.created, transaction.completed, and payment failures. Ships with a Hookdeck CLI command for local testing without ngrok. Pair it with the webhook-handler-patterns skill if you need idempotency and retry logic, because Paddle will hammer your endpoint if you're not careful with response codes.
- skills.sh installs
- 258
- GitHub stars
- 100
- last updated
- Aug 21, 2026
Install
$ npx -y skills add hookdeck/webhook-skills --skill paddle-webhooks --agent claude-codeInstalls into .claude/skills of the current project.
Files
Paddle Webhooks
When to Use This Skill
- Setting up Paddle webhook handlers
- Debugging signature verification failures
- Understanding Paddle event types and payloads
- Handling subscription, transaction, or customer events
Verification (core)
Paddle signs every webhook with HMAC-SHA256 over timestamp:rawBody. The Paddle-Signature header is ts=<unix>;h1=<hex> (multiple h1= values appear during secret rotation). Pass the raw request body — don't JSON.parse first.
The official @paddle/paddle-node-sdk exposes paddle.webhooks.unmarshal(rawBody, secretKey, signature) which verifies and parses in one call. For Python (or when not using the SDK), verify manually:
Node:
const crypto = require('crypto');
function verifyPaddleSignature(rawBody, signatureHeader, secret) {
const parts = signatureHeader.split(';');
const ts = parts.find(p => p.startsWith('ts='))?.slice(3);
const signatures = parts.filter(p => p.startsWith('h1=')).map(p => p.slice(3));
if (!ts || signatures.length === 0) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${ts}:${rawBody}`)
.digest('hex');
Sponsors
Details
- Repository
- github.com/hookdeck/webhook-skills
- Category
- Debugging
- First seen
- Jun 3, 2026