PayPal: como funciona a entrega de webhooks

O PayPal assina um CRC32 do corpo com RSA-SHA256, atrelado a um certificado hospedado. Por que a API de verificação é o caminho sensato e o formato manual.

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 respostanão publicado pelo provedor
Novas tentativasnão publicado pelo provedor
Desistenão publicado pelo provedor

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.

AlgoritmoRSA-SHA256
Payload assinado{txId}|{txTime}|{webhookId}|{crc32(body)}
Codificaçãobase64
Cabeçalhopaypal-transmission-sig + 4 more
Tolerâncianenhuma exigida

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.

// Manual verification means: fetch the cert from paypal-cert-url, extract
// its public key, then RSA-SHA256-verify paypal-transmission-sig against
//   "{transmission-id}|{transmission-time}|{webhook-id}|{crc32(rawBody)}"
// Most integrations skip that and call the verify endpoint instead:
const res = await fetch(
  "https://api-m.paypal.com/v1/notifications/verify-webhook-signature",
  {
    method: "POST",
    headers: { authorization: `Bearer ${accessToken}`, "content-type": "application/json" },
    body: JSON.stringify({
      transmission_id: req.headers["paypal-transmission-id"],
      transmission_time: req.headers["paypal-transmission-time"],
      cert_url: req.headers["paypal-cert-url"],
      auth_algo: req.headers["paypal-auth-algo"],
      transmission_sig: req.headers["paypal-transmission-sig"],
      webhook_id: webhookId, // yours, from the developer dashboard
      webhook_event: JSON.parse(rawBody),
    }),
  },
);
const valid = (await res.json()).verification_status === "SUCCESS";

Se você verificar manualmente, confirme que cert_url aponta para paypal.com antes de buscá-lo, ou o atacante só precisa hospedar o próprio certificado.

Armadilhas

Este é o único esquema da página em que a verificação pode exigir uma chamada de rede. Os cinco cabeçalhos de assinatura viajam com cada evento, e o payload assinado inclui um CRC32 do corpo, não o corpo em si.

Leia também

O AnyHook fica entre PayPal 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.

Como funciona →