Webhooks
Visão geral
Seção intitulada “Visão geral”Os webhooks de saída avisam o seu sistema quando uma nota fiscal muda de status, sem você precisar consultar a API em loop. A Nive faz um POST com JSON na URL que você cadastrar.
| Evento | Quando |
|---|---|
fiscal.document.authorized |
Nota autorizada pela SEFAZ |
fiscal.document.rejected |
Nota rejeitada (veja rejection.code e rejection.message) |
fiscal.document.cancelled |
Cancelamento homologado |
fiscal.document.contingency |
Nota emitida em contingência, aguardando transmissão |
fiscal.document.failed |
Falha local antes da SEFAZ (montagem ou assinatura do XML) |
Venda criada, estoque e outros eventos não geram webhook. Para eles continue consultando a API.
Permissões
Seção intitulada “Permissões”A chave de API precisa de permissão fiscal (fiscal.view para consultar, fiscal.manage para cadastrar e alterar destinos). O escopo padrão Vendas, estoque e cadastros não inclui o módulo fiscal: crie a chave com permissions personalizadas (veja autenticação).
Cadastrar o destino
Seção intitulada “Cadastrar o destino”curl -X POST https://api.nivesistemas.com.br/outbound-webhooks \ -H "Authorization: Bearer sl_live_..." \ -H "X-Store-Slug: sua-loja" \ -H "Content-Type: application/json" \ -d '{"url":"https://seu-sistema.com.br/hooks/nive","description":"CRM"}'A resposta traz o segredo (whsec_...) uma única vez. Guarde-o em um cofre. Se perder, gere outro com POST /outbound-webhooks/:id/rotate-secret.
Em produção a URL deve ser https e pública; endereços internos ou privados são recusados. Cada loja pode ter até 5 destinos. Use POST /outbound-webhooks/:id/test para enviar um evento webhook.test.
O que a Nive envia
Seção intitulada “O que a Nive envia”| Header | Conteúdo |
|---|---|
X-Nive-Event |
Nome do evento |
X-Nive-Delivery |
Identificador da entrega (use para deduplicar) |
X-Nive-Timestamp |
Segundos desde 1970 |
X-Nive-Signature |
v1= + HMAC-SHA256 hexadecimal |
Corpo:
{ "id": "…", "event": "fiscal.document.authorized", "createdAt": "2026-10-31T15:00:00.000Z", "data": { "documentId": "…", "saleId": "…", "model": 65, "series": 1, "number": 10, "accessKey": "42…", "status": "AUTHORIZED", "protocol": "…", "environment": "PRODUCTION", "issuedAt": "2026-10-31T14:59:58.000Z", "qrCodeUrl": "https://…", "rejection": null, "contingency": null, "cancellation": null, "links": { "document": "/fiscal/documents/…", "xml": "/fiscal/documents/…/xml", "pdf": "/fiscal/documents/…/pdf" } }}Os links são caminhos da API: baixe o XML e o DANFE com a sua chave.
Verificar a assinatura
Seção intitulada “Verificar a assinatura”A assinatura é o HMAC-SHA256 do texto {timestamp}.{corpo bruto} com o segredo whsec_. Calcule sobre o corpo exatamente como recebido e compare em tempo constante. Rejeite timestamps com mais de 5 minutos de diferença.
import { createHmac, timingSafeEqual } from "node:crypto";
function valid(secret, timestamp, rawBody, signature) { const expected = "v1=" + createHmac("sha256", secret) .update(timestamp + "." + rawBody).digest("hex"); const a = Buffer.from(expected), b = Buffer.from(signature); return a.length === b.length && timingSafeEqual(a, b);}Entrega e reenvio
Seção intitulada “Entrega e reenvio”- Responda 2xx em até 10 segundos. Qualquer outra resposta, ou timeout, conta como falha.
- Redirecionamentos não são seguidos.
- Em falha, a Nive reenvia após 1 min, 5 min, 15 min, 1 h, 3 h, 6 h, 12 h e 24 h. Esgotadas as tentativas, a entrega fica como
FAILED. - A entrega é pelo menos uma vez: pode chegar repetida. Deduplique por
X-Nive-Deliveryou pordocumentId+status. - A ordem não é garantida entre documentos. Trate
contingencyseguido deauthorizedcomo o fluxo normal da contingência.
Consulte as últimas entregas em GET /outbound-webhooks/:id/deliveries e reenvie uma falha com POST /outbound-webhooks/:id/deliveries/:deliveryId/retry.
Boa prática
Seção intitulada “Boa prática”Use o webhook como aviso e a consulta (GET /fiscal/documents/by-sale/:saleId) como conferência: se o seu sistema ficou fora do ar por mais de 24 horas, reconcilie por consulta.

