Webhooks

Configure endpoints para receber eventos em tempo real, eliminando a necessidade de polling. O sistema faz até 5 tentativas com backoff exponencial antes de marcar uma entrega como falha.

Eventos Disponíveis

nfse.issued

NFS-e emitida com sucesso. Contém chNFSe e nNFSe.

nfse.error

Falha na emissão. Contém errorCode e errorMessage.

nfse.cancelled

NFS-e cancelada com sucesso.

batch.completed

Lote finalizado. Contém total, issued, errors.

Estrutura do Payload

Todos os eventos seguem a mesma estrutura de envelope. O campo data varia por evento.

{
  "event": "nfse.issued",
  "deliveryId": "del_xyz789",
  "timestamp": "2026-03-12T19:00:00.000Z",
  "data": {
    "invoiceId": "inv_abc123",
    "chNFSe": "4321000001234",
    "nNFSe": "00001"
  }
}

Headers enviados com cada requisição:

HeaderValor
Content-Typeapplication/json
X-Notaas-EventNome do evento (ex: nfse.issued)
X-Notaas-DeliveryID único da entrega (UUID)
X-Notaas-SignatureHMAC-SHA256 do body — presente apenas se o endpoint tiver secret configurado

⚠️ Assinatura HMAC

O header X-Notaas-Signature só é enviado quando o endpoint tem um secret configurado. Configure o secret no Dashboard → Developers → Webhooks → Editar endpoint.

Validar Assinatura (HMAC)

O valor do header X-Notaas-Signature é calculado como sha256=HMAC-SHA256(secret, rawBody). Você deve recalcular a assinatura no seu servidor e comparar com timing-safe equality.

import crypto from 'crypto';

app.post('/webhook/notaas', (req, res) => {
  // IMPORTANTE: req.rawBody deve ser a string bruta antes do JSON.parse
  const rawBody = req.rawBody;
  const received = req.headers['x-notaas-signature'] ?? '';

  const expected =
    'sha256=' +
    crypto
      .createHmac('sha256', process.env.NOTAAS_WEBHOOK_SECRET)
      .update(rawBody)
      .digest('hex');

  const valid = crypto.timingSafeEqual(
    Buffer.from(received),
    Buffer.from(expected),
  );

  if (!valid) return res.status(401).send('Assinatura inválida');

  // Idempotência: evitar reprocessar em retries
  const deliveryId = req.headers['x-notaas-delivery'];
  if (alreadyProcessed(deliveryId)) return res.status(200).send('ok');

  const payload = JSON.parse(rawBody);
  console.log(payload.event, payload.data);

  res.status(200).send('ok');
});

Retry Policy

Uma entrega é considerada falha quando o endpoint retorna status não-2xx ou ocorre erro de rede/timeout (10s). O sistema tenta novamente até 5 vezes com delays crescentes:

TentativaDelay
Imediato
1 minuto
5 minutos
30 minutos
2 horas

Após 5 tentativas falhas, a entrega é marcada como failed. Você pode consultar o histórico em Dashboard → Webhooks → Histórico.

Configurar Endpoint via API

curl -X POST https://platform.notaas.com.br/api/v1/webhooks/endpoints \
  -H "Content-Type: application/json" \
  -H "x-api-key: ntaas_XXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d '{
    "url": "https://minha-api.com/webhooks/notaas",
    "events": ["nfse.issued", "nfse.error"],
    "secret": "meu-secret-para-assinar"
  }'

Parâmetros do Endpoint

Use o header X-Notaas-Delivery para garantir idempotência — armazene os IDs processados e ignore repetições em caso de retry.

POST /webhooks/endpoints

CampoTipoReq?Descrição
urlstringsimURL HTTPS que receberá o POST
eventsstring[]simLista de eventos: nfse.issued, nfse.error, nfse.cancelled, batch.completed
secretstringnãoSecret para assinar payloads com HMAC-SHA256 (opcional, mas recomendado em produção)
activebooleannãoAtivo por padrão (true)