Tutorial

Facturación electrónica obligatoria 2026: guía técnica para desarrolladores

28 de febrero de 2026 12 min de lectura PWR.es

La Ley 18/2022 de Creación y Crecimiento de Empresas (Ley Crea y Crece) y el Real Decreto 1007/2023 (Reglamento Verifactu) establecen la facturación electrónica obligatoria en España. A partir de 2026, todas las empresas con facturación superior a 8 millones de euros deben emitir facturas electrónicas. En 2027, la obligación se extiende a todas las empresas y autónomos.

Para los desarrolladores, esto significa que cualquier aplicación que genere facturas necesita actualizarse. No vale un PDF bonito enviado por email. La factura debe generarse en formato estructurado, firmarse electrónicamente, y enviarse a la AEAT en tiempo casi real. Este artículo explica cómo hacerlo.

Verifactu: el sistema de la AEAT

Verifactu (Verificación de Facturas) es el sistema mediante el cual los contribuyentes deben remitir los registros de facturación a la AEAT de forma electrónica. No es un formato de factura, sino un protocolo de comunicación con Hacienda. Cada factura emitida debe registrarse en la AEAT mediante un envío XML firmado electrónicamente.

El sistema define dos tipos de registros: alta (nueva factura) y anulación. Cada registro contiene los datos fiscales de la factura (NIF emisor, NIF receptor, base imponible, tipo de IVA, cuota, fecha de operación) más un hash encadenado que garantiza la integridad de la secuencia de facturas.

El hash encadenado: integridad de la cadena

Verifactu implementa un mecanismo de hash encadenado similar a una blockchain simplificada. Cada registro de facturación incluye el hash SHA-256 del registro anterior, formando una cadena inalterable. Si se modifica o elimina un registro intermedio, la cadena se rompe y la AEAT lo detecta.

PHP
<?php
/**
 * Generar el hash encadenado para Verifactu
 * Según especificación AEAT: SHA-256 del registro anterior
 */
function verifactu_hash_encadenado($registro_actual, $hash_anterior) {
    // Campos que forman parte del hash (orden específico AEAT)
    $cadena = implode('&', [
        $registro_actual['nif_emisor'],
        $registro_actual['numero_factura'],
        $registro_actual['fecha_expedicion'],
        $registro_actual['tipo_factura'],
        $registro_actual['cuota_total'],
        $registro_actual['base_total'],
        $hash_anterior, // Hash del registro anterior (vacío si es el primero)
    ]);

    return hash('sha256', $cadena);
}

Formato XML de envío

Los registros de facturación se envían a la AEAT en formato XML, firmado con certificado electrónico cualificado. El XML debe cumplir el esquema XSD publicado por la AEAT. Un registro de alta tiene esta estructura simplificada:

XML
<RegistroAlta>
  <IDFactura>
    <IDEmisorFactura>B12345678</IDEmisorFactura>
    <NumSerieFacturaEmisor>2026/001</NumSerieFacturaEmisor>
    <FechaExpedicionFacturaEmisor>2026-03-15</FechaExpedicionFacturaEmisor>
  </IDFactura>
  <TipoFactura>F1</TipoFactura>
  <DescripcionOperacion>Servicios de desarrollo web</DescripcionOperacion>
  <Desglose>
    <DetalleDesglose>
      <ClaveRegimen>01</ClaveRegimen>
      <BaseImponible>1000.00</BaseImponible>
      <TipoImpositivo>21.00</TipoImpositivo>
      <CuotaRepercutida>210.00</CuotaRepercutida>
    </DetalleDesglose>
  </Desglose>
  <CuotaTotal>210.00</CuotaTotal>
  <ImporteTotal>1210.00</ImporteTotal>
  <Huella>
    <Hash>a3f2b8c1d4e5f6...</Hash>
    <Algoritmo>SHA-256</Algoritmo>
  </Huella>
</RegistroAlta>

Firma electrónica del envío

El envío XML debe firmarse con un certificado electrónico cualificado (certificado de persona jurídica o de representante). La firma debe ser XAdES-BES o XAdES-T, que incluye marca temporal de una autoridad de sellado de tiempo (TSA). Esto garantiza no solo la autenticidad sino el momento exacto de emisión.

Implementar firma XAdES en PHP puro es complejo pero factible. Se necesita: el certificado en formato PFX/P12, la clave privada, la cadena de certificación, y una TSA (la FNMT ofrece una gratuita para certificados emitidos por ella).

PHP
<?php
// Firma XAdES simplificada con Rúbrica (PWR.es)
require_once 'rubrica.php';

// Cargar certificado de empresa
$certificado = rubrica_cargar_certificado(
    'certificados/empresa.pfx',
    'password-del-pfx'
);

// Firmar el XML de Verifactu
$xml_firmado = rubrica_firmar_xades($xml_registro, $certificado, [
    'tipo' => 'XAdES-T',
    'tsa' => 'https://tsa.fnmt.es/tsa/tss', // TSA de la FNMT
]);

// El resultado es XML con firma XAdES-T embebida
// Listo para enviar a la AEAT

Envío a la AEAT: endpoint y autenticación

La AEAT proporciona un servicio web SOAP para recibir los registros de facturación. El endpoint de producción requiere autenticación con certificado SSL cliente (mutual TLS). En el entorno de pruebas, se usa un certificado de pruebas emitido por la AEAT.

