Qué cambia en un TPV con TicketBAI
Cada ticket que emite tu TPV es una factura simplificada, y con TicketBAI cada una genera un registro: se firma, se encadena con el anterior y se envía a la hacienda foral que corresponda al comercio. Tu caja sigue calculando importes, impuestos y numeración como hasta ahora. Lo nuevo es ese registro y lo que tiene que acompañar al ticket.
Con KubiBAI, tu TPV manda la venta en JSON y recibe el registro ya generado, su estado, el identificador TBAI y el QR. No construyes XML ni gestionas la firma de la factura: KubiBAI firma con su certificado de Software Garante, o con el tuyo si eres titular de uno. Si el TPV tiene su propio certificado dado de alta en el panel, la petición lo indica (más abajo).
Lo que tiene que llevar el ticket
El ticket, impreso o digital, lleva el QR de TicketBAI y el identificador de la factura. En la respuesta recibes:
tbai_identifier: el código único de la factura en TicketBAI.
batuz_qr_value y batuz_qr_image: la URL que codifica el QR y la imagen, para imprimirla tal cual.
signature_value: la firma, que sirve para encadenar la factura siguiente.
Tu TPV solo tiene que pintarlos en el ticket.
No hace falta esperar a la hacienda para imprimir
En una caja, medio segundo importa. Por eso el envío tiene tres modos, que eliges en cada petición con async_mode:
| Modo |
Firma |
Envío a la hacienda |
Qué devuelve |
none |
Síncrona |
Síncrono |
La factura ya procesada, con el resultado de la hacienda. |
lite |
Síncrona |
Asíncrono |
El estado inicial, con el identificador TBAI y el QR ya generados. |
full |
Asíncrona |
Asíncrono |
La confirmación de que la factura está en cola. |
Para un TPV, lite suele ser el punto medio: tienes el QR al instante para imprimir el ticket, y el envío a la hacienda se hace aparte. Eso sí, la respuesta inicial no dice que la hacienda haya aceptado la factura: si luego la rechaza, el ticket ya entregado lleva el QR de una factura rechazada, y habrá que corregirla y reenviarla. El resultado final te llega por webhook a la URL que indiques en webhook_url, o lo consultas cuando quieras con el endpoint de estado.
Si el comercio emite pocas ventas y prefieres lo más simple, none te da el resultado de la hacienda en la propia respuesta.
Del ticket a la factura completa
Un ticket se envía con is_simplified_invoice: true y sin destinatario. Si el cliente pide después una factura con sus datos, se emite una factura completa que indica cuál sustituye: issued_in_substitution_of_simplified: true y la simplificada en replaced_rectified_invoices.
No es una rectificativa y no usa sus campos. Los dos casos, con su JSON, están en los ejemplos de la API.
La cadena y las varias cajas
TicketBAI encadena las facturas: cada una lleva los datos de la anterior. Tienes dos formas de resolverlo:
- Envías
previous_invoice_data en cada factura, con la firma de la anterior. Si KubiBAI reconoce el signature_value, completa la serie, el número y la fecha.
- Si has activado el encadenamiento automático para la empresa o para el TPV, puedes omitirlo. Es opcional y se activa desde el panel web de KubiBAI.
Cuando una factura sale de un TPV dado de alta en el panel de KubiBAI, la petición incluye pos_system_data con el identificador que el panel asigna a ese TPV y la contraseña del certificado del TPV con el que se firma la factura; KubiBAI no la guarda. Así KubiBAI sabe de qué TPV viene cada factura y puede encadenarlas por TPV. Si necesitas saber cuál fue la última factura correcta o cuáles están a ambos lados de otra, hay endpoints para la última factura y para las facturas adyacentes.
Si algo falla
- La hacienda rechaza la factura.
tbai_post_status llega como fail y tbai_post_response_data trae la respuesta de la hacienda. Si el rechazo es por el contenido, reenviar no lo arreglará: corrige los datos.
- No hay respuesta o falla la conexión. Si la respuesta es indeterminada, la factura queda con
has_undefined_response: true. El endpoint de reenvío reintenta el envío con el mismo XML firmado, sin regenerarlo ni volver a firmar, así que conserva las fechas de emisión y de firma.
- La hacienda está en mantenimiento. KubiBAI responde
503 con Retry-After, los segundos hasta el final previsto.
- Demasiadas peticiones. Responde
429, también con Retry-After.
Los errores de validación y de negocio llegan siempre con la misma forma, bajo data.error, con code, message, http_code y, cuando procede, los errores campo a campo.
Anular y corregir
Anular una factura es un registro adicional de TicketBAI: no la borra, la invalida a efectos fiscales, y su número no se puede reutilizar. Para corregir datos sin cambiar el importe total, en Araba y Gipuzkoa existe Zuzendu; en Bizkaia no. Si cambia el importe, toca una factura rectificativa, por sustitución o por diferencias.
Cómo se integra
- Pide acceso al entorno de pruebas y da de alta una empresa con su territorio.
- Envía un ticket de prueba. Las facturas de pruebas se remiten a los servidores de pruebas de TicketBAI, así que validas el flujo completo con la hacienda de verdad.
- Imprime el QR y el identificador en el ticket.
- Prueba los fallos: un rechazo, un reenvío y una anulación.
- Pasa a producción cambiando la URL base y las credenciales.
Si tus clientes también facturan fuera de Euskadi, el mismo planteamiento para la AEAT está en VeriFactu para TPV, con KubiFACTU.