PWR Verifactu

Facturacion electronica firmada para el sistema Verifactu de Espana. Crea facturas con firma digital (via Rubrica), encadenamiento de hashes (blockchain de facturas), exportacion XML/JSON y registro local.

Instalacion

Verifactu es un unico archivo PHP que depende del modulo Rubrica para firma digital.

PHP
require_once __DIR__ . '/core/verifactu.php';

Requisitos minimos

  • PHP 7.2 o superior
  • Modulo core/rubrica.php (se carga automaticamente)
  • Extension sodium (incluida en PHP 7.2+) o ffi + liboqs para ML-DSA
  • Directorio datos/verifactu/ con permisos de escritura (se crea automaticamente)
Carga automatica: Verifactu incluye automaticamente Rubrica al cargarse. No necesitas hacer require de ambos archivos por separado.

Inicio rapido

Crea una factura firmada, verificala y exportala en 10 lineas.

PHP
require_once 'core/verifactu.php';

// Generar claves de firma
$claves = pwr_rubrica_generar_claves();

// Crear factura firmada
$factura = ['numero' => 'F-001', 'fecha' => '2026-03-23',
    'emisor' => ['nif' => 'B12345678', 'nombre' => 'Mi Empresa S.L.'],
    'receptor' => ['nif' => 'A87654321', 'nombre' => 'Cliente S.A.'],
    'lineas' => [['concepto' => 'Servicio web', 'cantidad' => 1, 'precio' => 1000, 'iva' => 21]]];
$res = pwr_verifactu_crear($factura, $claves['clave_privada']);

// Verificar y exportar
$ok = pwr_verifactu_verificar($res['factura_firmada'], $claves['clave_publica']);
$xml = pwr_verifactu_exportar_xml($res['factura_firmada']);

Funciones

pwr_verifactu_crear()

Crea una factura electronica firmada. Calcula importes, genera hash SHA3-512, firma con Rubrica y encadena con la factura anterior.

Firma
pwr_verifactu_crear(array $factura, string $clave_privada_b64, string $hash_anterior = ''): array
ParametroTipoDescripcion
$facturaarrayDatos: numero, fecha, emisor (nif, nombre), receptor (nif, nombre), lineas (concepto, cantidad, precio, iva)
$clave_privada_b64stringClave privada en base64 (de Rubrica)
$hash_anteriorstringHash de la factura anterior en la cadena ('' para la primera)

Retorna: array con ok, factura_firmada (array completo), hash, firma.

pwr_verifactu_verificar()

Verifica una factura firmada: recalcula el hash para comprobar integridad y valida la firma digital.

Firma
pwr_verifactu_verificar(array $factura_firmada, string $clave_publica_b64): array
ParametroTipoDescripcion
$factura_firmadaarrayFactura con firma y metadatos (resultado de pwr_verifactu_crear)
$clave_publica_b64stringClave publica del emisor en base64

Retorna: array con ok, valida (bool), integridad (bool), firma_valida (bool).

pwr_verifactu_verificar_cadena()

Verifica una cadena completa de facturas: comprueba cada factura y que los hashes esten correctamente encadenados.

Firma
pwr_verifactu_verificar_cadena(array $facturas, string $clave_publica_b64): array
ParametroTipoDescripcion
$facturasarrayArray de facturas firmadas en orden cronologico
$clave_publica_b64stringClave publica del emisor

Retorna: array con ok, total, validas, cadena_integra (bool).

pwr_verifactu_exportar_xml()

Exporta una factura firmada a formato XML compatible con la estructura Verifactu de la AEAT.

Firma
pwr_verifactu_exportar_xml(array $factura_firmada): string

Retorna: string XML con formato SOAP Verifactu.

pwr_verifactu_exportar_json()

Exporta una factura firmada a formato JSON portable para intercambio entre sistemas.

Firma
pwr_verifactu_exportar_json(array $factura_firmada): string

Retorna: string JSON formateado con metadatos de version y fecha de exportacion.

pwr_verifactu_registrar()

Almacena una factura firmada en el registro local JSON. Si ya existe (mismo numero + NIF), la actualiza.

Firma
pwr_verifactu_registrar(array $factura_firmada): array

Retorna: array con ok, id (identificador unico del registro).

pwr_verifactu_listar()

Lista facturas del registro local con filtros opcionales por fecha y NIF del emisor.

Firma
pwr_verifactu_listar(array $filtros = []): array
FiltroTipoDescripcion
desdestringFecha minima (YYYY-MM-DD)
hastastringFecha maxima (YYYY-MM-DD)
emisor_nifstringFiltrar por NIF del emisor

