Webhooks¶
Webhooks existem por dialeto, e só onde o provedor de origem os tem.
| Dialeto | Webhooks |
|---|---|
| FocusNFE | Sim. Gatilhos, dois eventos aplicáveis à NFC-e |
| SmartNFCe | Sim. Uma configuração por empresa e ambiente. Ver SmartNFCe |
| ACBrAPI | Não existem. O provedor acompanha por consulta, e nós também |
Quando nada é entregue¶
Comece por aqui. São três situações em que integradores esperam um aviso que deliberadamente não vem. Uma integração construída à espera dele trava sem erro nenhum.
- Entrar em contingência não dispara evento. Um aviso de autorização é sempre uma resposta da SEFAZ, e entrar em contingência não é uma. A entrada você já conhece pelo próprio desfecho da emissão. O que acontece depois chega nos avisos documento a documento da resolução.
- Uma transmissão sem desfecho conhecido não dispara nada. Se a SEFAZ nunca disse o que aconteceu, não há veredito a comunicar. Anunciar uma rejeição que ela não emitiu seria pior do que o silêncio. O aviso vem quando a consulta provar o desfecho.
- Um cancelamento recusado não dispara nada. A recusa não mudou o documento: ele continua autorizado, exatamente como estava.
A regra por trás das três é a mesma, e vale para todos os dialetos: avisamos desfechos, não tentativas.
Gatilhos do FocusNFE¶
A emissão de NFC-e é síncrona, então não há callback de conclusão de emissão: o desfecho já
veio na resposta do POST. Isso se reflete no próprio contrato do provedor, cuja lista de
eventos não tem um evento nfce. Sobram dois, e são os dois que registramos:
| Evento | Quando dispara |
|---|---|
nfce_contingencia |
Um documento emitido em contingência offline foi resolvido (entregue à SEFAZ ou fracassado) |
inutilizacao |
A SEFAZ registrou uma inutilização efetiva |
Tentar registrar qualquer outro evento responde 422.
O gatilho de nfce_contingencia dispara apenas para documentos realmente emitidos em
contingência offline. Um envio comum cujo desfecho foi resolvido depois, por consulta, não
dispara este gatilho. Ele nunca esteve em contingência.
O gatilho de inutilizacao dispara para toda inutilização efetiva da empresa, não só
para as que passaram por este adaptador. Ele inclui as feitas pelo painel e as automáticas.
Só inutilizações efetivas disparam. Recusas da SEFAZ não.
Requisitos do seu endpoint¶
A URL registrada precisa ser alcançável a partir da internet pública:
- Só
httpehttps. Recusamos outros esquemas no registro, com422. - Sem endereços privados. Recusamos no registro os endereços de loopback, de redes privadas, link-local, CGNAT e de metadados de nuvem. A restrição continua valendo a cada envio, não só no cadastro. Um endpoint que aponte para um endereço privado no momento do envio não recebe a requisição: a tentativa apenas conta na escada de retentativas. Para testar localmente, use um túnel com endereço público.
- Não seguimos redirecionamentos. Um
3xxconta como tentativa fracassada. Registre a URL final. - Cabeçalho de autenticação.
authorization_headeraceita letras, números e hífen.authorizationaceita ASCII imprimível. Nós repassamos os dois literalmente, como cabeçalho da requisição de saída.
Registro¶
curl -X POST https://focusnfe.api.veraciti.com.br/v2/hooks \
-u 'SEU_TOKEN_AQUI:' \
-H 'Content-Type: application/json' \
-d '{
"event": "nfce_contingencia",
"url": "https://seu-sistema.exemplo.com.br/veraciti/hooks",
"authorization": "um-segredo-seu",
"authorization_header": "X-Auth-Token"
}'
O CNPJ é o da sua credencial. Informar um CNPJ diferente responde 403. Não aceitamos
registro por cpf, porque os tokens são por empresa.
São no máximo 10 gatilhos ativos por empresa e ambiente, somando os eventos. O registro
seguinte responde 422 erro_validacao pedindo que você exclua um antes.
O limite é nosso e fica num eixo diferente do que o provedor documenta. Ele permite 5 gatilhos por empresa para o mesmo evento. Nós contamos 10 no total, sem olhar o evento. Como a NFC-e tem dois eventos, os dois tetos chegam a dez.
As formas, porém, não batem. O provedor recusa um sexto gatilho num mesmo evento, e nós aceitamos até o décimo no conjunto. Dez gatilhos cobrem várias URLs de destino para cada evento.
DELETE /v2/hooks/{id} desativa o gatilho: ele para de disparar e some da listagem. O
histórico de entregas continua consultável. Nós abandonamos qualquer retentativa pendente ao
encontrar o gatilho inativo. A vaga volta para o limite de dez.
Autenticação da entrega¶
A autenticação é a do provedor, verbatim. Nós enviamos o valor que você registrou em
authorization no cabeçalho nomeado por authorization_header (por padrão,
Authorization). Não há assinatura HMAC. É um segredo compartilhado em cabeçalho.
Trate a URL do seu endpoint como sensível e prefira HTTPS.
Retentativas¶
Nós repetimos uma entrega que não responder 2xx, na escada fixa do provedor: 1 minuto,
30 minutos, 1 hora, 3 horas, 24 horas. São seis tentativas no total, contando a primeira.
Depois da última, nós descartamos o evento, e ele não volta.
O corpo é congelado no momento do disparo: uma retentativa reenvia o que o evento dizia, não o estado que o documento tem agora. Se o seu processamento depende do estado atual, consulte o documento ao receber o gatilho em vez de confiar no corpo.
Faça o seu recebedor idempotente
A entrega é ao menos uma vez. Uma falha nossa entre o envio e o registro do
resultado repete a mesma entrega, com o mesmo corpo congelado. Isso acontece mesmo que
o seu sistema já a tenha processado com sucesso. Trate o gatilho por uma chave própria
(a ref do documento, a faixa da inutilização) e ignore repetições.
Formato do corpo¶
nfce_contingencia envia o corpo de consulta do documento (sem os campos de QR Code, que as
rotas de arquivo servem sob demanda). inutilizacao envia o corpo da resposta de
inutilização. Ambos estão descritos na
referência do FocusNFE.