Delivery behaviour
Read from the vendor's own documentation, last checked 2026-08-06. Where the vendor states no number, this table carries none.
| Response budget | not published by the vendor |
|---|---|
| Retry | not published by the vendor |
| Gives up | not published by the vendor |
Signature
Verified against a working verifier proven by a test suite, not read from documentation. Last verified 2026-08-20.
| Algorithm | RSA-SHA256 |
|---|---|
| Signed payload | {txId}|{txTime}|{webhookId}|{crc32(body)} |
| Encoding | base64 |
| Header | paypal-transmission-sig + 4 more |
| Tolerance | none enforced |
Verify it
The raw request body, byte for byte, before any JSON parsing. Every scheme on this page breaks the moment a framework re-serializes the payload.
// 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";If you do verify manually: validate that cert_url points at paypal.com before fetching it, or the attacker simply hosts their own certificate.
What bites
This is the only scheme on the page where verification can require a network call. The five signature headers travel with each event, and the signed payload embeds a CRC32 of the body rather than the body itself.
Read more
AnyHook sits in front of endpoints that receive from PayPal: it answers inside the budget above, retries on its own schedule when your server is down, and keeps every event replayable. Change one URL, keep your code.