Saltar al pie de página
USANDO IRONPDF

VeriFactu y TicketBAI: recibos fintech conformes con RDL 15/2025

VeriFactu y TicketBAI: recibos fintech conforme a RDL 15/2025 con IronPDF en España

En España, la generación de recibos fintech ya no es solo un problema de formato: desde el 29 de julio de 2025, los proveedores de software de facturación están obligados a distribuir productos capaces de emitir registros conformes con VeriFactu (Royal Decree-Law 15/2025, de 2 de diciembre de 2025). Para plataformas de pagos, neobancos, plataformas de préstamo y aplicaciones de gestión de gastos empresariales que operan en España, esto significa que cada recibo generado puede estar sujeto a los requisitos de la AEAT: leyenda obligatoria VERI*FACTU, código QR de verificación con URL de la sede electrónica de la AEAT, y — en el País Vasco — formato XML TicketBAI con firma XAdES para las tres diputaciones forales de Bizkaia, Gipuzkoa y Araba.

El riesgo no recae sobre el usuario final sino sobre el proveedor de software: hasta €150.000/año de penalización para vendedores de software de facturación no conforme. Para ISV que integran un componente PDF de terceros en su software de facturación, la elección de la biblioteca PDF determina si el software puede emitir recibos conformes o no.


Anatomía de un recibo VeriFactu conforme con RDL 15/2025

Un recibo VeriFactu conforme con el RDL 15/2025 no es simplemente un PDF con datos de transacción. Tiene tres elementos obligatorios que el motor de generación PDF debe soportar:

1. Leyenda obligatoria VERI*FACTU

Cada visualización de un registro de facturación VeriFactu debe incluir la leyenda textual VERI*FACTU — con el asterisco en posición central, exactamente como se muestra, sin variaciones tipográficas. La leyenda alternativa o complementaria es Factura verificable en la sede electrónica de la AEAT, también reproducida verbatim.

Con IronPDF, esta leyenda se incluye en la plantilla HTML del recibo o en el pie de página mediante HtmlHeaderFooter:

using IronPdf;
using System.Security.Cryptography;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.MarginTop = 15;
renderer.RenderingOptions.MarginBottom = 15;

string receiptHtml = $@"
    <h1>Transaction Receipt</h1>
    <p><strong>Transaction ID:</strong> {tx.Id}</p>
    <p><strong>Timestamp (UTC):</strong> {tx.CompletedAt:u}</p>
    <p><strong>Amount:</strong> {tx.Amount:F2} {tx.Currency}</p>
    <p><strong>Fee:</strong> {tx.Fee:F2} {tx.Currency}</p>
    <p><strong>From:</strong> {tx.SenderRef} &rarr; <strong>To:</strong> {tx.ReceiverRef}</p>
    <p><strong>Resulting Balance:</strong> {tx.ClosingBalance:F2} {tx.Currency}</p>";

var pdf = renderer.RenderHtmlAsPdf(receiptHtml);

string hash = Convert.ToHexString(SHA256.HashData(pdf.BinaryData));

await _db.StoreReceiptHashAsync(tx.Id, hash);

await _blobStorage.UploadImmutableAsync($"receipts/{tx.Id}.pdf", pdf.BinaryData);
using IronPdf;
using System.Security.Cryptography;

var renderer = new ChromePdfRenderer();

renderer.RenderingOptions.MarginTop = 15;
renderer.RenderingOptions.MarginBottom = 15;

string receiptHtml = $@"
    <h1>Transaction Receipt</h1>
    <p><strong>Transaction ID:</strong> {tx.Id}</p>
    <p><strong>Timestamp (UTC):</strong> {tx.CompletedAt:u}</p>
    <p><strong>Amount:</strong> {tx.Amount:F2} {tx.Currency}</p>
    <p><strong>Fee:</strong> {tx.Fee:F2} {tx.Currency}</p>
    <p><strong>From:</strong> {tx.SenderRef} &rarr; <strong>To:</strong> {tx.ReceiverRef}</p>
    <p><strong>Resulting Balance:</strong> {tx.ClosingBalance:F2} {tx.Currency}</p>";

