Comportamento de entrega
Lido na documentação do próprio provedor, verificado pela última vez em 2026-08-06. Onde o provedor não informa um número, esta tabela também não traz nenhum.
| Prazo de resposta | 5 s |
|---|---|
| Novas tentativas | Produção: até 60 tentativas ao longo de cerca de 2 dias, cerca de 10 na primeira hora e cerca de 45 no primeiro dia. Sandbox: 3 tentativas em cerca de 2 min |
| Desiste | não publicado pelo provedor |
| Fonte | https://developer.paddle.com/webhooks/about/respond-to-webhooks |
Assinatura
Verificada com um verificador funcional, comprovado por uma suíte de testes, e não lida na documentação. Última verificação em 2026-08-20.
| Algoritmo | HMAC-SHA256 |
|---|---|
| Payload assinado | {timestamp}:{body} |
| Codificação | hex |
| Cabeçalho | paddle-signature = ts=X;h1=hex |
| Tolerância | 5 s |
Verifique a assinatura
O corpo bruto da requisição, byte a byte, antes de qualquer parsing de JSON. Todos os esquemas desta página quebram no momento em que um framework serializa o payload de novo.
const crypto = require("node:crypto");
// paddle-signature: "ts=1700000000;h1=abc..." — HMAC-SHA256 over "{ts}:{body}"
const pairs = Object.fromEntries(
req.headers["paddle-signature"].split(";").map((p) => p.split("=")),
);
const expected = crypto
.createHmac("sha256", secretKey) // per destination: pdl_ntfset_...
.update(`${pairs.ts}:${rawBody}`)
.digest("hex");
const received = Buffer.from(pairs.h1 ?? "");
const wanted = Buffer.from(expected);
// timingSafeEqual throws on a length mismatch, so check that first.
const valid =
received.length === wanted.length && crypto.timingSafeEqual(received, wanted);O SDK da Paddle aplica uma tolerância de 5 segundos ao timestamp, a menor entre os remetentes desta página. Atrás de um relay ou de uma fila, compare o timestamp com o momento em que o evento chegou à edge, não com o momento em que seu worker o pegou.
Armadilhas
A curva de novas tentativas é densa onde a da Stripe é esparsa: cerca de 10 tentativas na primeira hora, cerca de 45 no primeiro dia, até 60 em cerca de 2 dias. Um handler que está apenas lento roda de novo a cada poucos minutos no início e, sem idempotência, cada execução repete seus efeitos colaterais.
O sandbox não se parece em nada com produção (3 tentativas em cerca de 2 minutos), então um tratamento de novas tentativas que parece bom nos testes viu só 5% da pressão.
Leia também
O AnyHook fica entre Paddle e seus endpoints: responde em cerca de um segundo, tenta de novo segundo um cronograma próprio quando seu servidor está fora do ar e guarda cada evento disponível para replay. Troque uma URL e mantenha seu código; para aceitar novas tentativas e replays, verifique o cabeçalho AnyHook-Signature, porque a assinatura original do remetente (Paddle) expira após 5 s.