Lewati ke konten
getnextpdf.com

Enterprise edisi

Webhook

NextPDF Enterprise mengirimkan event job ke endpoint webhook per-tenant melalui HTTP POST, menandatangani setiap payload dengan tanda tangan HMAC-SHA256, mencoba ulang dengan backoff eksponensial, dan merutekan pengiriman yang gagal permanen ke antrean dead-letter untuk inspeksi dan replay. Halaman ini menjelaskan perilaku webhook yang dapat diamati dan kontrak publiknya.

Kapabilitas ini dikapalkan dalam NextPDF Enterprise (nextpdf/enterprise) dan aktif dengan envelope lisensi tier Enterprise. Deployment tanpa entitlement tersebut tidak memuat kelas-kelas kapabilitas ini. Bandingkan edisi dan dapatkan lisensi.

Permukaan webhook adalah kapabilitas Enterprise dasar, tersedia setelah paket Enterprise dipasang; tidak ada flag per-fitur tersendiri.

Sebuah tenant meregistrasi URL callback, secret penandatanganan, dan daftar tipe event opsional. Daftar event kosong berarti “berlangganan ke semua event”. Registrasi dicakup secara ketat per-tenant: sebuah tenant hanya dapat melihat dan mengelola registrasinya sendiri, dan meregistrasi di bawah tenant yang tidak cocok ditolak. Meng-unregister menonaktifkan registrasi alih-alih menghapusnya, sehingga riwayat dilestarikan; hanya registrasi aktif yang menerima dispatch.

Ketika sebuah event job di-dispatch untuk sebuah tenant, setiap registrasi aktif yang berlangganan tipe event tersebut menerima sebuah pengiriman. Payload adalah dokumen JSON terstandar — sebuah pengenal pengiriman yang unik, pengenal job, tipe event, data event, stempel waktu RFC 3339, dan pengenal tenant. Pengiriman adalah HTTP POST yang membawa body JSON dan empat header: tanda tangan HMAC-SHA256, stempel waktu unix-detik, pengenal pengiriman, dan tipe event. Tanda tangan dihitung atas base string kanonis {timestamp}.{body} dengan secret registrasi, sehingga header stempel waktu terikat secara kriptografis ke body. Penerima menghitung ulang HMAC atas base string yang sama dan menolak pengiriman yang stempel waktunya jatuh di luar jendela kesegaran yang dapat diterima, yang membatasi replay.

Pengiriman menggunakan backoff eksponensial. Respons 2xx adalah sukses. Respons 4xx selain 429 diperlakukan sebagai penolakan permanen dan tidak dicoba ulang. Kegagalan lain — 5xx, 429, atau error koneksi — dicoba ulang hingga jumlah percobaan kebijakan dengan penundaan berlipat ganda yang dibatasi pada sebuah maksimum. Ketika semua percobaan habis, pengiriman dicatat dalam antrean dead-letter in-memory dengan payload asli, jumlah percobaan, error terakhir, dan status HTTP terakhir; sebuah entri dead-letter dapat ditandai ter-replay. Dua kebijakan retry dikapalkan — sebuah default (5 percobaan, 1s dasar, 5min batas) dan sebuah aggressive (10 percobaan, 2s dasar, 10min batas).

Pengiriman diperlakukan sebagai permukaan operasional, bukan panggilan fire-and-forget. Kegagalan diklasifikasikan berdasarkan intensi. Sebuah 4xx selain 429 adalah penolakan penerima yang sesungguhnya, jadi ia berhenti seketika. Sebuah 5xx, sebuah 429, atau error koneksi bersifat transien, jadi ia mendapat retry yang mundur dan dibatasi. Pengiriman yang menghabiskan setiap percobaan tidak pernah dijatuhkan secara diam-diam; mereka mendarat di antrean dead-letter yang dapat diinspeksi dan dapat di-replay. Tanda tangan mengikat sebuah stempel waktu ke dalam base string-nya, dan setiap tujuan melewati gerbang egress, sehingga autentisitas dan resistensi replay berlaku secara konstruksi untuk setiap tenant.