var pdf = renderer.RenderHtmlAsPdf(receiptHtml);

string hash = Convert.ToHexString(SHA256.HashData(pdf.BinaryData));

await _db.StoreReceiptHashAsync(tx.Id, hash);

await _blobStorage.UploadImmutableAsync($"receipts/{tx.Id}.pdf", pdf.BinaryData);
Imports IronPdf
Imports System.Security.Cryptography

Dim renderer As New ChromePdfRenderer()

renderer.RenderingOptions.MarginTop = 15
renderer.RenderingOptions.MarginBottom = 15

Dim receiptHtml As String = $"
    <h1>Transaction Receipt</h1>
    <p><strong>Transaction ID:</strong> {tx.Id}</p>
    <p><strong>Timestamp (UTC):</strong> {tx.CompletedAt:u}</p>
    <p><strong>Amount:</strong> {tx.Amount:F2} {tx.Currency}</p>
    <p><strong>Fee:</strong> {tx.Fee:F2} {tx.Currency}</p>
    <p><strong>From:</strong> {tx.SenderRef} &rarr; <strong>To:</strong> {tx.ReceiverRef}</p>
    <p><strong>Resulting Balance:</strong> {tx.ClosingBalance:F2} {tx.Currency}</p>"

Dim pdf = renderer.RenderHtmlAsPdf(receiptHtml)

Dim hash As String = Convert.ToHexString(SHA256.HashData(pdf.BinaryData))

Await _db.StoreReceiptHashAsync(tx.Id, hash)

Await _blobStorage.UploadImmutableAsync($"receipts/{tx.Id}.pdf", pdf.BinaryData)
$vbLabelText   $csharpLabel

El pie de página del recibo debe incluir la leyenda VERI*FACTU y el hash de integridad:

var shortHash = hash[..12];

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = $@"
        <div style='font-size:9px; color:#666; text-align:center;'>
            Generated: {tx.CompletedAt:u} &nbsp;|&nbsp;
            TX: {tx.Id} &nbsp;|&nbsp;
            SHA-256: {shortHash}... &nbsp;|&nbsp;
            VERI*FACTU
        </div>"
};
var shortHash = hash[..12];

renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = $@"
        <div style='font-size:9px; color:#666; text-align:center;'>
            Generated: {tx.CompletedAt:u} &nbsp;|&nbsp;
            TX: {tx.Id} &nbsp;|&nbsp;
            SHA-256: {shortHash}... &nbsp;|&nbsp;
            VERI*FACTU
        </div>"
};
HTML

2. Código QR AEAT — URL de verificación y formato

El RDL 15/2025 exige que cada factura simplificada y recibo sujeto a VeriFactu incluya un código QR cuya URL apunta a la sede electrónica de la AEAT para verificación en tiempo real. El formato de la URL es:

https://sede.agenciatributaria.gob.es/Sede/verifactu.html?nif=NIF_EMISOR&numserie=SERIE&fecha=YYYYMMDD&cuota=IMPORTE

Este QR debe generarse como imagen SVG o PNG e insertarse en la plantilla HTML del recibo antes del renderizado PDF. Con IronPDF, el QR embebido en el HTML se renderiza correctamente como imagen dentro del PDF final.

3. Identificador CSV para recibos B2C simplificados

Para recibos B2C (facturas simplificadas), el registro VeriFactu incluye un CSV (Código Seguro de Verificación) generado por el sistema de facturación a partir de la cadena de huellas (huella) encadenada. El CSV debe imprimirse en el recibo como referencia de verificación independiente al QR.


TicketBAI en el País Vasco: tres diputaciones, tres implementaciones

