Webhooks
Webhooks avisam sua aplicação quando uma operação muda de estado, reduzindo a necessidade de consultas repetidas.
Informe a URL na própria emissão:
{
"cpf_cnpj": "60772432000142",
"webhook_url": "https://seu-sistema.com.br/webhooks/conota",
"nota": { "...": "..." }
}
Fluxo
1. Seu sistema envia a emissão -> 202 { job_id }
2. O Conota processa
3. O Conota chama o seu webhook (POST, JSON)
4. Seu sistema responde 2xx rapidamente
5. Seu sistema persiste o novo estado
Headers da notificação
POST /webhooks/conota
Content-Type: application/json
X-Qualyfiscal-Signature: sha256=<hmac_hex>
X-Qualyfiscal-Job-Id: 6f8dc295-...
X-Qualyfiscal-Tentativa: 1
X-Conota-*Esses nomes são contrato, não marca. O código dos clientes já lê X-Qualyfiscal-Signature para
conferir a assinatura; renomear quebraria a validação de toda integração existente — e a falha
apareceria do lado deles, silenciosamente. Se um dia mudar, os dois nomes conviverão por bastante
tempo antes.
Validando a assinatura
A assinatura é um HMAC-SHA256 do corpo bruto, em hexadecimal, prefixado por sha256=.
const crypto = require('crypto')
function assinaturaValida(corpoBruto, headerRecebido, segredo) {
const esperado = 'sha256=' + crypto
.createHmac('sha256', segredo)
.update(corpoBruto)
.digest('hex')
const a = Buffer.from(esperado)
const b = Buffer.from(headerRecebido || '')
// timingSafeEqual exige mesmo tamanho — compare o tamanho antes.
return a.length === b.length && crypto.timingSafeEqual(a, b)
}
JSON.parse seguido de JSON.stringify pode reordenar chaves e mudar espaçamento — e a assinatura
deixa de bater. Guarde o body cru antes do parse.
Retentativas
Se o seu endpoint não responder, o Conota tenta de novo:
| Tentativas | 3 no total |
| Timeout por tentativa | 10 segundos |
| Intervalos | 30s, depois 60s |
O número da tentativa vem em X-Qualyfiscal-Tentativa.
Seu endpoint deve
- usar HTTPS;
- responder rápido (menos de 10s) e processar o trabalho pesado de forma assíncrona;
- validar a assinatura antes de confiar no conteúdo;
- ser idempotente — o mesmo evento pode chegar mais de uma vez;
- registrar o
job_idpara auditoria.
Webhook não substitui consulta
Se o seu servidor estiver fora do ar durante as três tentativas, a notificação se perde. Sua aplicação precisa conseguir reconciliar o estado mesmo assim.
Mantenha uma rotina de recuperação que varra jobs sem estado final e consulte
POST /v1/jobs/consultar-lote. Webhook é o caminho rápido; a consulta é a rede de segurança.