VeriFactu
VeriFactu es el sistema de facturación electrónica de la AEAT (Agencia Estatal de Administración Tributaria) para empresas y autónomos del Estado español que no estén en territorio foral. Lo establece el Real Decreto 1007/2023, regulando los sistemas informáticos de facturación.
Esta guía cubre cómo se integra VeriFactu con la API pública de FacturaDirecta:
Cuándo se activa.
Los dos modos del sistema (
mode_verifactuymode_no_verifactu) y por qué es importante saber en cuál está cada factura.Qué campos puedes (y debes) enviar en
main.verifactuy por línea.Qué metadatos lee tu integración en
meta.verifactu.Códigos oficiales:
TipoFactura,CalificacionOperacion,OperacionExenta.Códigos QR y URLs de verificación.
Envío a AEAT, rate limit y reintentos.
Anulación.
Webhooks específicos de VeriFactu.
Para el contrato general del recurso de facturas, ver Facturas. Para el régimen equivalente del País Vasco, ver TicketBAI.
Cuándo se activa
VeriFactu se aplica cuando la empresa emisora está dada de alta en VeriFactu desde su configuración fiscal. La activación es administrativa; no hay un flag por factura para activarlo o desactivarlo.
La única forma de emitir una factura sin generar VeriFactu en una empresa con VeriFactu activo es marcarla como externa (main.external = true): es el modo para registrar facturas históricas o emitidas con otro software, no una vía para saltarse la obligación.
Los dos modos: mode_verifactu vs mode_no_verifactu
VeriFactu admite dos modos operativos. La diferencia es cuándo y cómo se comunican los registros a AEAT:
Modo | Comportamiento |
| Envío en tiempo real a AEAT. Cada factura se transmite por SOAP a la sede de Hacienda inmediatamente tras firmarla. La cadena de huellas se mantiene también. |
| Registros firmados y encadenados localmente. AEAT no recibe el envío inmediato; los registros quedan disponibles para consulta o auditoría a petición. La empresa sigue obligada a mantener el sistema de facturación íntegro. |
Tu integración no decide el modo: lo determina la configuración fiscal de la empresa. El modo en el que se procesó cada factura concreta queda registrado en meta.verifactu.mode (y en meta.verifactu.modeAnulacion si fue anulada). Lee esos campos para saber qué URL de verificación usar en el QR (ver más abajo).
Campos de entrada: main.verifactu
Son los únicos campos de VeriFactu que tu integración puede enviar en POST /invoices o PUT /invoices/{id}. El resto lo calcula el servidor.
Nivel factura
Campo | Tipo | Significado |
| enum (ver tabla) | Tipo de la factura según RD 1619/2012 y régimen rectificativo. Por defecto, el servidor lo deduce: |
| string (≤ 500 chars) | Descripción libre de la operación. Útil cuando las líneas no la describen suficientemente. |
|
|
|
| enum | Valor por defecto de |
Por línea
Cada elemento de lines puede llevar un sub-objeto verifactu:
Campo | Tipo | Significado |
| string | Clave del régimen aplicable según AEAT ( |
| enum (ver tabla) | Sólo para operaciones sujetas o no sujetas. Mutuamente excluyente con |
| enum | Sólo para operaciones exentas. Mutuamente excluyente con |
Códigos oficiales
Los enums los define la AEAT en la especificación técnica de VeriFactu y los reproduce literalmente nuestro schema.
TipoFactura
Código | Significado oficial |
| Factura (Art. 6, 7.2 y 7.3 del RD 1619/2012). |
| Factura simplificada y facturas sin identificación del destinatario Art. 6.1.d) RD 1619/2012. |
| Factura emitida en sustitución de facturas simplificadas facturadas y declaradas. |
| Factura rectificativa (Art. 80.1 y 80.2 y error fundado en derecho). |
| Factura rectificativa (Art. 80.3). |
| Factura rectificativa (Art. 80.4). |
| Factura rectificativa (resto). |
| Factura rectificativa en facturas simplificadas. |
Detalles de cuándo usar cada R# en la guía de Rectificativas. Para crear una F3 se utiliza el endpoint dedicado de sustitutivas.
CalificacionOperacion
Aplica solo en líneas sujetas o no sujetas (no exentas).
Código | Significado oficial |
| Operación sujeta y no exenta — sin inversión del sujeto pasivo. |
| Operación sujeta y no exenta — con inversión del sujeto pasivo. |
| Operación no sujeta artículo 7, 14, otros. |
| Operación no sujeta por reglas de localización. |
OperacionExenta
Aplica solo en líneas exentas.
Código | Significado oficial |
| Exenta por Art. 20. |
| Exenta por Art. 21. |
| Exenta por Art. 22. |
| Exenta por Art. 24. |
| Exenta por Art. 25. |
| Exenta otros. |
Los códigos E1-E6 de VeriFactu corresponden a artículos distintos de los E1-E6 de TicketBAI. No los mezcles si tu integración opera con empresas en ambos regímenes.
Metadatos: meta.verifactu
Tras guardar una factura definitiva (main.draft = false) en una empresa con VeriFactu activo, el servidor rellena meta.verifactu con la información operativa. Es read-only.
Campo | Significado |
| Objeto con el registro de alta enviado (formato AEAT). |
| XML literal del registro de alta. |
| Objeto con el registro de anulación (cuando aplica). |
| XML literal del registro de anulación. |
|
|
| Igual que |
| URL completa del código QR que debe aparecer en la representación impresa de la factura. |
| Datos codificados del QR (útil para regenerar imagen con tu propia librería QR). |
registroAlta y registroAnulacion son objetos abiertos (additionalProperties: true): siguen el contrato de AEAT, que puede evolucionar. Si necesitas un campo específico, accede por nombre; no asumas un conjunto cerrado.
Códigos QR
Cada factura emitida con VeriFactu debe llevar un código QR impreso que permite a un comprador (o a AEAT) verificar la factura. El servidor genera la URL y los datos en meta.verifactu.qrUrl y meta.verifactu.qr.
La URL apunta a la sede de AEAT. Cuál de las dos URLs depende del modo:
Modo de la factura | URL del QR |
| |
|
Los entornos de preproducción usan prewww2.aeat.es con el mismo patrón de path. Si tu integración renderiza PDFs propios y no usa nuestro generador, respeta la URL tal cual te llega en qrUrl: el QR contiene parámetros firmados/hashados que no puedes reconstruir.
Envío a AEAT
Para facturas en mode_verifactu, el envío al webservice SOAP de AEAT es inmediato tras guardar la factura definitiva:
Se construye el registro de alta a partir de la factura.
Se calcula la huella (hash de los campos relevantes, encadenando con la huella de la factura anterior).
Se firma el XML con el certificado de la empresa.
Se envía al endpoint SOAP correspondiente (producción o preproducción según configuración).
Si AEAT responde OK, el registro se considera aceptado y se dispara el webhook
invoice.verifactu_sent.
Para facturas en mode_no_verifactu, los pasos 1-3 son los mismos pero no hay paso 5: el registro queda guardado localmente con su huella, listo para que AEAT lo consulte cuando lo requiera.
Rate limit
AEAT puede indicar al sistema que espere antes del próximo envío (parámetro TiempoEsperaEnvio en sus respuestas). FacturaDirecta respeta ese rate limit por empresa: si AEAT pide esperar N segundos, los siguientes envíos de esa empresa se posponen automáticamente. Tu integración no necesita gestionarlo, pero puede observar el efecto si nota un retraso entre creación de facturas y meta.verifactu.registroAlta rellenado.
Anulación
Cuando una factura se anula con PUT /invoices/{id} enviando main.voided = true, el servidor:
Genera el registro de anulación.
Si está en
mode_verifactu, lo envía a AEAT por SOAP.Rellena
meta.verifactu.registroAnulacionyregistroAnulacionXml.Guarda el modo del envío en
meta.verifactu.modeAnulacion.Emite el webhook
invoice.voided.
Webhooks
VeriFactu dispone de dos eventos relacionados:
Evento | Cuándo se emite |
| Al crear cualquier factura, incluido el caso VeriFactu. No es específico de VeriFactu. |
| Cuando AEAT confirma el alta de una factura concreta (solo en |
| Cuando AEAT confirma el envío de un lote de eventos del sistema (eventos de facturación, sumarios periódicos). No corresponde a una factura individual. |
A diferencia de TicketBAI (que no emite webhooks específicos), VeriFactu sí permite a tu integración reaccionar a la confirmación de AEAT sin polling. Detalles del formato de entrega (firma HMAC, reintentos) en Webhooks.
Coexistencia con TicketBAI
Una factura emitida con VeriFactu no se envía también a TicketBAI: los dos regímenes son excluyentes y se determinan por la configuración fiscal de la empresa. En la práctica:
Empresa con domicilio fiscal en País Vasco → TicketBAI (ver TicketBAI).
Empresa con domicilio fiscal en el resto del Estado → VeriFactu.
Si tu integración opera con empresas en ambos territorios, no asumas la misma información: en unas facturas tendrás meta.verifactu rellenado y meta.ticketbai ausente, y viceversa.
Errores comunes
CalificacionOperacionyOperacionExentaenviados a la vez en una línea: son mutuamente excluyentes. Si la operación es exenta, usaOperacionExenta. Si no,CalificacionOperacion.Mezclar códigos de TicketBAI y VeriFactu: los
E1-E6refieren a artículos diferentes en cada régimen. Tu integración debe seleccionar el conjunto correcto según el régimen activo en la empresa.Asumir
mode_verifactusiempre: si tu integración monta el QR en su propio PDF y elige hardcodear la URLValidarQR, fallará para facturas enmode_no_verifactu. Lee siempremeta.verifactu.qrUrl.No esperar al
invoice.verifactu_sentantes de considerar enviada: la respuesta del POST/PUT de la factura te confirma que el alta se ha registrado localmente y se ha despachado. La confirmación firmada de AEAT llega después eninvoice.verifactu_sent. Si tu lógica depende de "AEAT lo tiene", espera al webhook.Cambiar manualmente
meta.verifactu: es read-only; el servidor lo regenera al guardar. Cualquier cambio se descarta.
Referencias oficiales
La AEAT publica la documentación técnica de VeriFactu, los esquemas XSD, los códigos de error y la especificación del QR en su sede:
Portal VeriFactu: sede.agenciatributaria.gob.es (sección "Sistemas Informáticos de Facturación y VERI*FACTU").
Endpoint de verificación QR (producción):
https://www2.agenciatributaria.gob.es/wlpl/TIKE-CONT/ValidarQRy…/ValidarQRNoVerifactu.Endpoint de preproducción:
https://prewww2.aeat.es/....
Para el significado funcional de cada código (artículos del IVA, casos rectificativos, claves de régimen) consulta siempre la documentación oficial: FacturaDirecta los acepta y los reenvía a AEAT, pero la autoridad sobre su semántica es la Agencia Tributaria, no este sistema.