Webhooks
O recurso de Webhooks faz o TryERP avisar um sistema do cliente assim que um documento fiscal muda de situação: quando a NF-e é autorizada, quando é cancelada, quando o MDF-e é encerrado. O aviso é uma chamada HTTP para um endereço que o próprio cliente cadastra. Em uma frase: em vez de o sistema do cliente ficar perguntando "já autorizou?", o TryERP avisa quando autoriza.
- 1 - Visão geral e conceito
- 2 - Configuração inicial
- 3 - Cadastrar um endpoint
- 4 - Eventos e o conteúdo enviado
- 5 - Entrega, reenvio e histórico
- 6 - Guia para o desenvolvedor do endpoint
- 7 - Troubleshooting e glossário
1 - Visão geral e conceito
O recurso de Webhooks faz o TryERP avisar um sistema do cliente assim que um documento fiscal muda de situação: quando a NF-e é autorizada, quando é cancelada, quando o MDF-e é encerrado. O aviso é uma chamada HTTP para um endereço que o próprio cliente cadastra.
Em uma frase: em vez de o sistema do cliente ficar perguntando "já autorizou?", o TryERP avisa quando autoriza.
1. Por que isso existe
Quem usa este recurso normalmente já contratou a API do TryERP e consegue ler os dados da nota por lá. O problema nunca foi o acesso ao dado — era saber a hora certa de buscar.
Sem webhook, a única saída é o sistema do cliente consultar a API de tempos em tempos (polling). Isso tem três defeitos conhecidos:
| Problema do polling | Consequência prática |
|---|---|
| Consulta que quase sempre volta vazia | Gasto de processamento e banda dos dois lados para não descobrir nada |
| Intervalo grande | O sistema do cliente demora a reagir — o pedido fica parado esperando a nota que já existe |
| Intervalo pequeno | Carga desnecessária no servidor, que cresce com o número de clientes integrados |
O webhook não substitui a API — ele a complementa. A notificação carrega a chave de acesso, o protocolo e os dados de identificação do documento. Se o sistema do cliente precisar do XML, dos itens ou dos impostos, ele continua buscando na API, só que na hora certa, uma vez, em vez de ficar perguntando.
2. O que dispara uma notificação
| Documento | Autorização | Cancelamento | Encerramento |
|---|---|---|---|
| NF-e (modelo 55) | Sim | Sim | — |
| NFC-e (modelo 65) | Sim | Sim | — |
| CT-e | Sim | Sim | — |
| CT-e OS | Sim | — | — |
| MDF-e | Sim | Sim | Sim |
O cancelamento de CT-e OS não dispara porque o próprio sistema ainda não implementa esse evento. O encerramento só existe no MDF-e.
Só há notificação quando a SEFAZ confirma o evento. Rejeição não notifica, lote em processamento não notifica, erro de comunicação não notifica. O webhook avisa fato consumado — nunca tentativa.
3. A garantia de entrega, e por que ela foi feita assim
Um endpoint do cliente pode estar fora do ar exatamente no minuto em que a nota é autorizada. Se a notificação fosse "tenta uma vez e esquece", o cliente perderia o aviso e nunca saberia disso. O desenho evita esse buraco em três camadas:
| # | Camada | O que faz |
|---|---|---|
| 1 | Registro junto com o documento | No instante em que o sistema grava "nota autorizada", ele grava também a notificação pendente — na mesma transação. Ou as duas coisas existem, ou nenhuma existe |
| 2 | Envio imediato | Logo depois, a notificação é enviada em segundo plano. É o caminho normal: o cliente recebe em segundos |
| 3 | Rede de segurança | Uma rotina roda a cada 2 minutos e reenvia tudo que não conseguiu sair — endpoint fora do ar, sistema fechado antes do envio terminar, queda de rede |
O efeito prático da camada 1 é o que importa: se a nota foi autorizada, a notificação existe. Ela pode demorar, pode precisar de várias tentativas, pode ser reenviada manualmente — mas não some. Não existe o caso "a nota autorizou e ninguém nunca soube".
4. O que o recurso deliberadamente não faz
- Não envia o XML nem o DANFE. A notificação é um aviso enxuto com a chave e o protocolo; o arquivo vem da API. Mandar XML por webhook engordaria cada chamada e obrigaria a repetir tudo a cada tentativa de reenvio.
- Não tenta para sempre. Há um limite de tentativas por endpoint (padrão 5). Depois disso a notificação fica marcada como Descartado e espera reenvio manual — o sistema não fica batendo indefinidamente em um endereço que não responde.
- Não garante ordem. Se duas notas são autorizadas no mesmo segundo, não há promessa de que cheguem na ordem de emissão.
- Não avisa rejeição. Ver o callout da seção 2.
5. Quem não usa não paga nada por isso
Esta é uma decisão de projeto que vale registrar, porque protege a empresa inteira: enquanto não houver nenhum endpoint cadastrado e ativo, o recurso não custa nada no fluxo de emissão.
O sistema mantém em memória a lista de quais filiais têm webhook ativo e a atualiza no máximo uma vez por minuto. Na emissão, a verificação é uma consulta a essa lista em memória — não há consulta ao banco por nota emitida, nem processo de envio iniciado. Para quem nunca vai usar o recurso, a emissão continua exatamente como era.
6. O ciclo completo, e quem faz cada parte
| # | Passo | Quem faz | Onde |
|---|---|---|---|
| 1 | Construir o endereço que vai receber as notificações | Desenvolvedor do cliente | Capítulo Guia para o desenvolvedor do endpoint |
| 2 | Liberar o acesso à tela e conferir a rede | Administrador | Capítulo Configuração inicial |
| 3 | Cadastrar o endpoint e testar | Responsável pela integração | Capítulo Cadastrar um endpoint |
| 4 | Combinar com o cliente o que será enviado | Responsável pela integração | Capítulo Eventos e o conteúdo enviado |
| 5 | Acompanhar entregas e reenviar o que falhou | Responsável pela integração / suporte | Capítulo Entrega, reenvio e histórico |
Próximo capítulo: Configuração inicial — o que precisa estar em ordem antes de cadastrar o primeiro endpoint.
2 - Configuração inicial
Este capítulo cobre o que precisa estar em ordem antes de cadastrar o primeiro endpoint. São quatro coisas: acesso à tela, um endereço do lado do cliente, saída de rede a partir das estações, e a rotina de reenvio ligada.
1. Onde fica a tela
A tela é cadastrada com restrição de acesso de propósito. Ela guarda o HMAC secret e os headers de autenticação do sistema do cliente — ou seja, credenciais de terceiros. Tratar como tela de administrador: liberar apenas para quem cuida de integrações, nunca para o operador de balcão.
2. O endereço do lado do cliente
O cliente precisa fornecer uma URL que aceite a chamada e responda rápido. Não adianta cadastrar antes de existir: o teste vai falhar e o histórico vai encher de tentativa perdida.
O que combinar com o cliente antes de cadastrar:
-
A URL completa, com
https://— inclusive o caminho (ex.:https://sistema.cliente.com.br/integracao/tryerp/fiscal) - Como autenticar — se o endpoint exige algum header (um token, uma chave de API) e qual é
- Se vai validar assinatura — e, nesse caso, qual será o segredo compartilhado (ver capítulo Cadastrar um endpoint)
- Quais eventos interessam — quase sempre autorização e cancelamento; encerramento só faz sentido para quem usa MDF-e
O capítulo Guia para o desenvolvedor do endpoint foi escrito para ser enviado direto ao programador do cliente. Ele é autocontido e explica o contrato inteiro — formato, headers, assinatura, o que responder e como se comportar em caso de repetição. Mandar essa página adiantada economiza várias idas e vindas.
3. A rede: quem chama é a estação, não o servidor
Este é o ponto que mais gera surpresa, então vale entender antes de cadastrar.
Quem faz a chamada HTTP é o TryERP rodando na estação — a mesma máquina que emitiu o documento (no envio imediato) ou a máquina designada para a rotina de reenvio. Não existe um servidor central da tryideas fazendo essa chamada.
| Consequência | O que verificar |
|---|---|
| A saída HTTPS precisa estar liberada nas estações | Firewall/proxy da rede do cliente permite as estações alcançarem a URL cadastrada |
| URL interna só funciona se for enxergada dali | Se o endpoint é http://192.168.0.x, ele precisa estar na mesma rede das estações. Endereço interno de outra rede não vai resolver |
| Não é preciso abrir porta de entrada no cliente do TryERP | O tráfego é de saída. Quem precisa estar publicamente acessível é o endpoint do destinatário |
Se a rede usa proxy com autenticação, a chamada vai falhar com erro de conexão e o histórico vai mostrar isso como falha do endpoint — quando o problema é a saída da rede. Testar com o botão Testar envio na própria estação antes de culpar o destinatário.
4. A rotina de reenvio
A rede de segurança (a rotina que reenvia o que falhou) é iniciada junto com o sistema e roda a cada 2 minutos. Ela só é ativada em uma instância por máquina — se o operador abre dois TryERP no mesmo computador, apenas o primeiro executa a varredura.
Isso é proposital: evita que várias estações fiquem varrendo a mesma fila ao mesmo tempo. Mesmo que duas máquinas diferentes rodem a rotina, o sistema reserva cada notificação antes de enviar, então não há envio em duplicidade.
Consequência operacional: com todos os TryERP fechados, nada é reenviado. As notificações pendentes ficam guardadas e saem quando alguém abrir o sistema. Em operação normal isso não aparece, porque o envio imediato já resolveu; só importa no cenário de endpoint que ficou fora do ar durante a noite.
5. Conferência rápida antes de seguir
| Item | Como confirmar |
|---|---|
| Tela acessível | O item aparece no menu e abre sem erro de permissão |
| Filial correta disponível | O campo Emitente/Filial no topo lista a filial que vai emitir |
| Endereço do cliente no ar | O cliente confirma que o endpoint responde |
| Saída de rede liberada | Botão Testar envio retorna sucesso (capítulo seguinte) |
Próximo capítulo: Cadastrar um endpoint — campo a campo, e o teste de conectividade.
3 - Cadastrar um endpoint
A aba Endpoints tem a lista de endereços cadastrados à esquerda e o formulário Configuração do Endpoint à direita. Uma filial pode ter vários endpoints — cada um com seus próprios filtros, autenticação e política de tentativas.
1. Selecionar a filial
O campo Emitente/Filial, no topo da tela, define de quem são os endpoints listados. Ele vale para as duas abas. Trocar a filial recarrega a lista e o histórico.
O endpoint pertence à filial, não à empresa. Se o cliente emite por três filiais e quer ser avisado das três, são três cadastros — ou o sistema dele só vai receber as notas de uma. É o engano mais comum na primeira configuração.
2. Os campos, um a um
| Campo | Para que serve |
|---|---|
| Descrição | Texto livre para você identificar o cadastro na lista (ex.: "ERP do cliente — produção"). Não vai na notificação |
| URL | O endereço que receberá a chamada. Único campo obrigatório |
| Método HTTP |
POST ou GET. Ver a seção 3 |
| Nível detalhe |
Resumido ou Completo — quanto de informação vai no corpo. Ver capítulo Eventos e o conteúdo enviado
|
| Documentos | Lista marcável: NFe, NFCe, CTe, CTeOS, MDFe. Só os marcados notificam |
| Eventos | Lista marcável: Autorizacao, Cancelamento, Encerramento |
| Headers (JSON) | Cabeçalhos HTTP extras, em formato JSON. Ver a seção 4 |
| Assinar corpo com HMAC-SHA256 | Liga a assinatura do corpo. Ver a seção 5 |
| HMAC secret | O segredo compartilhado usado na assinatura. Exibido mascarado |
| Timeout (s) | Quanto esperar pela resposta antes de considerar falha. Padrão 30 |
| Tentativas máx. | Quantas tentativas antes de desistir. Padrão 5 |
| Ativo | Desmarcado, o endpoint para de receber notificações — sem perder o cadastro |
Os filtros Documentos e Eventos são cruzados: um endpoint com NFe + NFCe e Autorizacao recebe autorização de NF-e e de NFC-e, e nada mais. O Encerramento só ocorre em MDF-e, então marcá-lo sem marcar MDFe não tem efeito.
3. POST ou GET
| POST (recomendado) | GET | |
|---|---|---|
| Como os dados vão | Corpo da requisição, em JSON | Query string na URL |
| Conteúdo | Payload completo, incluindo blocos aninhados (destinatário, valores) | Só os campos simples — o que está aninhado não vai |
| Assinatura HMAC | Disponível | Indisponível — não há corpo para assinar |
Use GET apenas quando o sistema do cliente não souber receber POST. Além de perder a assinatura e os blocos aninhados, dados de nota fiscal passam a trafegar na URL — e URL costuma ser gravada em log de servidor, de proxy e de firewall.
4. Headers (JSON)
Serve para atender a autenticação que o endpoint do cliente exigir. O conteúdo é um objeto JSON simples, com um par por cabeçalho:
{ "Authorization": "Bearer eyJhbGciOi...", "x-api-key": "9f3c2b1e-..." }
Deixe em branco se o endpoint não exige autenticação. O Content-Type não precisa ser informado — o sistema já envia application/json no POST.
Se o JSON estiver malformado, os cabeçalhos são simplesmente ignorados e a chamada segue sem eles — o envio não quebra. Na prática isso aparece como 401 ou 403 vindo do endpoint. Ao investigar uma falha de autenticação, conferir este campo primeiro.
5. Assinatura HMAC-SHA256
Marcando Assinar corpo com HMAC-SHA256 e preenchendo o HMAC secret, cada chamada leva o cabeçalho X-TryERP-Signature com a assinatura do corpo.
Isso responde a uma pergunta que o sistema do cliente não consegue responder sozinho: "esta chamada veio mesmo do TryERP, ou alguém descobriu a URL?" Quem conhece o segredo consegue recalcular a assinatura; quem não conhece, não.
O segredo é combinado entre as duas pontas — pode ser qualquer texto longo e aleatório. Ele não trafega na chamada: o que viaja é o resultado do cálculo. O procedimento de validação está no capítulo Guia para o desenvolvedor do endpoint.
6. Testar envio
O botão Testar envio manda ao endereço informado uma notificação de exemplo, com "evento": "TESTE" e uma chave de acesso fictícia de 44 zeros. Usa exatamente o que está na tela — URL, método, headers, HMAC e timeout — mesmo que você ainda não tenha salvo.
O resultado aparece numa mensagem com o código HTTP e o início da resposta.
O teste não entra na fila e não aparece no histórico: é uma chamada avulsa, só para validar conectividade, autenticação e assinatura. Pode ser repetido à vontade sem sujar o registro de entregas.
7. Salvar, criar outro, excluir
- Salvar grava o endereço em edição. A URL é obrigatória e a filial precisa estar selecionada
- Novo limpa o formulário para um cadastro novo, já com todos os documentos e eventos marcados e os padrões de timeout e tentativas
- Excluir apaga o endpoint selecionado na lista, com confirmação
Para suspender temporariamente as notificações, desmarque Ativo em vez de excluir. Excluir perde a configuração, e o histórico das notificações daquele endpoint deixa de ter a quem se referir.
8. Faça e não faça
| Faça | Não faça |
|---|---|
| Testar antes de salvar, na estação que vai emitir | Cadastrar e assumir que funciona porque a URL "está certa" |
| Marcar só os documentos e eventos que o cliente pediu | Deixar tudo marcado "por garantia" — gera chamada que o cliente descarta |
Usar https://
|
Usar http:// na internet, ainda mais sem HMAC |
| Usar HMAC quando o endpoint é público | Confiar que ninguém vai descobrir a URL |
| Timeout curto (10–30 s) | Timeout alto, que prende o envio esperando um endpoint lento |
| Um cadastro por filial que emite | Um cadastro só, esperando receber de todas as filiais |
Próximo capítulo: Eventos e o conteúdo enviado — o que exatamente sai em cada notificação.
4 - Eventos e o conteúdo enviado
Este capítulo descreve quando a notificação sai e o que vai dentro dela. É o material que você precisa ter em mãos para combinar a integração com o cliente.
1. O momento exato de cada evento
A notificação nasce quando a SEFAZ confirma o evento e o sistema grava essa confirmação. Na prática, cada evento corresponde a uma situação (cStat) do documento:
| Evento | Situação que dispara | Significado |
|---|---|---|
| AUTORIZADA |
100, 120 ou 150
|
Autorizado, autorizado com alerta, autorizado fora do prazo |
| CANCELADA |
101 (e 151 na consulta) |
Cancelamento homologado |
| ENCERRADA | 132 |
Encerramento de MDF-e homologado |
O 120 — autorizado com alerta, criado pela NT 2026.002 — conta como autorizada e notifica normalmente. Ele só ocorre em NF-e e NFC-e. A nota está válida; o alerta é uma observação da SEFAZ, não um impedimento.
2. A notificação também nasce na consulta de situação
Nem sempre a resposta da SEFAZ chega na hora do envio: o lote pode ficar em processamento, a conexão pode cair depois de enviado. Nesses casos o sistema descobre o desfecho depois, ao consultar a situação do documento — e a notificação é gerada nesse momento.
O sistema controla isso por documento e evento: se a notificação da autorização já foi criada no envio, a consulta não cria outra. O cliente não recebe o mesmo evento duas vezes por causa de uma reconsulta.
3. O corpo da notificação
No método POST, o corpo é um JSON com Content-Type: application/json. Exemplo no nível Resumido:
{
"versaoPayload": "1.0",
"evento": "AUTORIZADA",
"tipoDocumento": "NFe",
"ambiente": "producao",
"dataEvento": "2026-09-20T14:32:07-03:00",
"documento": {
"id": 18442,
"modelo": "55",
"serie": "1",
"numero": 4471,
"chaveAcesso": "35260912345678000199550010000044711234567890",
"protocolo": "135260004471234",
"cStat": 100,
"motivo": "Autorizado o uso da NF-e"
},
"emitente": {
"cnpj": "12345678000199",
"razaoSocial": "EMPRESA EXEMPLO LTDA"
}
}
4. Os campos
| Campo | Conteúdo |
|---|---|
versaoPayload |
Versão do formato. Hoje "1.0". Existe para o cliente conseguir evoluir sem quebrar |
evento |
AUTORIZADA, CANCELADA ou ENCERRADA
|
tipoDocumento |
NFe, NFCe, CTe, CTeOS ou MDFe
|
ambiente |
producao ou homologacao
|
dataEvento |
Data/hora do evento, com fuso (ISO 8601) |
documento.id |
Código interno do documento no TryERP — é o que a API usa |
documento.chaveAcesso |
Chave de 44 dígitos |
documento.protocolo |
Protocolo da autorização — ou do cancelamento, quando o evento é CANCELADA |
documento.cStat / motivo
|
Código e descrição devolvidos pela SEFAZ |
emitente.cnpj / razaoSocial
|
Identificação da filial emitente |
Campo sem valor vai como null, não é omitido. O sistema do cliente deve tratar null em vez de assumir que a chave não existe.
5. Resumido ou Completo
O nível Completo mantém tudo do Resumido e acrescenta:
| Campo adicional | Conteúdo |
|---|---|
documento.dataEmissao |
Data de emissão do documento |
documento.naturezaOperacao |
Natureza da operação |
documento.valorTotal |
Valor total do documento |
destinatario.nome |
Razão social / nome do destinatário |
destinatario.cnpjCpf |
CNPJ ou CPF do destinatário |
destinatario.inscricaoEstadual |
Inscrição estadual do destinatário |
O Completo coloca dado de terceiro (o destinatário da nota) dentro da notificação. Se o endpoint do cliente é hospedado fora, isso é tráfego de dado pessoal e deve ser uma decisão consciente. Resumido é o padrão certo para quem tem a API: com a chave e o id, o cliente busca o resto quando precisar — e só do que precisar.
6. Os cabeçalhos que acompanham
| Cabeçalho | Conteúdo |
|---|---|
X-TryERP-Delivery |
Número único da entrega. Repetido em toda tentativa da mesma notificação — é a chave para o cliente não processar duas vezes |
X-TryERP-Event |
O evento (AUTORIZADA, CANCELADA, ENCERRADA) |
X-TryERP-Signature |
Só quando a assinatura está ligada. Formato sha256=<hexadecimal>
|
Além desses, vão os cabeçalhos configurados em Headers (JSON) e o Content-Type: application/json.
7. No método GET
Com GET não há corpo. Os campos simples viram query string — os do primeiro nível e os de documento:
https://sistema.cliente.com.br/integracao?versaoPayload=1.0&evento=AUTORIZADA&tipoDocumento=NFe&ambiente=producao&id=18442&chaveAcesso=35260912...&protocolo=135260004471234&cStat=100
Os blocos emitente e destinatario não são enviados no GET, e não há assinatura. Os cabeçalhos de rastreio continuam indo.
Próximo capítulo: Entrega, reenvio e histórico — como acompanhar o que saiu e tratar o que falhou.
5 - Entrega, reenvio e histórico
Toda notificação gerada fica registrada, com o resultado de cada tentativa. A aba Histórico de Notificações é onde se acompanha isso e onde se resolve o que falhou.
1. Os dois caminhos de entrega
| Caminho | Quando age | Alcance |
|---|---|---|
| Envio imediato | Logo após o documento ser gravado como autorizado/cancelado/encerrado | Só as notificações daquele documento, a partir da estação que emitiu |
| Rede de segurança | A cada 2 minutos | Tudo que está pendente ou falhou e já está na hora de tentar de novo |
No dia a dia, quem entrega é o envio imediato — o cliente recebe em segundos. A rede de segurança existe para os casos em que ele não deu conta: endpoint fora do ar, rede instável, ou o sistema fechado antes de o envio terminar.
2. As quatro situações
| Status | Significa | Ainda vai tentar? |
|---|---|---|
| Pendente | Gerada, ainda não entregue | Sim |
| Enviado | O endpoint respondeu com sucesso (HTTP 2xx) | Não — encerrada |
| Falhou | A tentativa não deu certo, mas ainda há tentativas no limite | Sim, depois do intervalo |
| Descartado | Esgotou o Tentativas máx. do endpoint | Não — só por reenvio manual |
Sucesso é qualquer HTTP 2xx. Qualquer outra coisa — 4xx, 5xx, timeout, DNS que não resolve, conexão recusada — conta como falha e entra na fila de nova tentativa. Um 404 por URL errada é tratado como falha temporária e vai consumir todas as tentativas; não há como o sistema distinguir isso de uma indisponibilidade.
3. O intervalo entre tentativas
As tentativas são espaçadas de forma crescente, para não martelar um endpoint que está com problema:
| Tentativa que falhou | Próxima em |
|---|---|
| 1ª | 1 minuto |
| 2ª | 5 minutos |
| 3ª | 15 minutos |
| 4ª | 1 hora |
| 5ª em diante | 6 horas |
Com o padrão de 5 tentativas, uma notificação cuja primeira tentativa falha percorre pouco mais de 1 hora e 20 minutos antes de ser descartada. Aumentar Tentativas máx. estende essa janela em blocos de 6 horas.
Esse desenho dá folga real para uma manutenção do lado do cliente: uma indisponibilidade de meia hora é absorvida sem intervenção, e o cliente recebe a notificação atrasada, não perdida.
4. A aba Histórico de Notificações
Mostra as últimas 500 notificações da filial selecionada, da mais recente para a mais antiga.
| Coluna | Conteúdo |
|---|---|
| Documento | NFE, NFCE, CTE, CTEOS ou MDFE |
| Evento | AUTORIZADA, CANCELADA ou ENCERRADA |
| Chave | Chave de acesso do documento |
| Status | Pendente, Enviado, Falhou ou Descartado |
| Tentativas | Quantas já foram feitas |
| HTTP | Código devolvido na última tentativa (vazio se nem chegou a conectar) |
| Criação | Quando a notificação foi gerada |
| Envio | Quando foi entregue com sucesso |
| Último erro | A mensagem da última falha |
O campo Status no topo filtra a lista (Todos, Pendente, Enviado, Falhou, Descartado) e Atualizar recarrega. A lista não se atualiza sozinha.
Para achar problema rápido, filtre por Descartado: é a lista do que o cliente não recebeu e não vai receber sem ação. Falhou ainda está em tratamento automático.
5. Reenviar
Selecione a linha e clique em Reenviar selecionado. A notificação volta para Pendente, o contador de tentativas é zerado e o envio é disparado na hora.
Serve para quando a causa da falha já foi resolvida: a URL foi corrigida, o token foi renovado, o servidor do cliente voltou. Reenviar sem corrigir a causa só vai repetir a falha.
O reenvio manda o mesmo conteúdo gravado quando a notificação nasceu, não uma versão atualizada do documento. Se a nota foi autorizada e depois cancelada, a notificação de autorização reenviada continua dizendo AUTORIZADA — e é o correto: ela relata o evento daquele momento. O cancelamento tem a notificação dele.
O mesmo vale para o número da entrega (X-TryERP-Delivery): o reenvio mantém o número original. Um endpoint que controle idempotência por esse número vai reconhecer a repetição — o que é o comportamento desejado.
6. Limpeza automática
Notificações com status Enviado há mais de 30 dias são apagadas automaticamente pela rotina de reenvio. O histórico não cresce para sempre.
O que não é apagado: Pendente, Falhou e Descartado. Eles ficam até serem resolvidos ou removidos manualmente — justamente para que um problema antigo não desapareça sozinho do histórico.
O corpo da resposta do endpoint e a mensagem de erro são guardados truncados em 4.000 caracteres. Para diagnosticar, isso basta; o log completo fica do lado do cliente.
Próximo capítulo: Guia para o desenvolvedor do endpoint — a página que pode ser enviada a quem vai construir o receptor.
6 - Guia para o desenvolvedor do endpoint
Esta página descreve o contrato de integração dos webhooks de eventos fiscais do TryERP. Ela é destinada a quem vai construir o serviço que recebe as notificações, e é autossuficiente: tudo o que você precisa para implementar e testar está aqui.
1. O que você vai receber
Sempre que um documento fiscal for autorizado, cancelado ou (no caso do MDF-e) encerrado pela SEFAZ, o TryERP fará uma chamada HTTP ao endereço que você informar.
Os documentos cobertos são NF-e, NFC-e, CT-e, CT-e OS e MDF-e. A notificação avisa que o evento aconteceu e entrega a chave de acesso, o protocolo e a identificação do documento. Os dados completos (itens, impostos, XML) continuam disponíveis pela API REST — a notificação existe para você saber a hora exata de buscá-los, em vez de consultar periodicamente.
A chamada parte da estação onde o documento foi emitido, não de um servidor central. Na prática, a origem das requisições pode variar entre os IPs de saída do cliente — evite regra de firewall presa a um IP único; prefira autenticação por cabeçalho ou assinatura.
2. Formato da requisição
Por padrão é POST com Content-Type: application/json. O corpo:
{
"versaoPayload": "1.0",
"evento": "AUTORIZADA",
"tipoDocumento": "NFe",
"ambiente": "producao",
"dataEvento": "2026-09-20T14:32:07-03:00",
"documento": {
"id": 18442,
"modelo": "55",
"serie": "1",
"numero": 4471,
"chaveAcesso": "35260912345678000199550010000044711234567890",
"protocolo": "135260004471234",
"cStat": 100,
"motivo": "Autorizado o uso da NF-e"
},
"emitente": {
"cnpj": "12345678000199",
"razaoSocial": "EMPRESA EXEMPLO LTDA"
}
}
| Campo | Valores / conteúdo |
|---|---|
versaoPayload |
Versão do formato. Hoje 1.0
|
evento |
AUTORIZADA · CANCELADA · ENCERRADA
|
tipoDocumento |
NFe · NFCe · CTe · CTeOS · MDFe
|
ambiente |
producao · homologacao
|
dataEvento |
ISO 8601 com fuso horário |
documento.id |
Identificador do documento no sistema — é o que a API usa |
documento.chaveAcesso |
44 dígitos |
documento.protocolo |
Protocolo da autorização; no evento CANCELADA, o protocolo do cancelamento |
documento.cStat |
Código da SEFAZ: 100/120/150 autorizada, 101 cancelada, 132 encerrada |
Dependendo da configuração, o corpo pode trazer também documento.dataEmissao, documento.naturezaOperacao, documento.valorTotal e um bloco destinatario com nome, cnpjCpf e inscricaoEstadual.
Programe de forma tolerante: campos sem valor chegam como null (não são omitidos) e campos novos podem ser acrescentados em versões futuras. Não trate campo desconhecido como erro, e use versaoPayload se precisar diferenciar formatos.
3. Cabeçalhos
| Cabeçalho | Conteúdo |
|---|---|
X-TryERP-Delivery |
Identificador numérico da notificação. O mesmo valor se repete em toda retentativa |
X-TryERP-Event |
O evento: AUTORIZADA, CANCELADA ou ENCERRADA
|
X-TryERP-Signature |
Assinatura do corpo, quando habilitada. Formato sha256=<hex>
|
Cabeçalhos adicionais de autenticação (por exemplo Authorization ou x-api-key) podem ser configurados conforme o que o seu serviço exigir — basta informar quais são.
4. Validar a assinatura
Se a assinatura estiver habilitada, as duas pontas combinam um segredo compartilhado. O valor de X-TryERP-Signature é o HMAC-SHA256 do corpo bruto da requisição, em hexadecimal minúsculo, prefixado por sha256=.
Para validar:
- Leia o corpo da requisição exatamente como chegou, em bytes, antes de desserializar o JSON
- Calcule
HMAC-SHA256(corpo, segredo)e converta para hexadecimal minúsculo - Compare com o valor recebido, descontando o prefixo
sha256= - Se não bater, responda
401e descarte a mensagem
Dois cuidados que costumam passar batido: (1) calcule sobre o corpo original — se você desserializar e reserializar o JSON, os bytes mudam e a assinatura nunca vai conferir; (2) use comparação resistente a temporização (a função de comparação segura da sua linguagem), não o operador de igualdade de texto.
5. O que responder
| Sua resposta | O que acontece |
|---|---|
Qualquer 2xx
|
Notificação considerada entregue. Não haverá nova tentativa |
Qualquer outra coisa (4xx, 5xx, timeout, conexão recusada) |
Considerada falha. Será reenviada conforme a tabela da seção 6 |
Responda rápido. O tempo limite padrão é de 30 segundos, e ultrapassá-lo conta como falha — mesmo que você tenha processado tudo corretamente. O resultado é reprocessamento desnecessário do seu lado.
O padrão recomendado: receba, valide a assinatura, grave numa fila interna e responda 200 imediatamente. Faça o processamento pesado (buscar o XML na API, dar baixa no pedido, emitir etiqueta) depois, fora do ciclo da requisição.
6. Retentativas
Quando uma tentativa falha, a próxima vem depois de um intervalo crescente:
| Tentativa que falhou | Próxima em |
|---|---|
| 1ª | 1 minuto |
| 2ª | 5 minutos |
| 3ª | 15 minutos |
| 4ª | 1 hora |
| 5ª em diante | 6 horas |
Com a configuração padrão são 5 tentativas. Esgotadas, a notificação é marcada como descartada e só sai de novo por reenvio manual do lado do emissor — que pode ser solicitado a qualquer momento.
7. Idempotência: o ponto mais importante
O modelo de entrega é pelo menos uma vez. Você vai receber a mesma notificação mais de uma vez em algumas situações: sua resposta demorou mais que o tempo limite (você processou, mas o emissor entendeu como falha), houve reenvio manual, ou a rede cortou depois de você responder.
Use o X-TryERP-Delivery como chave de idempotência: guarde os identificadores já processados e, ao receber um repetido, responda 200 sem reprocessar. Sem isso, um único reenvio pode duplicar baixa de pedido, etiqueta ou lançamento financeiro.
Como reforço, a combinação documento.chaveAcesso + evento também identifica o fato de forma única e serve de checagem secundária.
8. Outros pontos do contrato
-
Ordem não é garantida. Documentos emitidos quase ao mesmo tempo podem chegar fora da ordem de emissão. Use
dataEventose a ordem importar - Autorização e cancelamento são notificações independentes. Se uma nota é autorizada e depois cancelada, chegam duas notificações, cada uma com seu evento e seu protocolo
-
O ambiente vem no corpo. Trate
homologacaocomo teste — nunca gere efeito real (faturamento, expedição) a partir dele -
Notificação de teste. Durante a configuração, o emissor pode disparar uma chamada de verificação com
eventoigual aTESTEe chave de acesso composta de 44 zeros. Trate-a respondendo200e ignorando o conteúdo -
Método GET. Se o seu serviço não puder receber
POST, é possível configurarGET: os campos simples vão na query string. Nesse modo não há corpo, portanto não há assinatura e os blocos aninhados não são enviados. Só use se não houver alternativa
9. Roteiro de implementação
- Publique um endereço
HTTPSque aceitePOST - Informe ao emissor a URL, os cabeçalhos de autenticação necessários e se vai usar assinatura
- Peça o disparo da notificação de teste e confirme que ela chega, autentica e assina corretamente
- Implemente a validação da assinatura e o controle de idempotência antes de ligar em produção
- Responda
200de imediato e processe de forma assíncrona - Registre em log o
X-TryERP-Deliveryde tudo que receber — é por ele que as duas pontas conseguem investigar um caso específico
7 - Troubleshooting e glossário
Este capítulo reúne os erros que aparecem no dia a dia, os casos que costumam confundir, o glossário e o que reunir antes de abrir um chamado.
1. Onde olhar primeiro
Quase todo diagnóstico começa na aba Histórico de Notificações, filtrando por Falhou ou Descartado e lendo a coluna Último erro junto com a coluna HTTP. As duas juntas separam "não consegui chegar no endereço" de "cheguei e ele recusou".
| Coluna HTTP | Leitura |
|---|---|
| Vazia | Não houve resposta: DNS, firewall, proxy, endereço errado ou timeout |
| Preenchida | A chamada chegou. O problema está no que o endpoint respondeu |
2. Erros comuns
| Mensagem / sintoma | Causa provável | O que fazer |
|---|---|---|
| Timeout ao conectar/responder no endpoint (30s) | O endpoint não respondeu no prazo — ou está lento, ou processa tudo antes de responder | Pedir ao cliente que responda 200 primeiro e processe depois. Aumentar o Timeout é paliativo |
| HTTP 401 ou 403 | Autenticação. Header ausente, token vencido, ou o JSON do campo Headers está malformado e foi ignorado | Conferir o campo Headers (JSON) e validar com Testar envio. Se usa HMAC, conferir se o segredo é o mesmo dos dois lados |
| HTTP 404 | URL errada, ou a rota mudou do lado do cliente | Corrigir a URL e usar Reenviar selecionado no que ficou para trás |
| HTTP 500 | O endpoint recebeu e quebrou ao processar | É do lado do cliente. Passar o X-TryERP-Delivery da linha para ele localizar no log dele |
| Erro de conexão / nome não resolvido | DNS, firewall ou proxy da rede das estações | Testar da própria estação. Ver o capítulo Configuração inicial, seção 3 |
| Nada é gerado após autorizar | Sem endpoint ativo para aquela filial, ou o documento/evento não está marcado | Conferir a filial no topo, o Ativo, e as listas Documentos e Eventos |
| Cliente diz que recebeu duas vezes | Comportamento esperado do modelo "pelo menos uma vez" | O endpoint precisa tratar idempotência pelo X-TryERP-Delivery. Ver capítulo Guia para o desenvolvedor
|
| Fica em Pendente e não sai | Nenhum TryERP aberto para rodar a rotina de reenvio | Abrir o sistema. Confirmar que a estação não está com duas instâncias (só a primeira roda a rotina) |
| Testar envio funciona, mas as notificações falham | O teste roda na estação onde você está; a emissão pode ocorrer em outra, com regra de rede diferente | Repetir o teste na estação que emite |
3. Casos e cuidados
Endpoint cadastrado na filial errada. É o engano mais comum. O endpoint pertence à filial selecionada no topo da tela; documentos emitidos por outra filial não notificam. Empresa com três filiais emitindo precisa de três cadastros.
Rejeição não notifica. Se o cliente reclama que "a nota saiu e não chegou aviso", confirmar antes a situação do documento: só autorizada (100, 120, 150), cancelada (101) e encerrada (132) geram notificação. Rejeição e lote em processamento, não.
Nota autorizada com alerta (120) notifica normalmente. A situação foi criada pela NT 2026.002 e vale como autorizada. Se o sistema do cliente só trata 100, ele vai descartar uma nota válida — vale avisar na integração.
O reenvio manda o conteúdo original. Ele não recalcula o payload com o estado atual do documento. Uma notificação de AUTORIZADA reenviada depois do cancelamento continua dizendo AUTORIZADA — e está correto: ela relata o evento daquele momento. O cancelamento tem a notificação própria.
Trocar o HMAC secret quebra as notificações em trânsito. As que estiverem pendentes serão assinadas com o segredo novo. Combinar a troca com o cliente, e só depois salvar — senão o endpoint dele passa a recusar tudo com 401 até alguém perceber.
Excluir um endpoint não apaga o histórico dele, mas as notificações passam a apontar para um cadastro que não existe mais. Para parar de notificar, prefira desmarcar Ativo.
4. Limpeza do histórico
Notificações Enviado com mais de 30 dias são apagadas automaticamente. Pendente, Falhou e Descartado permanecem — de propósito, para que um problema não desapareça sozinho.
Se a aba Histórico acumula muito Descartado, isso é sinal de integração quebrada há tempo, não de histórico sujo. Resolver a causa e reenviar; não ignorar.
5. Glossário
| Termo | Significado |
|---|---|
| Webhook | Chamada HTTP que um sistema faz a um endereço de outro para avisar que algo aconteceu. O oposto de ficar consultando (polling) |
| Endpoint | O endereço (URL) que recebe a chamada, e o cadastro que o representa na tela |
| Payload | O conteúdo enviado na notificação — aqui, um JSON |
| Evento | O fato notificado: AUTORIZADA, CANCELADA ou ENCERRADA
|
| cStat | Código de situação devolvido pela SEFAZ. 100/120/150 autorizada, 101 cancelada, 132 encerrada |
| Chave de acesso | O identificador de 44 dígitos do documento fiscal perante a SEFAZ |
| HMAC-SHA256 | Cálculo que gera uma assinatura do conteúdo usando um segredo compartilhado. Permite ao destinatário confirmar a origem da chamada |
| Header | Cabeçalho HTTP — informação que acompanha a chamada, fora do corpo |
| Idempotência | Propriedade de processar a mesma mensagem duas vezes sem gerar efeito duplicado |
| Pelo menos uma vez | O modelo de entrega adotado: a notificação nunca se perde, mas pode chegar repetida |
| X-TryERP-Delivery | Número da entrega, repetido em todas as tentativas da mesma notificação. É a chave de idempotência |
| Timeout | Tempo máximo de espera pela resposta antes de considerar a tentativa falha |
| Backoff | O espaçamento crescente entre as tentativas de reenvio |
| Descartado | Situação da notificação que esgotou as tentativas. Só sai por reenvio manual |
| Nível de detalhe | Quanto vai no corpo: Resumido (identificação do documento) ou Completo (acrescenta destinatário, valor e dados de emissão) |
| Ambiente |
producao ou homologacao, conforme o ambiente em que o documento foi emitido |
6. Suporte
Em caso de dúvida ou comportamento inesperado:
- Conferir as seções "Erros comuns" e "Casos e cuidados" deste capítulo
- Abrir a aba Histórico de Notificações, filtrar por Falhou e Descartado e ler a coluna Último erro
- Confirmar o básico: filial correta, endpoint Ativo, documento e evento marcados
- Rodar Testar envio na estação que emite e guardar o resultado
- Confirmar com o cliente se o endpoint dele registrou a chamada (pelo
X-TryERP-Delivery) - Contatar o suporte com: filial, chave de acesso do documento, evento, print da aba Histórico com a linha em questão, o conteúdo da coluna Último erro na íntegra, o resultado do Testar envio, e o que esperava acontecer
Versão deste manual: Rev 1 — 2026-09-20 (notificação HTTP de autorização, cancelamento e encerramento de NF-e, NFC-e, CT-e, CT-e OS e MDF-e; cadastro de múltiplos endpoints por filial com filtro de documento e evento; payload resumido/completo; headers customizados e assinatura HMAC-SHA256; entrega imediata com rede de segurança a cada 2 minutos, backoff e limite de tentativas; histórico com reenvio manual e limpeza automática)