Perilaku pengiriman
Diambil dari dokumentasi resmi vendor, terakhir diperiksa 2026-08-06. Jika vendor tidak menyebut angka, tabel ini juga tidak mencantumkannya.
| Batas waktu respons | tidak dipublikasikan vendor |
|---|---|
| Percobaan ulang | tidak dipublikasikan vendor |
| Berhenti mencoba | tidak dipublikasikan vendor |
Tanda tangan
Diverifikasi dengan verifier yang berfungsi dan dibuktikan oleh test suite, bukan dibaca dari dokumentasi. Terakhir diverifikasi 2026-08-20.
| Algoritma | RSA-SHA256 |
|---|---|
| Payload bertanda tangan | {txId}|{txTime}|{webhookId}|{crc32(body)} |
| Encoding | base64 |
| Header | paypal-transmission-sig + 4 more |
| Toleransi | tidak diberlakukan |
Verifikasi
Raw body dari permintaan, byte demi byte, sebelum parsing JSON apa pun. Setiap skema di halaman ini rusak begitu framework melakukan serialisasi ulang pada 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";Jika Anda memverifikasi secara manual: pastikan cert_url mengarah ke paypal.com sebelum mengambilnya, atau penyerang cukup meng-hosting sertifikatnya sendiri.
Yang sering menjebak
Ini satu-satunya skema di halaman ini yang verifikasinya bisa membutuhkan panggilan jaringan. Lima header tanda tangan ikut di setiap event, dan payload yang ditandatangani memuat CRC32 dari body, bukan body itu sendiri.
Baca juga
AnyHook berada di depan endpoint yang menerima webhook dari PayPal: AnyHook menjawab dalam sekitar satu detik, mencoba ulang sesuai jadwalnya sendiri saat server Anda mati, dan menyimpan setiap event agar dapat diputar ulang (replay). Ganti satu URL, kode Anda tetap.