Qué cambia en un TPV con VeriFactu
Cada factura simplificada que emite tu TPV, el ticket de caja en la mayoría de comercios, genera un registro de facturación. Ese registro lleva una huella, se encadena con el anterior y se envía a la AEAT. Tu caja sigue calculando importes, impuestos y numeración como hasta ahora: lo nuevo es el registro y lo que tiene que aparecer en el ticket.
Con KubiFACTU, tu TPV envía los datos de la venta en JSON y recibe el registro ya generado, su estado y el QR. No hay XML que construir ni firmas que gestionar.
Lo que tiene que llevar el ticket
El ticket, impreso o digital, debe entregarse con un QR de cotejo que permita al cliente verificar que la factura se ha remitido a la AEAT. Según la documentación de la API:
- Junto al QR debe aparecer la frase «Factura verificable en la sede electrónica de la AEAT» o «VERI*FACTU», con un tipo de letra y un tamaño visibles, similares a los del resto de datos.
- El QR debe medir entre 30×30 y 40×40 milímetros.
El QR lo genera KubiFACTU. En la respuesta recibes qr_value (la URL que codifica) y qr_image_url (la imagen PNG), así que tu TPV solo tiene que imprimirlo en el ticket. Si la AEAT rechaza el registro, ambos campos llegan a null.
Ventas seguidas: el límite de la AEAT y el envío diferido
La AEAT limita cuántas solicitudes puede enviar cada obligado tributario. Por defecto, el límite es de una solicitud cada 60 segundos por CIF. La respuesta de la API te indica cuánto esperar antes de enviar otra (next_request_waiting_time y next_request_datetime).
Si tu cliente emite más de una factura por minuto, usa el envío diferido:
- Tu TPV envía la venta a
/api/invoices/deferred, con la misma petición de siempre más una callback_url.
- KubiFACTU genera al momento los datos que necesitas, como el QR, para que puedas imprimir el ticket.
- El registro espera el margen que marca la AEAT, se envía, y el resultado llega a tu servidor por callback. Puede ser aceptado, aceptado con errores o rechazado.
Si el comercio no emite a ese ritmo, es más sencillo el envío normal: la AEAT responde en el momento, sin esperas ni callbacks.
Del ticket a la factura completa
Un ticket es una factura simplificada: invoice_type_key F2 y sin destinatario. Si el cliente pide después una factura con sus datos, se emite una factura en sustitución de la simplificada (F3), que indica en substituted_invoices cuál sustituye.
Los dos casos están como ejemplos de petición.
Si algo falla
- Fallo de conexión con VeriFactu. Si la respuesta trae
"vf_post_status": "failure" (timeout, error del servidor, falta de respuesta o un error de validación básica), no modifiques el registro ni generes otro de la misma factura. Reenvíalo con el endpoint de reenvío: se envía de nuevo sin regenerarlo, con la misma huella y el mismo encadenamiento.
- La AEAT rechaza el registro. Se emite una subsanación con registro previo rechazado (
correction_key S y previous_rejection_key X).
- La AEAT lo acepta con errores. Se emite una subsanación ordinaria (
correction_key S).
La subsanación solo se usa cuando la AEAT ha rechazado o aceptado con errores el registro de forma explícita. Los dos casos tienen su ejemplo.
Varias cajas y varias tiendas
Los registros se encadenan por separado dentro de cada SIF, el sistema informático de facturación, y para cada empresa. Hay una cadena por cada pareja de SIF y empresa emisora. Una empresa con varias tiendas puede dar un SIF a cada establecimiento para que su trazabilidad se trate por separado, aunque no es obligatorio. El encadenamiento lo calcula KubiFACTU.
Cómo se integra
- Regístrate en el entorno de pruebas, da de alta una empresa y copia su API-KEY.
- Envía una factura simplificada siguiendo el inicio rápido.
- Imprime el QR y la frase en tu ticket.
- Prueba el envío diferido y los fallos.
- Pasa a producción cuando todo encaje. Ten en cuenta que producción empieza de cero: las API-KEY y los SIF son nuevos.
Si tienes dudas sobre las fechas, mira los plazos de VeriFactu. Y si tu TPV también vende a comercios de Euskadi, el equivalente para las haciendas forales está en TicketBAI para TPV, con KubiBAI.