Verificação de NF-e
Verificar XML
Envia o XML da NF-e; devolve o veredito de nível 1 e os dados da nota e inicia a verificação na SEFAZ.
/openapi/v3/consultas/nf-e/xmltoken, timestamp e sign, veja Autenticação.Envia o XML bruto da NF-e. Devolve de forma síncrona o veredito de nível 1 e os dados da nota já interpretados; se o nível 1 for aprovado, a verificação de nível 2 na SEFAZ começa automaticamente e o veredito final chega pelo webhook invoice.verify.completed (veja Verificação de NF-e).
HTTP 200 significa que a requisição foi aceita, não que a nota foi aprovada. Um XML bem formado que reprova na validação também devolve 200; o veredito está no bloco validation. Nunca decida a validade pelo status HTTP.
Cabeçalhos
Content-Type* | string | Tipo do corpo |
forceRevalidate | bool | Nova verificação forçada |
* Campo obrigatório
validation com o veredito de nível 1. Inclui os casos em que a validação reprovou: verifique validation.validationStatus e validation.errors.tipo | string | Tipo de documento |
modelo | string | Modelo do documento |
status | string | Situação fiscal |
statusDescription | string | Descrição do status |
ambienteEmissao | string | Ambiente de emissão |
numero | string | Número da nota |
serie | string | Série |
dataEmissao | string | Data de emissão |
tipoOperacao | string | Tipo de operação (tpNF), o sentido da mercadoria visto pelo emitente |
chaveAcesso | string | Chave de acesso |
| object | Emitente |
| object | Destinatário |
| array | Itens |
dataAutorizacao | string | Data de autorização |
| object | Protocolo de autorização |
valorTotal | number | Valor líquido da nota |
| object | Veredito de nível 1 |
- Preferível: o documento completo autorizado pela SEFAZ, com o protocolo de autorização. Uma nota sem o protocolo também é aceita: gera um aviso
PROTOCOL_MISSING, mas é processada normalmente. - Limites rígidos: máximo de 1 MB, somente UTF-8, DTD proibido (qualquer
<!DOCTYPEé rejeitado de imediato). - Assinatura: o corpo entra na assinatura depois de remover todos os CR e LF, enquanto o corpo enviado permanece inalterado:
sign = md5Hex(app_secret + "/openapi/v3/consultas/nf-e/xml" + xmlSemCrLf + timestamp)
O cabeçalho forceRevalidate não participa da assinatura. Veja as regras completas em Autenticação.
O itens[].valorTotal de cada linha é o valor bruto da linha, antes do desconto; o valorTotal da raiz é o total líquido da nota, após desconto. A diferença é o desconto total.
Valores e quantidades são números JSON tirados do documento sem zeros finais: 100.00 volta como 100 e 94.90 como 94.9. Formate-os na exibição. Campos sem valor no documento são omitidos, nunca devolvidos como null.
O nível 1 é decidido na hora e devolvido nesta resposta; o nível 2 é a verificação na SEFAZ e chega só pelo webhook. Os valores de validationStatus e de errors[].code estão nas tabelas de enumerações no fim da página.
Nível 1 reprovado na resposta síncrona
HTTP 200 com validationStatus = REJECTED e ao menos um item em errors. É terminal: não há nível 2 e a nova verificação exige reenviar o XML (com forceRevalidate: true dentro da janela de 24 horas).
"validation": {"fileAccessible": true,"xmlWellFormed": true,"schemaValid": true,"signatureValid": false,"accessKeyValid": true,"protocolPresent": true,"protocolValid": true,"xmlVersion": "4.00","validationStatus": "REJECTED","validationStatusDescription": "Verification failed","errors": [ { "code": "SIGNATURE_INVALID", "field": "Signature", "message": "Digital signature verification failed: ..." } ],"warnings": []}
Nível 2 pelo webhook
Quando o nível 1 é aprovado (PENDING_SEFAZ), o veredito final chega pelo webhook invoice.verify.completed com VALIDATED, REJECTED ou VALIDATION_ERROR; cabeçalhos, carga e requisitos do receptor estão em Verificação de NF-e. Se uma entrega se perder, a consulta por chave devolve o validationStatus atual. Não são erros HTTP.
- A verificação de XML é idempotente pela chave: enquanto o nível 2 está em andamento, reenviar devolve o progresso atual e não inicia outra checagem;
forceRevalidate: truetambém não a reinicia nem acelera. - Vereditos terminais são reutilizados por 24 horas a partir do momento em que foram obtidos, inclusive
VALIDATION_ERROR; depois disso, um reenvio simples executa a verificação completa de novo. - A resposta reutilizada reflete o XML enviado originalmente com o
validationStatusatual; para verificar um XML corrigido da mesma chave dentro da janela, envieforceRevalidate: true. - Nova verificação forçada: envie o cabeçalho
forceRevalidate: true; o novo veredito chega como um novo evento de webhook. A consulta por chave não força rechecagem. - Um
REJECTEDbloqueante de nível 1 não tem registro de nível 2; a nova verificação exige reenviar o XML. - As verificações pertencem à sua conta de integrador: outro integrador verificando a mesma nota não afeta a sua, e cada conta recebe o próprio veredito.
Content-TypeTipo do corpo (cabeçalho)
| Valores | Significado |
|---|---|
| application/xml | Corpo XML |
| text/xml | Corpo XML; equivalente |
forceRevalidateNova verificação forçada (cabeçalho)
Omitido vale false.
| Valores | Significado |
|---|---|
| true | Verifica de novo do zero, ignorando o veredito terminal reutilizável |
| false | Reutiliza o veredito terminal das últimas 24 horas, se houver |
tipoTipo de documento
| Valores | Significado |
|---|---|
| NF-e | Nota fiscal eletrônica, usada entre empresas e em vendas com entrega |
| NFC-e | Nota fiscal de consumidor eletrônica, venda no balcão |
modeloModelo do documento
| Valores | Significado |
|---|---|
| 55 | NF-e |
| 65 | NFC-e |
statusSituação fiscal
| Valores | Significado |
|---|---|
| Autorizada | Autorizada pela SEFAZ e sem evento de cancelamento |
| Cancelada | Cancelada, inclusive por cancelamento substitutivo |
| Denegada | Denegada pela SEFAZ |
| Inutilizada | Numeração inutilizada |
| NaoEncontrada | Não encontrada na SEFAZ; pode ser atraso de sincronização |
| Desconhecida | Situação não classificável a partir da resposta da SEFAZ |
ambienteEmissaoAmbiente de emissão
| Valores | Significado |
|---|---|
| Producao | Ambiente oficial |
| Homologacao | Ambiente de teste da SEFAZ; a nota não tem validade |
tipoOperacaoTipo de operação
| Valores | Significado |
|---|---|
| Saida | Saída de mercadoria do emitente (tpNF=1), como uma venda |
| Entrada | Entrada de mercadoria no emitente (tpNF=0), como uma devolução de consumidor ou uma importação |
validation.validationStatusStatus da verificação
A primeira resposta síncrona traz só PENDING_SEFAZ ou REJECTED; os demais chegam pelo webhook invoice.verify.completed e também aparecem em respostas reutilizadas e na consulta por chave.
| Valores | Significado |
|---|---|
| PENDING_SEFAZ | Nível 1 aprovado, verificação na SEFAZ enfileirada |
| REJECTED | Reprovada; terminal. No nível 1 por erro bloqueante, no nível 2 pela situação na SEFAZ (cancelada, denegada, inutilizada, não encontrada, protocolo divergente); não prossiga |
| VALIDATING | Nível 2 em andamento, consultando a SEFAZ |
| VALIDATED | Nota autêntica e regular na SEFAZ; terminal, seguro prosseguir |
| VALIDATION_ERROR | Falha técnica do lado da plataforma, não é juízo sobre a nota; reutilizada por 24 horas como os demais vereditos, reenvie mais tarde com forceRevalidate: true |
validation.errors[].codeCódigos de problema de nível 1
Todos são bloqueantes e levam a REJECTED, exceto PROTOCOL_MISSING, que vai para warnings[]. O número entre parênteses é o código numérico equivalente.
| Valores | Significado |
|---|---|
| XML_MALFORMED | Sintaxe XML inválida (10015100) |
| XSD_INVALID | Não conforme ao layout oficial da NF-e 4.00 (10015101) |
| SIGNATURE_INVALID | Assinatura digital inválida: conteúdo alterado ou certificado vencido ao assinar (10015102) |
| SIGNATURE_CERT_MISMATCH | CNPJ do certificado de assinatura diferente do emitente (10015103) |
| ACCESS_KEY_INVALID | Estrutura ou dígito verificador da chave inválidos (10015104) |
| ACCESS_KEY_MISMATCH | Segmentos da chave diferentes dos campos do documento (10015105) |
| PROTOCOL_MISMATCH | Protocolo de autorização incoerente com a nota (10015106) |
| PROTOCOL_MISSING | Sem protocolo de autorização; aviso, não bloqueia (10015107) |
| XML_VERSION_UNSUPPORTED | Versão do layout diferente de 4.00 (10015108) |
| Código | HTTP | |
|---|---|---|
| 10015000 | 400 | Corpo da requisição vazio. Envie o XML no corpo. |
| 10015001 | 400 | Corpo maior que 1 MB. Verifique se não está encapsulando ou codificando duas vezes. |
| 10015002 | 400 | DTD detectado (<!DOCTYPE). Remova DTDs. |
| 10015003 | 400 | Codificação diferente de UTF-8. Converta para UTF-8 antes de enviar. |
