Reconciliação de documentos e eventos NF-e

Os endpoints de documentos (/inbound/documentos) e eventos (/inbound/eventos) operam de forma independente. O client consome cada um em seu próprio loop de…

How-to Guide — Este documento orienta o integrador na construção da lógica de reconciliação entre documentos e eventos NF-e inbound consumidos via API REST.


1. Introdução

Os endpoints de documentos (/inbound/documentos) e eventos (/inbound/eventos) operam de forma independente. O client consome cada um em seu próprio loop de polling, com tokens e filtros separados. No entanto, documentos e eventos estão relacionados: um evento de cancelamento (ou uma manifestação do destinatário), por exemplo, só faz sentido quando associado à NF-e correspondente.

A reconciliação é a lógica no lado do client que conecta esses dois fluxos. Como a ordem de chegada é imprevisível — um evento pode chegar antes do documento correspondente, e vice-versa — o client precisa lidar com ambos os cenários de forma resiliente.


2. Pré-requisitos


3. Visão geral do modelo

O client mantém dois loops de polling independentes, cada um com seu próprio nextToken e filtros. Ambos os loops gravam os registros recebidos na base local. A reconciliação acontece após cada gravação, usando a chave de acesso como elo de ligação.

┌──────────────────────┐       ┌──────────────────────┐
│  Loop de Documentos  │       │   Loop de Eventos    │
│  /inbound/documentos │       │  /inbound/eventos    │
└────────┬─────────────┘       └────────┬─────────────┘
         │                              │
         ▼                              ▼
   Salva documento              Salva evento
   na base local                na base local
         │                              │
         ▼                              ▼
   Busca eventos pendentes      Busca documento
   pela chave de acesso         pela chave de acesso
         │                              │
         ▼                              ▼
   Encontrou?                   Encontrou?
   ├─ Não → fim                 ├─ Não → fim
   └─ Sim → reconcilia         └─ Sim → reconcilia

Chave de acesso

A chave de acesso é o identificador que conecta um documento ao(s) seu(s) evento(s):

OrigemCampo
Documento (/inbound/documentos)metadata.chNFe (também exposto na raiz do item como chNFe)
Evento (/inbound/eventos)metadata.chNFe

Os dois campos têm exatamente o mesmo valor e formato (44 posições, sem prefixo) — diferente da NFS-e, onde o id do documento carrega um prefixo ("NFS...") que não bate literalmente com o id do evento (lá, a correlação correta é id do documento vs infPedReg.chNFSe do evento). Na NF-e, chNFe casa diretamente nos dois lados.

Multiplicidade por empresa: tanto o documento quanto os eventos de uma mesma NF-e podem aparecer mais de uma vez — uma linha por (companyId, chNFe) — quando várias empresas do tenant são partes do documento. Reconcilie por (companyId, chNFe), não apenas por chNFe, para não cruzar o evento de uma empresa com o documento de outra.

O client deve indexar sua base local por (companyId, chNFe) para permitir buscas eficientes durante a reconciliação.


4. Ao receber um documento

Quando o loop de documentos retorna um novo item:

  1. Salvar o documento na base local, independentemente de já existirem eventos associados.
  2. Buscar na base local todos os eventos cujo (companyId, chNFe) corresponda ao (companyId, chNFe) do documento recém-salvo.
  3. Se nenhum evento for encontrado, encerrar o processamento deste item. Os eventos podem ainda não ter chegado — serão reconciliados quando o loop de eventos os consumir.
  4. Se um ou mais eventos forem encontrados, associar cada evento ao documento e executar a ação correspondente ao tipo de evento (tpEvento). Por exemplo, se um evento de cancelamento for encontrado, marcar o documento como cancelado na base local; se uma manifestação do destinatário for encontrada, refletir o novo statusMde.

5. Ao receber um evento

Quando o loop de eventos retorna um novo item:

  1. Salvar o evento na base local, independentemente de o documento associado já existir.
  2. Buscar na base local o documento cujo (companyId, chNFe) corresponda ao (companyId, chNFe) do evento recém-salvo.
  3. Se o documento não for encontrado, encerrar o processamento deste item. O documento pode ainda não ter chegado — será reconciliado quando o loop de documentos o consumir.
  4. Se o documento for encontrado, associar o evento ao documento e executar a ação correspondente ao tipo de evento. Por exemplo, se for um evento de cancelamento, marcar o documento como cancelado na base local.

6. Considerações

Ordem de chegada imprevisível

Não há garantia de que o documento chegará antes dos seus eventos, nem o contrário. O client deve tratar ambos os cenários com a mesma lógica: salvar primeiro, reconciliar depois.

Idempotência

A lógica de reconciliação deve ser idempotente. Se o mesmo par documento-evento for reconciliado mais de uma vez (por exemplo, após uma reinicialização do client), o resultado final deve ser o mesmo. Isso significa que marcar um documento como cancelado duas vezes não deve gerar efeitos colaterais indesejados.

Múltiplos eventos por documento

Uma NF-e pode acumular vários eventos ao longo do tempo (ex.: ciência da operação seguida de confirmação da operação, ou uma carta de correção seguida de cancelamento). Use nSeqEvento e tpEvento para ordenar e desduplicar eventos do mesmo tipo, em vez de assumir que o documento só recebe um evento.

Eventos sem documento

É possível que um evento permaneça sem documento associado por um período prolongado — por exemplo, se o documento ainda não foi processado pela API ou se o client iniciou o consumo de eventos com um createdFrom anterior ao dos documentos. O client deve tratar eventos não reconciliados como estado normal, não como erro.

Documentos sem evento

Nem todo documento terá eventos associados. Uma NF-e que nunca foi cancelada, corrigida ou manifestada simplesmente não terá eventos. A ausência de eventos para um documento é o cenário padrão.

Nesta página