Pular para o conteúdo
getnextpdf.com

Enterprise edição

Webhook

O NextPDF Enterprise entrega eventos de job a endpoints de webhook por locatário via HTTP POST, assina cada payload com uma assinatura HMAC-SHA256, faz retry com backoff exponencial e roteia entregas permanentemente com falha para uma fila de dead-letter para inspeção e replay. Esta página descreve o comportamento observável do webhook e o contrato público.

Esta capacidade é fornecida no NextPDF Enterprise (nextpdf/enterprise) e é ativada com um envelope de licença de nível Enterprise. Uma implantação sem esse direito não carrega as classes da capacidade. Compare edições e obtenha uma licença.

A superfície de webhook é uma capacidade base do Enterprise, disponível assim que o pacote Enterprise é instalado; não há nenhum sinalizador por recurso separado.

Um locatário registra uma URL de callback, um segredo de assinatura e uma lista opcional de tipos de evento. Uma lista de eventos vazia significa “assinar todos os eventos”. Os registros têm escopo estrito de locatário: um locatário só pode ver e gerenciar seus próprios registros, e registrar sob um locatário incompatível é rejeitado. Cancelar o registro desativa o registro em vez de excluí-lo, então o histórico é preservado; apenas registros ativos recebem dispatches.

Quando um evento de job é despachado para um locatário, cada registro ativo que assina o tipo de evento recebe uma entrega. O payload é um documento JSON padronizado — um identificador único de entrega, o identificador de job, o tipo de evento, os dados do evento, um carimbo de data/hora RFC 3339 e o identificador de locatário. A entrega é um HTTP POST que carrega o corpo JSON e quatro cabeçalhos: uma assinatura HMAC-SHA256, um carimbo de data/hora em segundos unix, o identificador de entrega e o tipo de evento. A assinatura é calculada sobre a string base canônica {timestamp}.{body} com o segredo do registro, então o cabeçalho de timestamp fica criptograficamente vinculado ao corpo. O receptor recalcula o HMAC sobre a mesma string base e rejeita entregas cujo timestamp esteja fora de uma janela de frescor aceitável, o que limita o replay.

A entrega usa backoff exponencial. Uma resposta 2xx é sucesso. Uma resposta 4xx diferente de 429 é tratada como uma rejeição permanente e não passa por retry. Outras falhas — 5xx, 429 ou um erro de conexão — passam por retry até a contagem de tentativas da política com um atraso que dobra, limitado a um máximo. Quando todas as tentativas se esgotam, a entrega é registrada em uma fila de dead-letter em memória com o payload original, a contagem de tentativas, o último erro e o último status HTTP; uma entrada de dead-letter pode ser marcada como reenviada. Duas políticas de retry são fornecidas — uma default (5 tentativas, 1s base, 5min limite) e uma aggressive (10 tentativas, 2s base, 10min limite).

A entrega é tratada como uma superfície operacional, não como uma chamada fire-and-forget. As falhas são classificadas por intenção. Um 4xx diferente de 429 é uma rejeição genuína do receptor, então ele para de imediato. Um 5xx, um 429 ou um erro de conexão é transiente, então ganha um retry limitado e com backoff. Entregas que esgotam todas as tentativas nunca são descartadas silenciosamente; elas caem em uma fila de dead-letter inspecionável que pode ser reenviada. A assinatura vincula um timestamp à sua string base, e todo destino passa por um portão de saída, então a autenticidade e a resistência a replay se mantêm por construção para cada locatário.

Contexto de design: Operar o NextPDF em produção.

Terminal window
composer require nextpdf/enterprise:^3

Os pontos de integração suportados são o gerenciador de webhook (register, unregister, activeRegistrations, dispatch), o objeto de valor de registro (subscribesTo, deactivate), o payload (fromJobEvent, toJson, toArray, sign, signedTimestamp), o engine de entrega (deliver, deadLetters, clearDeadLetters), a política de retry (delayForAttempt, shouldRetry, default, aggressive) e a entrada de 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

Verificação no lado do receptor:

$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
}
  • Uma lista de eventos vazia assina todos. Um registro sem tipos de evento recebe todo evento; passe uma lista explícita para definir o escopo.
  • O isolamento de locatário é imposto. Registrar com um ID de locatário que difere do locatário do contexto é rejeitado; o dispatch itera apenas os registros ativos do locatário chamador.
  • 4xx (exceto 429) é terminal. Um 4xx diferente de 429 não passa por retry — ele é tratado como uma rejeição permanente do receptor e vai para a fila de dead-letter.
  • O cancelamento de registro é suave. Cancelar o registro desativa; o registro persiste e é excluído do dispatch.
  • A fila de dead-letter é em memória. Ela é para inspeção e replay dentro da duração do processo; persista as entradas por conta própria se precisar de replay durável entre reinicializações.

