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= 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 401 e 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 dataEvento se 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 homologacao como 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 evento igual a TESTE e chave de acesso composta de 44 zeros. Trate-a respondendo 200 e ignorando o conteúdo Método GET. Se o seu serviço não puder receber POST, é possível configurar GET: 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 HTTPS que aceite POST 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 200 de imediato e processe de forma assíncrona Registre em log o X-TryERP-Delivery de tudo que receber — é por ele que as duas pontas conseguem investigar um caso específico