Para plataformas fintech que operan con comercios y usuarios en el País Vasco, el sistema TicketBAI es obligatorio y está activo desde 2022–2024 (calendarios diferenciados por provincia). A diferencia de VeriFactu (nacional), TicketBAI es gestionado por tres autoridades fiscales forales independientes, cada una con su propia especificación XML:

Provincia Autoridad foral Portal Esquema XML
Bizkaia Diputación Foral de Bizkaia bizkaia.eus TicketBAI Bizkaia + BATUZ
Gipuzkoa Diputación Foral de Gipuzkoa gipuzkoa.eus TicketBAI Gipuzkoa
Araba Diputación Foral de Araba araba.eus TicketBAI Araba

Cada registro TicketBAI es un fichero XML firmado con XAdES (XML Advanced Electronic Signatures) y encadenado al registro anterior (similar a la huella de VeriFactu). El PDF de visualización del ticket — el recibo que el cliente recibe — incluye el QR TicketBAI de verificación y la leyenda específica de cada diputación foral.

Para Bizkaia, el sistema se enmarca en el programa BATUZ, que integra TicketBAI con el libro de registros contables (LROE). Esto añade una dimensión adicional a la generación del recibo: el PDF debe ser coherente con el registro LROE enviado a la Diputación Foral de Bizkaia.

Generación del recibo PDF para TicketBAI

El flujo de trabajo para recibos TicketBAI con IronPDF es:

  1. Generar el XML TicketBAI y firmarlo con XAdES mediante el certificado del software de facturación.
  2. Obtener el QR de verificación de la diputación foral correspondiente (Bizkaia, Gipuzkoa o Araba).
  3. Renderizar el recibo HTML con el QR embebido y la leyenda foral correspondiente.
  4. Convertir a PDF con IronPDF ChromePdfRenderer y almacenar en formato inmutable.
  5. Registrar el hash SHA-256 del PDF para trazabilidad.

Por qué el incumplimiento tiene consecuencias asimétricas para los ISV

La arquitectura de penalización del RDL 15/2025 es inusual globalmente: la sanción recae sobre el proveedor del software, no sobre el usuario final. Esto significa que:

  • Un ISV que vende su software de facturación a 500 comercios en España y cuyo software no emite recibos VeriFactu conformes tiene una exposición de €150.000/año — independientemente de cuántos comercios lo usen.
  • Un ISV que opera en el País Vasco y no gestiona los tres dialectos TicketBAI (Bizkaia, Gipuzkoa, Araba) tiene exposición simultánea ante tres diputaciones forales.
  • La ley Crea y Crece (mandatos B2B 2027–2028) añade una capa adicional: el software de facturación debe también soportar la cadena de EN 16931 / CIUS-ES para facturación electrónica B2B.

IronPDF como biblioteca de generación PDF no es un sistema de facturación certificado: es el componente de renderizado dentro del sistema de facturación. La certificación VeriFactu recae sobre el ISV que distribuye el software completo. IronPDF garantiza que el componente PDF del sistema puede renderizar correctamente la leyenda VERI*FACTU, el QR de la AEAT, el identificador CSV y los metadatos del documento.


Casos especiales en el contexto español

Anulaciones y devoluciones bajo VeriFactu. Una transacción anulada o un reembolso también genera un registro VeriFactu de anulación (TipoFactura = R4 o R5), que referencia el registro original mediante su hash (huella). El PDF de anulación es un documento independiente — no modifica el original — y también debe incluir la leyenda VERI*FACTU y el QR de la AEAT.

Transacciones multidivisa con IVA español. Para recibos con importes en divisa extranjera, el desglose del IVA (tipo general 21%, reducido 10%, superreducido 4% o exento) debe aparecer en euros y en la moneda de la transacción. Las cadenas de formato de C# gestionan los separadores decimales españoles (1.234,56 €) mediante CultureInfo.GetCultureInfo("es-ES").