Latar belakang desain: Mengoperasikan NextPDF di produksi.

Terminal window
composer require nextpdf/enterprise:^3

Titik integrasi yang didukung adalah webhook manager (register, unregister, activeRegistrations, dispatch), value object registrasi (subscribesTo, deactivate), payload (fromJobEvent, toJson, toArray, sign, signedTimestamp), engine pengiriman (deliver, deadLetters, clearDeadLetters), kebijakan retry (delayForAttempt, shouldRetry, default, aggressive), dan entri dead-letter (markReplayed).

use NextPDF\Enterprise\Webhook\WebhookManager;
use NextPDF\Enterprise\Webhook\WebhookRegistration;
$manager->register($tenant, new WebhookRegistration(
id: $id,
tenantId: $tenant->tenantId,
url: 'https://customer.example.com/hooks/nextpdf',
events: [], // empty = subscribe to all event types
secret: $signingSecret,
));
$delivered = $manager->dispatch($tenant, $jobEvent); // count of successes

Verifikasi sisi-penerima:

$ts = (int) $request->header('X-NextPDF-Timestamp');
if (abs(time() - $ts) > 300) {
return new Response(401); // stale timestamp: reject to bound replay
}
$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $rawBody, $sharedSecret);
if (! hash_equals($expected, $request->header('X-NextPDF-Signature'))) {
return new Response(401);
}
use NextPDF\Enterprise\Webhook\WebhookDelivery;
use NextPDF\Enterprise\Webhook\WebhookRetryPolicy;
$delivery = new WebhookDelivery(
$httpClient, $requestFactory, $streamFactory,
retryPolicy: WebhookRetryPolicy::aggressive(), // 10 attempts, 2s base, 10min cap
logger: $logger,
);
$manager = new WebhookManager($delivery, $logger);
$manager->dispatch($tenant, $jobEvent);
foreach ($delivery->deadLetters() as $dead) {
$this->scheduleReplay($dead); // inspect last error + last HTTP status
}
  • Daftar event kosong berlangganan ke semua. Sebuah registrasi tanpa tipe event menerima setiap event; berikan daftar eksplisit untuk mencakupkannya.
  • Isolasi tenant ditegakkan. Meregistrasi dengan ID tenant yang berbeda dari konteks tenant ditolak; dispatch hanya mengiterasi registrasi aktif milik tenant pemanggil.
  • 4xx (kecuali 429) bersifat terminal. Sebuah 4xx selain 429 tidak dicoba ulang — ia diperlakukan sebagai penolakan penerima permanen dan masuk ke antrean dead-letter.
  • Unregister bersifat soft. Meng-unregister menonaktifkan; rekaman bertahan dan dikecualikan dari dispatch.
  • Antrean dead-letter bersifat in-memory. Ia untuk inspeksi dan replay dalam seumur hidup proses; persistensikan entri sendiri jika Anda membutuhkan replay yang tahan lama lintas restart.

Biaya dispatch proporsional dengan jumlah registrasi aktif untuk tenant yang berlangganan event tersebut. Setiap pengiriman adalah satu HMAC-SHA256 atas base string yang ditandatangani ditambah round trip HTTP; retry menambahkan penundaan backoff eksponensial yang dibatasi. Penandatanganan adalah O(ukuran payload).

