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