Archivado de largo plazo bajo Crea y Crece. La ley Crea y Crece requiere conservar las facturas electrónicas durante períodos definidos. IronPDF permite archivar recibos en formato PDF/A-3b mediante una única opción de renderizado:

renderer.RenderingOptions.PdfArchiveFormat = IronPdf.Rendering.PdfArchiveFormat.PDF_A_3B

Esto genera documentos conforme a la norma ISO para conservación a largo plazo de registros financieros.

Residencia de datos bajo LOPDGDD. Para plataformas fintech que procesan datos personales de usuarios españoles, el almacenamiento de los recibos PDF en infraestructura española o de la UE es un requisito de la LOPDGDD (transposición española del RGPD). El procesamiento de IronPDF es completamente local — no transmite datos del documento a través de Internet — lo que facilita el cumplimiento de los requisitos de residencia de datos de la AEPD.


Recibos que son registros, no consultas

La diferencia entre "almacenamos datos de transacciones" y "tenemos un registro auditable conforme con VeriFactu" es concreta: un paso de procesamiento añadido al flujo de confirmación de la transacción que genera un documento con la leyenda VERI*FACTU, el QR de verificación de la AEAT, el identificador CSV, el hash SHA-256 y el sello temporal — todo en un PDF almacenado en el momento de la liquidación en almacenamiento inmutable.

IronPDF ofrece a los equipos .NET el control sobre ese paso, desde el renderizado HTML del recibo hasta el sellado del pie de página con la leyenda obligatoria, el hash de la salida y la transmisión al almacenamiento. Si está construyendo o reforzando un canal de transacciones para el mercado español, comience su prueba gratuita de 30 días y verifique que el recibo generado incluye todos los elementos requeridos por la AEAT antes de pasar a producción.

Preguntas Frecuentes

¿Qué leyenda obligatoria debe incluir un recibo VeriFactu en el PDF?

Según el RDL 15/2025, cada visualización de un registro VeriFactu debe incluir la leyenda VERI*FACTU (con asterisco en posición central, exactamente) y/o la leyenda alternativa 'Factura verificable en la sede electrónica de la AEAT'. Ambas deben reproducirse verbatim, sin variaciones tipográficas. Con IronPDF, se incluyen en la plantilla HTML o en el HtmlHeaderFooter del renderizador.

¿Cuál es el formato del QR de verificación de la AEAT para facturas VeriFactu?

El QR VeriFactu apunta a la sede electrónica de la AEAT con URL formato: https://sede.agenciatributaria.gob.es/Sede/verifactu.html?nif=NIF_EMISOR&numserie=SERIE&fecha=YYYYMMDD&cuota=IMPORTE. El QR se genera como imagen y se embebe en el HTML del recibo antes del renderizado PDF con IronPDF.

¿Qué diferencia hay entre TicketBAI en Bizkaia, Gipuzkoa y Araba?

Cada provincia vasca tiene su propia diputación foral y especificación XML para TicketBAI. Bizkaia (bizkaia.eus) incluye el programa BATUZ que integra TicketBAI con el libro de registros contables LROE. Gipuzkoa (gipuzkoa.eus) y Araba (araba.eus) tienen sus propios esquemas con variaciones menores en la estructura XML. Los tres requieren firma XAdES encadenada. El PDF de visualización del recibo incluye el QR foral correspondiente.

¿Cuál es la penalización por distribuir software de facturación no conforme con VeriFactu?

Hasta €150.000/año para el proveedor del software de facturación, independientemente del número de usuarios finales. La penalización recae sobre el ISV que distribuye el software, no sobre el contribuyente que lo usa. Esto hace crítica la conformidad de todos los componentes del sistema de facturación, incluida la biblioteca de generación PDF.

Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

Leer más

Equipo de soporte de Iron

Estamos disponibles online las 24 horas, 5 días a la semana.
Chat
Email
Llámame