Verificación de NF-e
Verificación de XML
Envía el XML de la NF-e; devuelve el veredicto de nivel 1 y los datos de la factura e inicia la verificación en la SEFAZ.
/openapi/v3/consultas/nf-e/xmltoken, timestamp y sign, vea Autenticación.Envía el XML sin procesar de la NF-e. Devuelve de forma síncrona el veredicto de nivel 1 y los datos de la factura ya interpretados; si el nivel 1 se aprueba, la verificación de nivel 2 en la SEFAZ empieza automáticamente y el veredicto final llega por el webhook invoice.verify.completed (vea Verificación de NF-e).
HTTP 200 significa que la solicitud fue aceptada, no que la factura fue aprobada. Un XML bien formado que no supera la validación también devuelve 200; el veredicto está en el bloque validation. Nunca decida la validez por el estado HTTP.
Cabeceras
Content-Type* | string | Tipo del cuerpo |
forceRevalidate | bool | Nueva verificación forzada |
* Campo obligatorio
validation con el veredicto de nivel 1. Incluye los casos en que la validación falló: compruebe validation.validationStatus y validation.errors.tipo | string | Tipo de documento |
modelo | string | Modelo del documento |
status | string | Situación fiscal |
statusDescription | string | Descripción del estado |
ambienteEmissao | string | Ambiente de emisión |
numero | string | Número de la factura |
serie | string | Serie |
dataEmissao | string | Fecha de emisión |
tipoOperacao | string | Tipo de operación (tpNF), el sentido de la mercancía visto por el emisor |
chaveAcesso | string | Clave de acceso |
| object | Emisor |
| object | Destinatario |
| array | Ítems |
dataAutorizacao | string | Fecha de autorización |
| object | Protocolo de autorización |
valorTotal | number | Importe neto de la factura |
| object | Veredicto de nivel 1 |
- Preferible: el documento completo autorizado por la SEFAZ, con el protocolo de autorización. Una factura sin el protocolo también se acepta: genera un aviso
PROTOCOL_MISSING, pero se procesa con normalidad. - Límites estrictos: máximo 1 MB, solo UTF-8, DTD prohibido (cualquier
<!DOCTYPEse rechaza de inmediato). - Firma: el cuerpo participa en la firma tras eliminar todos los CR y LF, mientras que el cuerpo enviado permanece sin cambios:
sign = md5Hex(app_secret + "/openapi/v3/consultas/nf-e/xml" + xmlSinCrLf + timestamp)
La cabecera forceRevalidate no participa en la firma. Reglas completas en Autenticación.
El itens[].valorTotal de cada línea es el importe bruto de la línea, antes del descuento; el valorTotal de la raíz es el total neto de la factura, tras el descuento. La diferencia es el descuento total.
Importes y cantidades son números JSON tomados del documento sin ceros finales: 100.00 se devuelve como 100 y 94.90 como 94.9. Deles formato al mostrarlos. Los campos sin valor en el documento se omiten, nunca se devuelven como null.
El nivel 1 se decide en el momento y se devuelve en esta respuesta; el nivel 2 es la verificación en la SEFAZ y llega solo por el webhook. Los valores de validationStatus y de errors[].code están en las tablas de enumeraciones al final de la página.
Nivel 1 rechazado en la respuesta síncrona
HTTP 200 con validationStatus = REJECTED y al menos un elemento en errors. Es terminal: no hay nivel 2 y la nueva verificación exige reenviar el XML (con forceRevalidate: true dentro de la ventana 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": []}
Nivel 2 por el webhook
Una vez aprobado el nivel 1 (PENDING_SEFAZ), el veredicto final llega por el webhook invoice.verify.completed con VALIDATED, REJECTED o VALIDATION_ERROR; cabeceras, carga y requisitos del receptor están en Verificación de NF-e. Si se pierde una entrega, la consulta por chave devuelve el validationStatus actual. No son errores HTTP.
- La verificación de XML es idempotente por la chave: mientras el nivel 2 está en curso, reenviar devuelve el progreso actual y no inicia otra comprobación;
forceRevalidate: truetampoco la reinicia ni la acelera. - Los veredictos terminales se reutilizan durante 24 horas desde el momento en que se obtuvieron, incluido
VALIDATION_ERROR; después, un reenvío normal ejecuta de nuevo la verificación completa. - Una respuesta reutilizada refleja el XML enviado originalmente con el
validationStatusactual; para verificar un XML corregido de la misma chave dentro de la ventana, envíeforceRevalidate: true. - Nueva verificación forzada: envíe la cabecera
forceRevalidate: true; el nuevo veredicto llega como un nuevo evento de webhook. La consulta por chave no puede forzar una comprobación. - Un
REJECTEDbloqueante de nivel 1 no tiene registro de nivel 2; la nueva verificación exige reenviar el XML. - Las verificaciones pertenecen a su cuenta de integrador: que otro integrador verifique la misma factura no afecta a la suya, y cada cuenta recibe su propio veredicto.
Content-TypeTipo del cuerpo (cabecera)
| Valores | Significado |
|---|---|
| application/xml | Cuerpo XML |
| text/xml | Cuerpo XML; equivalente |
forceRevalidateNueva verificación forzada (cabecera)
Omitido vale false.
| Valores | Significado |
|---|---|
| true | Verifica de nuevo desde cero, ignorando el veredicto terminal reutilizable |
| false | Reutiliza el veredicto terminal de las últimas 24 horas, si existe |
tipoTipo de documento
| Valores | Significado |
|---|---|
| NF-e | Factura electrónica usada entre empresas y en ventas con entrega |
| NFC-e | Factura electrónica al consumidor, venta en mostrador |
modeloModelo del documento
| Valores | Significado |
|---|---|
| 55 | NF-e |
| 65 | NFC-e |
statusSituación fiscal
| Valores | Significado |
|---|---|
| Autorizada | Autorizada por la SEFAZ y sin evento de cancelación |
| Cancelada | Cancelada, incluso por cancelación sustitutiva |
| Denegada | Denegada por la SEFAZ |
| Inutilizada | Numeración inutilizada |
| NaoEncontrada | No encontrada en la SEFAZ; puede ser retraso de sincronización |
| Desconhecida | Situación no clasificable a partir de la respuesta de la SEFAZ |
ambienteEmissaoAmbiente de emisión
| Valores | Significado |
|---|---|
| Producao | Ambiente oficial |
| Homologacao | Ambiente de prueba de la SEFAZ; la factura no tiene validez |
tipoOperacaoTipo de operación
| Valores | Significado |
|---|---|
| Saida | Salida de mercancía del emisor (tpNF=1), como una venta |
| Entrada | Entrada de mercancía en el emisor (tpNF=0), como una devolución del consumidor o una importación |
validation.validationStatusEstado de la verificación
La primera respuesta síncrona trae solo PENDING_SEFAZ o REJECTED; los demás llegan por el webhook invoice.verify.completed y también aparecen en respuestas reutilizadas y en la consulta por chave.
| Valores | Significado |
|---|---|
| PENDING_SEFAZ | Nivel 1 aprobado, verificación en la SEFAZ en cola |
| REJECTED | Rechazada; terminal. En el nivel 1 por error bloqueante, en el nivel 2 por la situación en la SEFAZ (cancelada, denegada, inutilizada, no encontrada, protocolo divergente); no continúe |
| VALIDATING | Nivel 2 en curso, consultando a la SEFAZ |
| VALIDATED | Factura auténtica y regular en la SEFAZ; terminal, seguro continuar |
| VALIDATION_ERROR | Fallo técnico del lado de la plataforma, no es un juicio sobre la factura; se reutiliza 24 horas como cualquier veredicto, reenvíe más tarde con forceRevalidate: true |
validation.errors[].codeCódigos de problema de nivel 1
Todos son bloqueantes y llevan a REJECTED, salvo PROTOCOL_MISSING, que va a warnings[]. El número entre paréntesis es el código numérico equivalente.
| Valores | Significado |
|---|---|
| XML_MALFORMED | Sintaxis XML inválida (10015100) |
| XSD_INVALID | No conforme al layout oficial de la NF-e 4.00 (10015101) |
| SIGNATURE_INVALID | Firma digital inválida: contenido alterado o certificado caducado al firmar (10015102) |
| SIGNATURE_CERT_MISMATCH | CNPJ del certificado de firma distinto del emisor (10015103) |
| ACCESS_KEY_INVALID | Estructura o dígito verificador de la clave inválidos (10015104) |
| ACCESS_KEY_MISMATCH | Segmentos de la clave distintos de los campos del documento (10015105) |
| PROTOCOL_MISMATCH | Protocolo de autorización incoherente con la factura (10015106) |
| PROTOCOL_MISSING | Sin protocolo de autorización; aviso, no bloquea (10015107) |
| XML_VERSION_UNSUPPORTED | Versión del layout distinta de 4.00 (10015108) |
| Código | HTTP | |
|---|---|---|
| 10015000 | 400 | Cuerpo de la solicitud vacío. Envíe el XML en el cuerpo. |
| 10015001 | 400 | El cuerpo supera 1 MB. Compruebe que no la está envolviendo ni codificando dos veces. |
| 10015002 | 400 | DTD detectado (<!DOCTYPE). Elimine los DTD. |
| 10015003 | 400 | La codificación no es UTF-8. Convierta a UTF-8 antes de enviar. |