PHP
<?php
// Envío a la AEAT vía SOAP con certificado cliente
function verifactu_enviar($xml_firmado, $certificado_pfx, $password) {
    $endpoint = 'https://www1.agenciatributaria.gob.es/'
              . 'wlpl/TGVI-VERI/ws/SistemaVerifactuSOAP';

    // Extraer cert y clave del PFX
    $pfx_contenido = file_get_contents($certificado_pfx);
    openssl_pkcs12_read($pfx_contenido, $certs, $password);

    // Guardar temporalmente para cURL
    $tmp_cert = tempnam(sys_get_temp_dir(), 'cert');
    $tmp_key = tempnam(sys_get_temp_dir(), 'key');
    file_put_contents($tmp_cert, $certs['cert']);
    file_put_contents($tmp_key, $certs['pkey']);

    $ch = curl_init($endpoint);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => $xml_firmado,
        CURLOPT_HTTPHEADER => ['Content-Type: application/xml'],
        CURLOPT_SSLCERT => $tmp_cert,
        CURLOPT_SSLKEY => $tmp_key,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
    ]);

    $respuesta = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // Limpiar temporales
    unlink($tmp_cert);
    unlink($tmp_key);

    return [
        'exito' => $http_code === 200,
        'respuesta' => $respuesta,
    ];
}

Tipos de factura y claves de régimen

Verifactu define tipos de factura específicos que debes mapear correctamente. Los más comunes son:

  • F1 — Factura completa (artículo 6 del RD 1619/2012)
  • F2 — Factura simplificada (ticket, artículo 7)
  • F3 — Factura emitida en sustitución de simplificada
  • R1 — Factura rectificativa por error en datos
  • R2 — Factura rectificativa por artículo 80.3 LIVA (concurso de acreedores)
  • R3 — Factura rectificativa por artículo 80.4 LIVA (créditos incobrables)
  • R4 — Factura rectificativa por resto de causas
  • R5 — Factura rectificativa en facturas simplificadas

Las claves de régimen fiscal determinan el tipo de IVA aplicable. Las más habituales: 01 (régimen general), 02 (exportaciones), 05 (régimen de caja), 07 (régimen especial de agencias de viajes), 15 (recargo de equivalencia).

Requisitos del software de facturación

El Reglamento Verifactu establece requisitos específicos para el software que genera las facturas. Tu aplicación debe:

  • Generar registros de facturación con todos los campos obligatorios
  • Calcular y almacenar el hash encadenado SHA-256 de cada registro
  • Firmar electrónicamente cada envío con certificado cualificado
  • Enviar los registros a la AEAT en tiempo real o en plazo máximo de 4 días
  • Mantener un registro local de todos los envíos y respuestas de la AEAT
  • Incluir un código QR en cada factura con enlace de verificación AEAT
  • Generar una declaración responsable de cumplimiento del sistema
  • No permitir la modificación de registros ya enviados (solo rectificación)

El código QR obligatorio

Cada factura emitida debe incluir un código QR que permita al receptor verificar su validez en la sede electrónica de la AEAT. El QR codifica una URL con los parámetros de identificación de la factura. Esto permite al cliente comprobar que la factura está efectivamente registrada en Hacienda.

PHP
<?php
// Generar URL de verificación para el QR
function verifactu_url_verificacion($factura) {
    $params = http_build_query([
        'nif' => $factura['nif_emisor'],
        'numserie' => $factura['numero'],
        'fecha' => $factura['fecha'],
        'importe' => $factura['importe_total'],
    ]);

    return 'https://www2.agenciatributaria.gob.es/'
         . 'wlpl/TGVI-VERI/ValidarFactura?' . $params;
}

// Generar QR con la librería Verifactu de PWR.es
$url_qr = verifactu_url_verificacion($factura);
$qr_png = verifactu_generar_qr($url_qr); // PNG en base64

Calendario de implantación

  • 1 de julio de 2026 — Obligatorio para empresas con facturación > 8M€
  • 1 de enero de 2027 — Obligatorio para el resto de empresas y autónomos
  • El software debe estar certificado antes de la fecha de obligación
  • Período transitorio: se permiten envíos en lotes durante los primeros 6 meses

Si desarrollas una aplicación que genera facturas — ya sea un ERP, un CRM, una tienda online o un sistema de gestión — necesitas integrar Verifactu antes de julio de 2026 para empresas grandes, o antes de enero de 2027 para el resto.

Verifactu de PWR.es: todo en un archivo PHP

Verifactu, el módulo de facturación electrónica de PWR.es, implementa todo lo descrito en este artículo en un solo archivo PHP. Genera el XML según el esquema de la AEAT, calcula los hashes encadenados, firma con XAdES-T usando Rúbrica, envía por SOAP con certificado cliente, y genera el QR. Sin Composer, sin Java, sin SAP.

La integración es directa: defines los datos de la factura en un array PHP, llamas a verifactu_emitir(), y el módulo se encarga de todo. Recibes la respuesta de la AEAT con el código de registro. Si hay error, recibes el código de error específico para que puedas corregir y reenviar.

La facturación electrónica no tiene por qué ser un proyecto de 6 meses con consultoras y middleware de Java. Con las herramientas adecuadas, es un require_once y una función. Así de simple debería ser la tecnología fiscal.