Enterprise 版本
Webhook
NextPDF Enterprise 透過 HTTP POST 將工作事件傳遞到逐租戶的 webhook 端點,以一個 HMAC-SHA256 簽章為每個酬載簽署,以指數退避重試,並將永久失敗的傳遞路由到一個死信佇列以供檢視與重播。本頁描述可觀察的 webhook 行為與公開合約。
可用性與授權
標題為「可用性與授權」的區段此能力隨附於 NextPDF Enterprise(nextpdf/enterprise),並以一份 Enterprise 層級的授權信封啟用。缺少該授權的部署不會載入此能力的類別。比較各版本並取得授權。
webhook 介面是一項基礎 Enterprise 能力,只要安裝了 Enterprise 套件即可使用;沒有獨立的逐功能旗標。
概念總覽
標題為「概念總覽」的區段一個租戶登錄一個回呼 URL、一個簽署密鑰,以及一個選用的事件型別清單。空的事件清單代表「訂閱所有事件」。登錄嚴格地以租戶為範圍:一個租戶只能看見與管理自己的登錄,而以不符的租戶登錄會被拒絕。取消登錄會停用該登錄,而非刪除它,因此歷史會被保留;只有有效的登錄會收到派送。
當為某個租戶派送一個工作事件時,每個訂閱了該事件型別的有效登錄都會收到一次傳遞。酬載是一份標準化的 JSON 文件——一個唯一的傳遞識別碼、工作識別碼、事件型別、事件資料、一個 RFC 3339 時間戳記,以及租戶識別碼。該傳遞是一個 HTTP POST,承載該 JSON 主體與四個標頭:一個 HMAC-SHA256 簽章、一個 unix 秒數時間戳記、傳遞識別碼,以及事件型別。簽章是以登錄的密鑰在標準基礎字串 {timestamp}.{body} 上計算的,因此時間戳記標頭在密碼學上與主體綁定。接收方在同一個基礎字串上重新計算 HMAC,並拒絕其時間戳記落在可接受的新鮮度視窗之外的傳遞,藉此界定重播範圍。
傳遞使用指數退避。一個 2xx 回應為成功。一個非 429 的 4xx 回應會被視為永久拒絕,且不重試。其他失敗——5xx、429 或連線錯誤——會以一個加倍的延遲(以一個最大值為上限)重試到原則的嘗試次數。當所有嘗試耗盡時,傳遞會被記錄到一個記憶體中的死信佇列,內含原始酬載、嘗試次數、最後錯誤,以及最後的 HTTP 狀態;一個死信項目可被標記為已重播。隨附兩個重試原則——一個 default(5 次嘗試、1s 基礎、5min 上限)與一個 aggressive(10 次嘗試、2s 基礎、10min 上限)。
為何如此設計
標題為「為何如此設計」的區段傳遞被視為一個維運介面,而非發後不理的呼叫。失敗依意圖分類。一個非 429 的 4xx 是真正的接收方拒絕,因此立即停止。一個 5xx、一個 429 或一個連線錯誤是暫時性的,因此獲得一次有上限、會退避的重試。耗盡每一次嘗試的傳遞絕不會被靜默丟棄;它們會落入一個可檢視的死信佇列,並可被重播。簽章將一個時間戳記綁入其基礎字串,而每個目的地都會通過一道出口閘門,因此真實性與抗重播對每個租戶而言都是由設計所保證。
設計背景:在正式環境中營運 NextPDF。
公開 API 介面
標題為「公開 API 介面」的區段composer require nextpdf/enterprise:^3受支援的整合點是 webhook manager(register、unregister、activeRegistrations、dispatch)、登錄值物件(subscribesTo、deactivate)、酬載(fromJobEvent、toJson、toArray、sign、signedTimestamp)、傳遞引擎(deliver、deadLetters、clearDeadLetters)、重試原則(delayForAttempt、shouldRetry、default、aggressive),以及死信項目(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接收方側的驗證:
$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}邊界案例與陷阱
標題為「邊界案例與陷阱」的區段- 空事件清單會訂閱全部。 一個沒有事件型別的登錄會收到每一個事件;請傳入一個明確的清單以界定其範圍。
- 租戶隔離受到強制。 以一個與情境租戶不同的租戶 ID 登錄會被拒絕;派送只走訪呼叫租戶的有效登錄。
- 4xx(429 除外)為終止。 一個非 429 的 4xx 不會重試——它被視為永久的接收方拒絕,並進入死信佇列。
- 取消登錄是軟性的。 取消登錄會停用;記錄會持續存在,並被排除於派送之外。
- 死信佇列在記憶體中。 它用於程序生命週期內的檢視與重播;若你需要跨重啟的持久重播,請自行持久化項目。
派送成本與該租戶中訂閱該事件的有效登錄數量成正比。每次傳遞是一次對已簽署基礎字串的 HMAC-SHA256 加上 HTTP 往返;重試會增加受限的指數退避延遲。簽署成本為 O(酬載大小)。
安全注意事項
標題為「安全注意事項」的區段每個酬載都以一個由登錄密鑰鍵控的 HMAC-SHA256 簽章驗證,並在 X-NextPDF-Signature 標頭中以 sha256=<hex> 送出。簽章涵蓋 {timestamp}.{body} 基礎字串,而時間戳記在 X-NextPDF-Timestamp 標頭中傳遞;接收方以常數時間比較驗證,並拒絕新鮮度視窗之外的傳遞以界定重播範圍。目的地 URL 在每次送出前都會通過一道中央出口閘門:要求 HTTPS,而解析到私有、迴路、鏈路本地或雲端中繼資料位址的主機會在不發出請求的情況下被拒絕,並被路由到死信佇列。簽署密鑰是逐登錄的;請將其視為一份憑證。簽章驗證酬載的完整性與來源;它不是加密層——請勿將接收方不應看到的密碼放入事件資料。
一致性
標題為「一致性」的區段- 酬載驗證使用搭配 SHA-256 的 HMAC,即 FIPS PUB 198-1 的金鑰雜湊訊息驗證碼;OWASP ASVS 5.0 將 HMAC-SHA-256 列於其核可的訊息驗證演算法之中。
- 酬載時間戳記是 RFC 3339 日期時間字串。注意:本頁未從 RAG 語料庫取得 RFC 3339;該格式由程式碼宣告(RFC 3339 延伸),並標示為程式碼宣告,而非 RAG 驗證。
行為合約
標題為「行為合約」的區段- 登錄嚴格地以租戶為範圍;以不符的租戶登錄會被拒絕,而取消登錄是一種保留歷史的軟停用。
- 空的事件清單會訂閱所有事件;只有訂閱該事件型別的有效登錄會收到一次派送。
- 每次傳遞都是一個帶有 JSON 主體加上一個 HMAC-SHA256 簽章標頭(在
{timestamp}.{body}基礎字串上)、一個 unix 秒數時間戳記標頭、傳遞識別碼,以及事件型別的 HTTP POST。 - 一個 2xx 為成功;一個非 429 的 4xx 為永久拒絕(不重試);5xx、429 或連線錯誤會以有上限的加倍退避重試到原則的嘗試次數。
- 耗盡的嘗試會將傳遞記錄到一個記憶體中的死信佇列(酬載、嘗試次數、最後錯誤、最後狀態);一個死信項目可被標記為已重播。
發布邊界
標題為「發布邊界」的區段本頁僅記載外部可觀察的行為與受支援的公開 API 介面。內部命名空間路徑、輔助類別、機制表格、runbook 檔名,以及工單前綴不在範圍內。
Core 回退
標題為「Core 回退」的區段NextPDF Core(Apache-2.0)沒有 webhook 登錄或傳遞介面——完全沒有;此能力沒有 Core 層級的對應。
Pro 回退
標題為「Pro 回退」的區段NextPDF Pro 沒有 webhook 登錄或傳遞介面——完全沒有;此能力沒有 Pro 層級的對應。webhook manager、登錄、酬載、傳遞引擎與重試原則僅隨附於 nextpdf/enterprise 套件。
Enterprise 邊界註記
標題為「Enterprise 邊界註記」的區段重試原則、退避排程與死信處理皆以行為層級描述。死信佇列在記憶體中,用於程序生命週期內的檢視與重播;跨重啟的持久持久化與任何內部傳遞內部實作不在公開介面的範圍內。
部署邊界
標題為「部署邊界」的區段操作者負責回呼端點、逐登錄的簽署密鑰(視為憑證)、在需要跨重啟重播時對死信項目的持久化,以及接收方 URL 的 HTTPS 態勢。NextPDF Enterprise 會簽署與傳遞,但本身不會在程序生命週期之外持久化登錄或死信。
法律合規邊界
標題為「法律合規邊界」的區段webhook 介面不適用任何出口管制限制。HMAC 簽章驗證酬載的完整性與來源;它不是加密層——操作者不得將接收方不應看到的密碼放入事件資料。本文件不是法律意見;請諮詢你自己的合規與法律顧問。