O custo de dispatch é proporcional ao número de registros ativos do locatário que assinam o evento. Cada entrega é um HMAC-SHA256 sobre a string base assinada mais a ida e volta HTTP; os retries acrescentam atrasos limitados de backoff exponencial. A assinatura é O(tamanho do payload).

Cada payload é autenticado com uma assinatura HMAC-SHA256 com chave igual ao segredo do registro e enviada no cabeçalho X-NextPDF-Signature como sha256=<hex>. A assinatura cobre a string base {timestamp}.{body}, e o timestamp viaja no cabeçalho X-NextPDF-Timestamp; os receptores verificam com uma comparação de tempo constante e rejeitam entregas fora de uma janela de frescor para limitar o replay. As URLs de destino passam por um portão de saída central antes de cada envio: HTTPS é obrigatório, e hosts que resolvem para endereços privados, de loopback, link-local ou de metadados de nuvem são recusados sem uma requisição e roteados para a fila de dead-letter. O segredo de assinatura é por registro; trate-o como uma credencial. A assinatura autentica a integridade e a origem do payload; ela não é uma camada de criptografia — não coloque segredos nos dados do evento que o receptor não deve ver.

  • A autenticação de payload usa HMAC com SHA-256, o código de autenticação de mensagem por hash com chave do FIPS PUB 198-1; o OWASP ASVS 5.0 lista o HMAC-SHA-256 entre seus algoritmos de autenticação de mensagem aprovados.
  • Os carimbos de data/hora do payload são strings de data-hora RFC 3339. Observação: o RFC 3339 não foi recuperado do corpus RAG para esta página; o formato é declarado em código (RFC 3339 estendido) e marcado como declarado em código em vez de verificado por RAG.
  • Os registros têm escopo estrito de locatário; registrar sob um locatário incompatível é rejeitado e o cancelamento de registro é uma desativação suave que preserva o histórico.
  • Uma lista de eventos vazia assina todos os eventos; apenas registros ativos que assinam o tipo de evento recebem um dispatch.
  • Cada entrega é um HTTP POST com o corpo JSON mais um cabeçalho de assinatura HMAC-SHA256 (sobre a string base {timestamp}.{body}), um cabeçalho de timestamp em segundos unix, o identificador de entrega e o tipo de evento.
  • Um 2xx é sucesso; um 4xx diferente de 429 é uma rejeição permanente (sem retry); 5xx, 429 ou um erro de conexão passa por retry até a contagem de tentativas da política com backoff de duplicação limitado.
  • Tentativas esgotadas registram a entrega em uma fila de dead-letter em memória (payload, contagem de tentativas, último erro, último status); uma entrada de dead-letter pode ser marcada como reenviada.

Esta página documenta apenas o comportamento observável externamente e a superfície de API pública suportada. Caminhos de namespace internos, classes auxiliares, tabelas de mecanismo, nomes de arquivo de runbook e prefixos de tíquete estão fora do escopo.

O NextPDF Core (Apache-2.0) não tem nenhuma superfície de registro ou entrega de webhook — nenhuma; esta capacidade não tem equivalente no nível Core.

O NextPDF Pro não tem nenhuma superfície de registro ou entrega de webhook — nenhuma; esta capacidade não tem equivalente no nível Pro. O gerenciador de webhook, o registro, o payload, o engine de entrega e a política de retry são fornecidos apenas no pacote nextpdf/enterprise.

A política de retry, o cronograma de backoff e o tratamento de dead-letter são descritos no nível de comportamento. A fila de dead-letter é em memória para inspeção e replay dentro da duração do processo; a persistência durável entre reinicializações e quaisquer detalhes internos de entrega estão fora do escopo da superfície pública.

O operador é dono dos endpoints de callback, dos segredos de assinatura por registro (tratados como credenciais), da persistência durável das entradas de dead-letter caso seja necessário replay entre reinicializações e da postura HTTPS das URLs receptoras. O NextPDF Enterprise assina e entrega, mas não persiste por si só registros nem dead letters além da duração do processo.

Nenhuma restrição de controle de exportação se aplica à superfície de webhook. A assinatura HMAC autentica a integridade e a origem do payload; ela não é uma camada de criptografia — os operadores não devem colocar segredos nos dados do evento que o receptor não deve ver. Esta documentação não é um parecer jurídico; consulte seus próprios assessores de conformidade e jurídicos.