Retorna: array con las facturas que cumplen los filtros.

pwr_verifactu_info()

Devuelve informacion del modulo: version, estado de Rubrica, directorio de almacenamiento y numero de facturas registradas.

Firma
pwr_verifactu_info(): array

Retorna: array con version, rubrica_disponible, rubrica_version, directorio, facturas_registradas, hash_algoritmo.

Configuracion

Verifactu almacena las facturas registradas en datos/verifactu/registro.json. El directorio se crea automaticamente al registrar la primera factura.

ElementoValorDescripcion
Directoriodatos/verifactu/Almacenamiento del registro de facturas
Registrodatos/verifactu/registro.jsonArchivo JSON con todas las facturas registradas
FirmaRubrica (Ed25519 / ML-DSA)Se usa el mejor backend disponible de Rubrica
HashSHA3-512 (o SHA-512 fallback)Hash de la cadena canonica de cada factura
Cadenanumero|fecha|emisor_nif|receptor_nif|total|hash_anteriorCadena canonica para calcular el hash
Cadena de hashes: Cada factura incluye el hash de la factura anterior. Esto crea una cadena inmutable (similar a blockchain) donde alterar una factura invalida todas las posteriores.
Produccion: El registro local es adecuado para desarrollo y pruebas. En produccion, complementalo con el envio a la AEAT via su servicio web oficial.

Ejemplos

Crear y firmar una factura

PHP
require_once 'core/verifactu.php';

$claves = pwr_rubrica_generar_claves();

$factura = [
    'numero'   => 'F-2026-001',
    'fecha'    => '2026-03-23',
    'emisor'   => ['nif' => 'B12345678', 'nombre' => 'Mi Empresa S.L.'],
    'receptor' => ['nif' => 'A87654321', 'nombre' => 'Cliente S.A.'],
    'lineas'   => [
        ['concepto' => 'Desarrollo web', 'cantidad' => 1, 'precio' => 3000, 'iva' => 21],
        ['concepto' => 'Hosting anual',  'cantidad' => 1, 'precio' => 200,  'iva' => 21],
    ],
];

$res = pwr_verifactu_crear($factura, $claves['clave_privada']);
echo 'Hash: ' . $res['hash'];

Verificar cadena de 3 facturas

PHP
require_once 'core/verifactu.php';

$claves = pwr_rubrica_generar_claves();
$sk = $claves['clave_privada'];
$pk = $claves['clave_publica'];

// Crear cadena de 3 facturas encadenadas
$hash = '';
$cadena = [];
for ($i = 1; $i <= 3; $i++) {
    $f = ['numero' => "F-00{$i}", 'fecha' => '2026-03-2'.$i,
        'emisor' => ['nif' => 'B12345678', 'nombre' => 'Empresa'],
        'receptor' => ['nif' => 'A87654321', 'nombre' => 'Cliente'],
        'lineas' => [['concepto' => "Servicio {$i}", 'cantidad' => 1, 'precio' => 500, 'iva' => 21]]];
    $res = pwr_verifactu_crear($f, $sk, $hash);
    $cadena[] = $res['factura_firmada'];
    $hash = $res['hash'];
}

// Verificar cadena completa
$verif = pwr_verifactu_verificar_cadena($cadena, $pk);
echo $verif['cadena_integra'] ? 'Cadena integra' : 'Cadena rota';

Exportar a XML Verifactu

PHP
require_once 'core/verifactu.php';

// (tras crear una factura firmada)
$xml = pwr_verifactu_exportar_xml($res['factura_firmada']);
file_put_contents('factura_F-001.xml', $xml);

// Exportar tambien a JSON portable
$json = pwr_verifactu_exportar_json($res['factura_firmada']);
file_put_contents('factura_F-001.json', $json);

Registrar y listar facturas

PHP
require_once 'core/verifactu.php';

// Registrar factura en almacenamiento local
$reg = pwr_verifactu_registrar($res['factura_firmada']);
echo 'Registrada con ID: ' . $reg['id'];

// Listar todas las facturas
$todas = pwr_verifactu_listar();
echo 'Total registradas: ' . count($todas);

// Filtrar por fecha y emisor
$filtradas = pwr_verifactu_listar([
    'desde'      => '2026-01-01',
    'hasta'      => '2026-12-31',
    'emisor_nif' => 'B12345678',
]);

// Informacion del modulo
$info = pwr_verifactu_info();
echo 'Verifactu v' . $info['version'] . ' — ' . $info['facturas_registradas'] . ' facturas';