Webhook e Callbacks
A emissão de uma NFS-e é assíncrona: o módulo envia a nota para a NFE.io, que se comunica com a prefeitura e devolve o resultado depois. Essa devolução chega por webhook — uma chamada HTTP da NFE.io para o seu WHMCS. É o webhook que faz o status da nota sair de "Criada" para "Emitida" sem intervenção manual.
Como funciona
- Na primeira emissão de nota, o módulo verifica se já existe um webhook registrado e válido na NFE.io.
- Se não existir — ou se a URL registrada não corresponder à URL atual do seu WHMCS — o módulo cria um webhook novo automaticamente.
- O identificador e o secret do webhook são armazenados na configuração do módulo.
- A cada mudança de estado da nota, a NFE.io envia um POST assinado para o endpoint de callback do módulo, que valida a assinatura e atualiza o status local.
O webhook é criado com filtros restritos ao ciclo de vida da NFS-e (emissão e cancelamento, incluindo os respectivos estados de sucesso, erro e falha), evitando o recebimento de eventos não relacionados.
Não é preciso cadastrar o webhook no painel da NFE.io. O módulo cuida disso na primeira emissão. Instalações que possuíam webhooks de versões anteriores da API têm o registro substituído automaticamente na próxima emissão.
Endpoint de callback
O endpoint é o arquivo callback.php do módulo, na sua instalação do WHMCS:
https://seu-whmcs.com.br/modules/addons/NFEioServiceInvoices/callback.php
Para que os callbacks funcionem, esse endereço precisa:
- Estar acessível publicamente pela internet, por HTTPS;
- Aceitar requisições POST (outros métodos são recusados com
405); - Não estar bloqueado por WAF, firewall, proteção de bot, autenticação HTTP ou regras de
.htaccess.
Para testar o alcance do endpoint existe uma verificação de saúde que responde ok. Ela exige POST — abrir a URL no navegador retorna 405, o que é o comportamento esperado e não indica problema:
curl -X POST "https://seu-whmcs.com.br/modules/addons/NFEioServiceInvoices/callback.php?echo"
# resposta esperada: ok
Segurança
Cada callback é assinado pela NFE.io com HMAC no cabeçalho X-Hub-Signature, calculado sobre o corpo da requisição usando o secret gerado na criação do webhook. O módulo recalcula a assinatura e compara antes de processar. Requisições sem assinatura ou com assinatura inválida são recusadas com 403 e registradas no Log de Módulo.
Além da assinatura, o módulo compara o ambiente da nota com o ambiente configurado:
| Ambiente de Desenvolvimento no módulo | Callbacks aceitos |
|---|---|
| Marcado | Apenas notas de Development |
| Desmarcado | Apenas notas de Production |
Se não coincidirem, o callback é recusado com 400 e o status da nota não é atualizado. Essa é uma causa comum de notas travadas em "Criada": o módulo em produção com a opção de desenvolvimento marcada, ou o contrário.
Verificando a configuração
Acesse Addons -> NFE.io NFSe -> Sobre. O bloco Webhook de Callbacks exibe:
- URL do Webhook: endpoint local que recebe os callbacks
- ID do Webhook: identificador do webhook registrado na NFE.io
- Secret (mascarado): primeiros caracteres do secret, para conferência
- Última Verificação: data e hora da última validação manual
O botão Verificar Status na API consulta a NFE.io sob demanda e valida:
- se o webhook existe na API;
- se a URL registrada na API é a mesma do WHMCS;
- se o webhook está ativo.
O resultado é exibido como mensagem na própria página e registrado no Log de Módulo.
Mensagens possíveis
| Mensagem | O que significa e o que fazer |
|---|---|
| Webhook não configurado | Nenhuma nota foi emitida ainda. O webhook será criado na primeira emissão |
| Webhook não encontrado na API | O registro foi removido na NFE.io. Será recriado automaticamente na próxima emissão |
| URL divergente | A URL registrada não corresponde à do WHMCS — comum após mudança de domínio. Será corrigida na próxima emissão |
Diagnóstico
Quando notas ficam paradas em um status intermediário, siga esta ordem:
- Atualize o status manualmente. Na listagem de Notas Fiscais, use a ação Atualizar. Se o status muda, a nota está correta na NFE.io e o problema é a entrega do callback.
- Verifique o webhook na página Sobre, com o botão Verificar Status na API.
- Confirme o ambiente. Ambiente de Desenvolvimento marcado em uma instalação de produção rejeita todos os callbacks. Veja Instalação.
- Teste o alcance do endpoint pela internet, de fora da sua rede.
- Consulte o Log de Módulo em
Utilitários → Logs → Log de Módulo, módulonfeio_serviceinvoices. Callbacks recusados são registrados com o motivo: assinatura ausente, assinatura inválida, ambiente incompatível, payload inválido ou nota inexistente no banco local.
A ação Atualizar na listagem de notas sincroniza o status sob demanda e permite operar normalmente enquanto a causa da falha de entrega é investigada.