Skip to main content
Cada conta tem um endpoint de webhook por ambiente: um de produção e um de sandbox. Eventos de notas reais vão só para o endpoint de produção, e eventos de notas de sandbox vão só para o de sandbox. Cada endpoint recebe os eventos de todas as empresas da conta. O campo empresa_cnpj do payload diz de qual empresa é cada evento. A Invo assina cada entrega com HMAC-SHA256 e entrega de forma assíncrona. A entrega HTTP não atrasa a requisição da API nem a mudança de estado da nota.
Os webhooks cobrem só a NF-e (eventos nfe_*). Acompanhe a NFS-e por polling em GET /notas/{id}. Veja o Ciclo de vida.

Configuração

Um administrador da conta configura o endpoint no painel da Invo, em Conta › Credenciais de API › Webhooks. Produção e sandbox têm páginas separadas. O botão Validar do formulário envia um POST de teste com "evento": "webhook_teste". Responda 2xx a esse POST para confirmar que o endpoint está no ar.

Verificação da assinatura

Cada entrega traz dois cabeçalhos: A Invo assina esta string: o valor de X-Webhook-Timestamp, um ponto (.) e o corpo bruto do POST, nessa ordem.
Para verificar uma entrega, calcule o HMAC-SHA256 dessa string com a chave_seguranca do endpoint. Compare o resultado com X-Webhook-Signature por uma comparação de tempo constante, como Rack::Utils.secure_compare. Uma comparação de string comum vaza informação pelo tempo de resposta. O timestamp faz parte da string assinada, então você também pode rejeitar entregas antigas e se proteger contra replay.

Regras de entrega

A entrega não segue ordem e acontece pelo menos uma vez (at-least-once). Cada entrega roda num job próprio, com novas tentativas próprias. Por isso:
  • a ordem dos eventos não é garantida. Um nfe_autorizada rápido pode chegar antes de um nfe_solicitacao_autorizacao que precisou de nova tentativa;
  • o mesmo evento pode chegar mais de uma vez.
Use event_id e occurred_at para tratar esses casos:
1

Deduplique por event_id

Ignore um event_id que você já processou.
2

Ignore eventos mais antigos

Descarte um evento com occurred_at anterior ao último evento já aplicado àquela nota.

Novas tentativas

A Invo espera até 10 segundos pela resposta do seu endpoint e não segue redirecionamentos. A segunda tentativa sai cerca de 5 minutos depois da primeira. O intervalo dobra a cada nova tentativa: 5, 10, 20 minutos e assim por diante. O atraso real pode passar alguns minutos desse valor. Responda 2xx assim que receber o evento e processe depois. Um 4xx encerra as tentativas daquele evento.

Campos comuns

Todo payload traz estes campos:

Tipos de evento (nfe_*)

nfe_inutilizada tem dois formatos de payload

O evento nfe_inutilizada cobre os dois modos de inutilização, e cada modo tem um payload diferente. Use o campo modo para saber o formato. Todo payload traz modo, então você não precisa deduzir o formato pelos campos presentes.
  • Modo nota ("modo": "nota"): traz uuid e chave_acesso de uma nota.
  • Modo faixa ("modo": "faixa"): traz numero_inicial e numero_final de uma faixa de numeração, sem nota associada.
A faixa não tem chave de acesso. Nesse modo, empresa_cnpj é a única forma de saber de qual empresa é a inutilização.
xml_url e danfe_url apontam para as rotas autenticadas da API (HTTP Basic). Elas não são links públicos para os documentos fiscais.