¿Qué datos deben incluirse en la factura se entrega al cliente?
La factura debe ser entregada al receptor (ya sea en versión impresa o digital) con un QR de cotejo que le permita verificar que la factura ha sido correctamente remitida a la AEAT. Junto al QR deberá aparecer la frase «Factura verificable en la sede electrónica de la AEAT» o «VERI*FACTU», que deberá tener un tipo de letra y tamaño bien visibles, similares a los del resto de datos de la factura. El código QR deberá tener un tamaño entre 30x30 y 40x40 milímetros.¿Qué debo hacer si cuando Veri*Factu “rechaza” una de mis facturas?
En estos casos hay que emitir una subsanación CON registro previo rechazado. Para subsanar un registro que ha sido rechazado anteriormente por Veri*Factu debemos enviar el campocorrection_key con el valor S y el campo previous_rejection_key con el valor X. También deberán modificarse los campos que deban ser corregidos.
Caso de ejemplo
Dado la secuencia de facturas F4 → F5 → F6, donde cada factura se genera encadenada a la anterior. El resultado del envío es:- F4: Aceptada, encadenada a la factura del emisor anteriormente procesada por el SIF. Probablemente la F3.
- F5: Recibida, pero rechazada (no queda registrada en la AEAT). Encadenada a F4.
- F6: Aceptada. Encadenada a F5.
previous_rejection_key = Xcorrection_key = S
¿Cuándo no debo subsanar con rechazo previo X?
Conprevious_rejection_key = X se declara que la factura no está registrada en la AEAT. Si la AEAT ya tiene un alta o una anulación de esa factura, rechaza la subsanación como registro duplicado (código 3000).
Para evitarlo, KubiFACTU comprueba si ya existe un alta de la misma factura (mismo número y mismo ejercicio o fecha de expedición, en la misma empresa cliente) y rechaza la petición con HTTP 422 y el error en previous_rejection_key (invoices.<n>.previous_rejection_key en los lotes) en estos casos:
- El alta original ya está registrada en la AEAT (
vf_record_registration_status=success,accepted_with_errorsocancelled). No envíesX: si necesitas corregir su contenido, envía una subsanación ordinaria concorrection_key = Syprevious_rejection_key = N(u omitido). - El alta original sigue pendiente de envío. Espera a conocer su resultado, mediante el
callback_urlo consultando el registro, y decide después cómo subsanarla.
X sigue admitiéndose cuando el alta original fue rechazada (failed), no está registrada (not_registered) o no existe en KubiFACTU.
¿Qué debo hacer cuando Veri*Factu “acepta con errores” una de mis facturas?
En estos casos hay que emitir una subsanación ordinaria, es decir, una subsanación SIN registro previo rechazado. Para subsanar un registro que ha sido aceptado con errores por Veri*Factu debemos enviar el campocorrection_key con el valor S y hay que obviar el campo previous_rejection_key (o enviarlo con el valor N). También deberán modificarse los campos que deban ser corregidos.
Caso de ejemplo
Dado la secuencia de facturas F4 → F5 → F6, donde cada factura se genera encadenada a la anterior. El resultado del envío es:- F4: Aceptada, encadenada a la factura del emisor anteriormente procesada por el SIF. Probablemente la F3.
- F5: Aceptada con errores (queda registrada en la AEAT). Encadenada a F4.
- F6: Aceptada. Encadenada a F5.
correction_key = S
¿Qué debo hacer si no puedo enviar un registro porque VeriFactu tiene problemas técnicos de conexión o no ha superado las validaciones básicas de VeriFactu?
Si el envío falla por un problema técnico de conexión con Veri*Factu o por no superar sus validaciones básicas, no debes modificar el registro ni generar otra alta o anulación de la misma factura. El reenvío del mismo registro conserva su UUID, identidad, huella y encadenamiento originales. La excepción son los errores en el NIF o el nombre del emisor o del representante: reenviar no los resuelve y se tratan como un rechazo. Ver ¿Qué ocurre si Veri*Factu no identifica el NIF o el nombre del emisor?vf_post_status = failure indica un fallo de envío o una respuesta de error; no demuestra por sí solo que la AEAT no haya recibido el registro. Un timeout identificable se guarda con vf_post_status = failure y vf_record_registration_status = unknown, tanto en los envíos directos como en los diferidos, y activa la conciliación obligatoria: KubiFACTU consulta el registro en la AEAT por sí mismo y, mientras no obtiene un resultado definitivo, el reenvío queda bloqueado. No se reclasifican masivamente los registros históricos.
¿Qué es la recuperación automática de envíos?
KubiFACTU reintenta por su cuenta los envíos que dejan esperando la cadena de una empresa cliente y un SIF. Se aplica a altas y anulaciones, tanto inmediatas como diferidas, también en KubiBAI. Ante un fallo temporal, no necesitas consultar ni reenviar el registro. Si hay dudas sobre si la AEAT lo recibió, KubiFACTU lo comprueba antes de reenviarlo. Mientras se resuelve la incidencia, los siguientes registros de la misma cadena esperan su turno. Puedes seguir la recuperación mediante el objetorecovery y los callbacks. El estado resolved indica que la recuperación ha terminado; el resultado de la AEAT se consulta en vf_record_registration_status.
Si el registro pasa a attention, necesita intervención. Revisa el motivo indicado, corrige la causa y solicita el reenvío del mismo registro. No modifiques el registro ni generes otra alta o anulación de la misma factura. Si necesitas ayuda, contacta con [email protected]. KubiFACTU avisa por correo al intermediario cuando hace falta intervenir o la incidencia se prolonga.
Los registros históricos que no están en recuperación automática (recovery: null) y mantienen bloqueada la cadena requieren consulta y reenvío manual.
Para los campos de la respuesta y los callbacks, consulta la referencia de la API y las diferencias con KubiBAI.
¿Cómo compruebo el resultado desde el panel?
Tras un timeout, la conciliación obligatoria se encarga de comprobar el resultado. Si aun así un registro queda con el envío en Failure y el registro en Unknown, sin conciliación obligatoria pendiente, por ejemplo un registro histórico, el botón de reenvío conserva su visibilidad, pero requiere dos acciones separadas:- En el primer clic, la confirmación dice «Sí, comprobar estado». Sólo consulta a la AEAT; no reenvía.
- Si la consulta confirma el registro con su identidad y huella, actualiza su estado y evita el reenvío. Si devuelve un SinDatos válido, guarda «No registrado» (
not_registered) y permite confirmar el reenvío mediante un segundo clic.
¿Qué cambia para las integraciones por API?
El flujo de dos clics pertenece al panel. La API mantiene su autenticación medianteX-Qbikode-ClientApiKey y sus operaciones de consulta (GET /api/invoices/{invoiceId}/query) y reenvío (GET /api/invoices/{invoiceId}/resubmit). La API de reenvío no impone la comprobación previa del panel para failure + unknown sin conciliación pendiente. Ante ese resultado incierto, consulta el mismo registro antes de decidir reenviarlo.
Tras un timeout identificable, en cambio, el reenvío devuelve HTTP 409 con motivo pending_reconciliation hasta que la conciliación termina. Los envíos iniciales directos y los reenvíos consultan el registro en el momento, y los envíos diferidos, poco después. Si esa consulta no obtiene un resultado definitivo, KubiFACTU la repite periódicamente con un número limitado de intentos. También puedes consultar tú el registro: una consulta con resultado definitivo levanta el bloqueo.
Un mismo registro puede generar más de un callback, por ejemplo tras una consulta o un reenvío. Correlaciona cada callback por id y procésalo de forma idempotente.
Seguimiento de la recuperación automática
- Las respuestas incluyen siempre el campo
recovery: el alta inmediata y la diferida, el listadoGET /api/invoices,GET /api/invoices/{invoiceId}, la consulta, el reenvío, las anulaciones (/cancely/deferredcancel), sus equivalentes de KubiBAI y los callbacks. Va relleno en los registros que sigue la recuperación y valenullen el resto; si valenull, puedes ignorarlo. La respuesta dePOST /api/invoices/batchno lo incluye. - KubiFACTU llama a
callback_urlcon cada cambio que producen los intentos automáticos: un nuevoretry, el paso aattentiono el final de la recuperación. No llama por el resultado que ya devuelve la propia petición. Por esocallback_urltambién sirve en los envíos inmediatos. - Tras un timeout, si la consulta no obtiene un resultado definitivo, KubiFACTU la repite en los siguientes intentos de la recuperación.
- El reenvío de un registro en recuperación se admite en
retry, enattentiony enpendingsi el registro ya se envió. Enprocessing, enresolvedy en un diferido que aún espera su primer envío devuelve HTTP422. Mientras la conciliación está pendiente devuelve HTTP409con motivopending_reconciliation. - La consulta de un registro en recuperación solo genera un callback si cambia el resultado o el estado de
recovery.
¿Qué significa conciliación obligatoria?
Conciliar significa comprobar qué recibió la AEAT antes de permitir otro envío. Mientras esa comprobación esté pendiente, el reenvío manual queda bloqueado tanto en el panel como en la API. Se aplica cuando existe la marca internarecovery_reconciliation_pending o cuando un registro histórico tiene envío success y estado unknown. Un timeout identificable la activa; los duplicados 3000/3001 y las respuestas inutilizables o desconocidas pueden exigirla.
En la API, el bloqueo del propio registro devuelve HTTP 409, con data.error.code = E-INVOICE-SUBMISSION-BLOCKED, data.error.errors.reason = pending_reconciliation, data.error.errors.blocking_invoice_id = UUID del propio registro y data.error.details = null. Consulta su estado y revisa el resultado antes de volver a solicitar el reenvío; una comprobación fallida o inconcluyente no levanta el bloqueo.
¿Qué ocurre si intento enviar el siguiente registro mientras el anterior sigue pendiente?
Antes de crear un nuevo registro mediantePOST /api/invoices (envío síncrono), KubiFACTU comprueba la cadena de la misma empresa cliente y el mismo SIF. Si un registro anterior está pendiente de envío o de confirmar su resultado, la API devuelve HTTP 409 con el código E-INVOICE-SUBMISSION-BLOCKED.
Por ejemplo, en la secuencia A → B → C:
- A ha sido aceptado por AEAT.
- B se ha enviado, pero un timeout deja incierto si AEAT lo recibió.
- El cliente intenta crear C mediante
POST /api/invoices. La API devuelvedata.error.errors.reason = unresolved_submissionydata.error.errors.blocking_invoice_id = ID de B. C no se crea, no se envía a AEAT y no queda en cola.
GET /api/invoices/{invoiceId}) y sigue su estado en recovery.status o mediante su callback_url. Vuelve a solicitar C cuando B esté en resolved. Si B pasa a attention, desbloquéalo como se indica en ¿Qué es la recuperación automática de envíos?.
Si el registro anterior todavía no se ha enviado, el motivo es pending_submission. El bloqueo por unresolved_submission también se mantiene mientras esté pendiente la conciliación de un reenvío duplicado. Un rechazo explícito definitivo de AEAT es distinto de un resultado incierto y no bloquea por sí solo todos los registros posteriores.
El motivo del 409 es pending_submission mientras el registro anterior está en pending y unresolved_submission mientras está en retry, processing o attention. Si un registro histórico bloquea la cadena y tiene recovery: null, consulta su estado en la AEAT y solicita el reenvío del mismo registro si no llegó, conservando su identidad, huella y encadenamiento.
¿Qué ocurre con los registros diferidos que esperan detrás de un registro fallido?
Los envíos diferidos no se bloquean al crearlos: el registro se crea y queda en cola. Si un registro anterior de la misma empresa cliente y SIF falló o tiene un resultado incierto, los diferidos posteriores esperan a que se resuelva y salen más tarde de lo normal. La fecha y hora de generación de esos registros no cambia, porque forma parte de su huella. Cuando un registro llega con retraso, la AEAT puede aceptarlo con errores por la diferencia entre esa fecha y su propia hora (código 2004). El artículo 16.4 de la Orden HAC/1177/2024 obliga a indicar en el envío que una incidencia retrasó la remisión. Por eso, antes de enviarlos, KubiFACTU cambia aS el campo affected_by_incidence_key de los diferidos que esperaban, aunque se crearan con N. Lo hace cuando el registro que falló se reenvía o cuando una consulta aclara su resultado.
Por ejemplo, en la secuencia diferida A → B → C:
- El envío de A falla por un problema de conexión.
- B y C se crean después y quedan en cola detrás de A.
- KubiFACTU reintenta A por su cuenta con
Incidencia = Sy marca B y C conS. Los dos salen después conIncidencia = S.
recovery: null conservan el valor con el que se crearon si esperan detrás de un registro en recuperación automática.
¿Qué ocurre si Veri*Factu no identifica el NIF o el nombre del emisor?
La AEAT comprueba que el NIF y el nombre o razón social del obligado a emitir (sender_data) y, si se informa, del representante, coinciden con su censo. Si no coinciden, rechaza la remisión completa con un error SOAP, por ejemplo:
vf_post_status = successyvf_record_registration_status = failed, con el detalle envf_error_descriptions.- El registro no se puede reenviar: el reenvío manda los mismos datos y volvería a fallar.
- El registro no bloquea los siguientes registros del SIF.
- Revisa con tu cliente el NIF y el nombre o razón social tal como constan en la AEAT. Si el NIF de la empresa cliente es erróneo, corrígelo primero en la empresa cliente.
- Envía una subsanación con registro previo rechazado (
correction_key = Syprevious_rejection_key = X) con los datos corregidos.
Un alta normal con el mismo número de factura se rechaza como duplicada. Usa siempre la subsanación.
vf_post_status = failure: se resuelven reenviando el mismo registro.
¿Un CSV vacío significa que el registro no está acreditado?
No. El campocsv (Código Seguro de Verificación) no es un indicador del estado del registro.
La AEAT emite el CSV en la respuesta a la remisión y acredita la remisión, no cada registro individual. Según la documentación técnica de la AEAT «Sistemas Informáticos de Facturación» (v1.0.3, apartado 6.4.4), el CSV debe guardarlo el SIF en el momento del alta y no puede recuperarse mediante consultas posteriores. Por eso un registro aceptado puede tener csv vacío (null). Ocurre, por ejemplo, cuando el resultado del envío no llegó (timeout o respuesta ilegible) y se confirmó después con una consulta de estado.
¿Qué CSV recibe cada registro en un envío diferido por lote?
Todos los registros del mismo envío comparten el mismo CSV, también los rechazados. Solo se omite cuando la AEAT rechaza todos los registros del envío.¿Qué pasa con el CSV si reenvío un registro?
Un reenvío no borra un CSV que el registro ya tenga guardado cuando la nueva respuesta de la AEAT no incluye uno, por ejemplo ante un registro duplicado, o cuando el envío falla sin respuesta. Si la nueva respuesta trae un CSV, este sustituye al anterior.Hay un límite de 12 líneas (conceptos) para las facturas. ¿Qué debo hacer si un cliente emite facturas con más de 12 líneas?
La lista de los conceptos facturados deben agruparse por condición fiscal completa. En ese sentido, el número máximo de líneas es de 12.Caso 1: Factura con todas las líneas al 21%
Si las líneas al 21% se acogen a regímenes diferentes, deben generarse múltiples agrupaciones en el desglose, cada una con su combinación única detax_rate + vat_tax_regime_key o igic_tax_regime_key + equalization_tax_rate (si aplica).
Ejemplo válido:
- Línea 1: 21%, régimen general
- Línea 2: 21%, régimen criterio de caja
Caso 2: Factura con líneas al 21% y al 10%
Se pueden informar más de una clave de régimen por cada tipo impositivo, siempre que existan líneas que lo justifiquen. Ejemplo válido:- Línea 1: 21%, régimen general
- Línea 2: 21%, régimen especial agencias
- Línea 3: 10%, régimen general
- 21% + régimen general
- 21% + régimen especial agencias
- 10% + régimen general
¿Cómo se debe aplicar una retención por IRPF a una factura entre profesionales?
En las facturas, a menudo se incluyen menciones, detracciones, adiciones o cantidades que no forman parte de la información fiscalmente obligatoria de una factura. A título de ejemplo, podemos mencionar: el recargo financiero (al igual que ocurre con los importes suplidos), la retención por garantía decenal, los suplidos o, en este caso, la retención de IRPF. Todos estos importes, aunque se incluyen en la factura por su evidente importancia, no son importes “propios” de la factura, razón por la que no afectan a la base ni a la cuota de IVA, ni al “Importe Total” . Se trata de cantidades que alteran el “total a pagar” añadiendo o restando cantidades, pero no el “importe total factura”. Por ello cuando sea preciso incluirlos en la factura, esa parte NO integrará el registro de facturación. A este respecto, a modo de consejo o recomendación, para facilitar la comprensión de este matiz al cliente que reciba la factura, se podrían incluir ambos importes en la factura: “Importe total factura” (que es el que aparece en el QR tributario) y “Total a pagar”, debidamente diferenciados.¿Cómo informar una factura con IPSI?
Para las nuevas peticiones contax_type_key: "02", informa ipsi_tax_regime_key con una de las claves admitidas (01, 08, 11, 18, 19 o 20) y omite vat_tax_regime_key e igic_tax_regime_key. La referencia de la API describe el alcance concreto de cada clave; no debe interpretarse como cobertura completa de todos los regímenes IPSI.
La documentación técnica de la AEAT «Sistemas Informáticos de Facturación», versión 1.2.2 de 08/04/2026, apartado 3.1.3 y punto 15.6, admite estas seis claves (PDF de validaciones y errores). La AEAT indica que la omisión de la clave se avisa hasta el 31/12/2026 y se rechaza desde el 01/01/2027. KubiFACTU validará el campo requerido y las combinaciones incompatibles desde esta actualización, que pueden producir una respuesta HTTP 422.