Setiap payload diautentikasi dengan tanda tangan HMAC-SHA256 yang dikunci oleh secret registrasi dan dikirim dalam header X-NextPDF-Signature sebagai sha256=<hex>. Tanda tangan mencakup base string {timestamp}.{body}, dan stempel waktu berjalan dalam header X-NextPDF-Timestamp; penerima memverifikasi dengan perbandingan constant-time dan menolak pengiriman di luar jendela kesegaran untuk membatasi replay. URL tujuan melewati gerbang egress terpusat sebelum setiap pengiriman: HTTPS diwajibkan, dan host yang resolve ke alamat private, loopback, link-local, atau cloud-metadata ditolak tanpa sebuah request dan dirutekan ke antrean dead-letter. Secret penandatanganan bersifat per-registrasi; perlakukan sebagai kredensial. Tanda tangan mengautentikasi integritas dan asal payload; ia bukan lapisan enkripsi — jangan menempatkan secret dalam data event yang tidak boleh dilihat penerima.

  • Autentikasi payload menggunakan HMAC dengan SHA-256, keyed-hash message authentication code dari FIPS PUB 198-1; OWASP ASVS 5.0 mencantumkan HMAC-SHA-256 di antara algoritma autentikasi-pesan yang disetujuinya.
  • Stempel waktu payload adalah string date-time RFC 3339. Catatan: RFC 3339 tidak diambil dari korpus RAG untuk halaman ini; format bersifat code-declared (extended RFC 3339) dan ditandai code-declared alih-alih RAG-verified.
  • Registrasi dicakup secara ketat per-tenant; meregistrasi di bawah tenant yang tidak cocok ditolak dan unregister adalah soft deactivate yang melestarikan riwayat.
  • Daftar event kosong berlangganan ke semua event; hanya registrasi aktif yang berlangganan tipe event yang menerima dispatch.
  • Setiap pengiriman adalah HTTP POST dengan body JSON ditambah header tanda tangan HMAC-SHA256 (atas base string {timestamp}.{body}), header stempel waktu unix-detik, pengenal pengiriman, dan tipe event.
  • Sebuah 2xx adalah sukses; sebuah 4xx selain 429 adalah penolakan permanen (tanpa retry); 5xx, 429, atau error koneksi dicoba ulang hingga jumlah percobaan kebijakan dengan backoff berlipat ganda yang dibatasi.
  • Percobaan yang habis mencatat pengiriman dalam antrean dead-letter in-memory (payload, jumlah percobaan, error terakhir, status terakhir); sebuah entri dead-letter dapat ditandai ter-replay.

Halaman ini hanya mendokumentasikan perilaku yang dapat diamati secara eksternal dan permukaan API publik yang didukung. Jalur namespace internal, kelas helper, tabel mekanisme, nama berkas runbook, dan prefiks tiket berada di luar cakupan.

NextPDF Core (Apache-2.0) tidak memiliki permukaan registrasi atau pengiriman webhook — sama sekali tidak; kapabilitas ini tidak memiliki padanan tier Core.

NextPDF Pro tidak memiliki permukaan registrasi atau pengiriman webhook — sama sekali tidak; kapabilitas ini tidak memiliki padanan tier Pro. Webhook manager, registrasi, payload, engine pengiriman, dan kebijakan retry hanya dikapalkan dalam paket nextpdf/enterprise.

Kebijakan retry, jadwal backoff, dan penanganan dead-letter dijelaskan pada tingkat perilaku. Antrean dead-letter bersifat in-memory untuk inspeksi dan replay dalam seumur hidup proses; persistensi lintas-restart yang tahan lama dan internal pengiriman internal apa pun berada di luar cakupan permukaan publik.

Operator memiliki endpoint callback, secret penandatanganan per-registrasi (diperlakukan sebagai kredensial), persistensi tahan lama dari entri dead-letter jika replay lintas-restart diperlukan, dan postur HTTPS dari URL penerima. NextPDF Enterprise menandatangani dan mengirimkan tetapi tidak memersistensikan sendiri registrasi atau dead letter di luar seumur hidup proses.

Tidak ada pembatasan kendali ekspor yang berlaku pada permukaan webhook. Tanda tangan HMAC mengautentikasi integritas dan asal payload; ia bukan lapisan enkripsi — operator tidak boleh menempatkan secret dalam data event yang tidak boleh dilihat penerima. Dokumentasi ini bukan opini hukum; konsultasikan penasihat kepatuhan dan hukum Anda sendiri.