arnaullfe/verifactu
Composer 安装命令:
composer require arnaullfe/verifactu
包简介
Librería para la implementación del sistema VERI*FACTU para la facturación electrónica en España
README 文档
README
Una librería PHP simple y elegante para enviar facturas electrónicas al sistema VERI*FACTU de la AEAT. Sin complicaciones, sin dolor de cabeza. ✨
¿Qué es esto?
Esta librería te permite generar y enviar facturas electrónicas a la Agencia Tributaria española de forma sencilla. Solo necesitas crear tu factura con los datos básicos, y nosotros nos encargamos del resto: validación, envío SOAP, generación de QR, y todo lo que necesitas para cumplir con la normativa.
Instalación
composer require arnaullfe/verifactu
Requisitos:
- PHP >= 8.1
- Extensión SOAP (
ext-soap) - Un certificado digital (PFX/P12) para autenticarte con la AEAT
Empezar en 5 minutos
Aquí tienes un ejemplo completo de cómo crear y enviar una factura. Es así de simple:
<?php use arnaullfe\Verifactu\Models\CabeceraFactura; use arnaullfe\Verifactu\Models\CuerpoFactura; use arnaullfe\Verifactu\Models\Factura; use arnaullfe\Verifactu\Models\IdentificacionFiscal; use arnaullfe\Verifactu\Models\IdFactura; use arnaullfe\Verifactu\Models\LineaFactura; use arnaullfe\Verifactu\Models\SistemaInformatico; use arnaullfe\Verifactu\Models\TipoFactura; use arnaullfe\Verifactu\Services\VerifactuClient; use arnaullfe\Verifactu\Services\VerifactuQrGenerator; // 1. Define tu empresa (emisor) $EMISOR_NIF = "12345678A"; $EMISOR_NOMBRE = "Mi Empresa SL"; $emisor = new IdentificacionFiscal($EMISOR_NOMBRE, $EMISOR_NIF); // 2. Crea la estructura de la factura $cabeceraFactura = new CabeceraFactura($emisor); $cuerpoFactura = new CuerpoFactura(); // 3. Identifica tu factura (número único, fecha, etc.) $cuerpoFactura->idFactura = new IdFactura($EMISOR_NIF, "F-2025-2", new DateTime()); // 4. Completa los datos básicos $cuerpoFactura->nombreRazonEmisor = $EMISOR_NOMBRE; $cuerpoFactura->tipoFactura = TipoFactura::FACTURA; $cuerpoFactura->descripcionOperacion = "Venta de productos"; $cuerpoFactura->fechaOperacion = new DateTime(); $cuerpoFactura->destinatarios = [ new IdentificacionFiscal("Cliente SA", "87654321B") ]; // 5. Define los importes (en string con 2 decimales) $cuerpoFactura->cuotaTotal = "21.00"; // Total impuestos (IVA) $cuerpoFactura->importeTotal = "121.00"; // Total factura (100 base + 21 IVA) // 6. Información del sistema (tu software de facturación) $cuerpoFactura->sistemaInformatico = new SistemaInformatico( "77", // ID del sistema informático (2 dígitos). Si eres colaborador te asignan un número propio; en caso contrario, usa 77 para software propio o no registrado. "Mi Sistema de Facturación", // Nombre $EMISOR_NIF, // NIF del fabricante $EMISOR_NIF, // NIF del desarrollador "1.0", // Versión "1" // Número de instalación ); // 7. Desglose de impuestos (base, IVA, tipo) $cuerpoFactura->desglose = [ new LineaFactura("100.00", "21.00", "21.00") // Base: 100€, IVA: 21€, Tipo: 21% ]; // 8. Crea la factura completa $factura = new Factura($cabeceraFactura, $cuerpoFactura); // 9. Configura el cliente y envía $client = new VerifactuClient(); $client->setIsProduction(false); // true para producción $client->setCertificate("ruta/al/certificado.pfx", "contraseña"); $respuesta = $client->enviarFactura($factura); // 10. Verifica que todo salió bien if (empty($respuesta['success'])) { throw new Exception("Error al enviar la factura: " . $respuesta['message']); } // 11. Genera el código QR para mostrar en tu PDF $qrGenerator = new VerifactuQrGenerator(); $qrGenerator->setIsProduction(false); $qrUrl = $qrGenerator->generateQr($cuerpoFactura->idFactura, $cuerpoFactura->importeTotal); echo "¡Factura enviada! QR: " . $qrUrl;
¡Y listo! 🎉 Tu factura ya está registrada en la AEAT.
Casos Comunes
Factura Rectificativa
Si necesitas corregir una factura anterior, usa TipoFactura::R1 y añade el registro anterior:
// Solo si es una factura rectificativa $cuerpoFactura->tipoFactura = TipoFactura::R1; $cuerpoFactura->tipoRectificativa = TipoRectificativa::DIFERENCIAS; $cuerpoFactura->descripcionOperacion = "Rectificación de factura"; $cuerpoFactura->fechaOperacion = new DateTime(); $cuerpoFactura->cuotaTotal = "-21.00"; // Total impuestos (IVA) - negativo para rectificativas $cuerpoFactura->importeTotal = "-121.00"; // Total factura - negativo para rectificativas $cuerpoFactura->desglose = [ new LineaFactura("-100.00", "21.00", "21.00") ]; // Necesitas la huella de la factura original (la obtienes al guardar $factura->toArray()) $cuerpoFactura->registroAnterior = new RegistroAnterior( $EMISOR_NIF, "F-2025-1", // Número de la factura original new DateTime(), // Fecha de la factura original "HUELLA_DE_LA_FACTURA_ORIGINAL" // Hash SHA-256 de la factura original );
Factura Sin IVA
Para facturas exentas o no sujetas a IVA:
use arnaullfe\Verifactu\Models\TipoImpuesto; use arnaullfe\Verifactu\Models\TipoRegimen; use arnaullfe\Verifactu\Models\TipoOperacion; $cuerpoFactura->descripcionOperacion = "Venta de productos sin IVA por educación"; $cuerpoFactura->fechaOperacion = new DateTime(); $cuerpoFactura->cuotaTotal = "0.00"; // Total impuestos (sin IVA) $cuerpoFactura->importeTotal = "100.00"; // Total factura (sin IVA) $cuerpoFactura->desglose = [ new LineaFactura( "100.00", "00.00", // Sin cuota "00.00", // Sin tipo impositivo TipoImpuesto::IVA, TipoRegimen::C01, TipoOperacion::NonSubject // No sujeta ) ];
Cancelar Factura
Para anular una factura previamente enviada:
use arnaullfe\Verifactu\Models\CabeceraFactura; use arnaullfe\Verifactu\Models\CancelarFactura; use arnaullfe\Verifactu\Models\IdentificacionFiscal; use arnaullfe\Verifactu\Models\IdFactura; use arnaullfe\Verifactu\Models\SistemaInformatico; // 1. Crea la cabecera con el emisor $cabecera = new CabeceraFactura( new IdentificacionFiscal('Mi Empresa SL', '12345678A') ); // 2. Identifica la factura a cancelar (debe ser la misma que enviaste antes) $idFactura = new IdFactura( '12345678A', // NIF del emisor 'F-2025-2', // Número de serie de la factura original new DateTime('2025-03-15') // Fecha de expedición de la factura original ); // 3. Crea el registro de cancelación $cancelarFactura = new CancelarFactura( $cabecera, $idFactura, new DateTime('2025-03-15T14:32:18+00:00'), // Fecha y hora de la cancelación 'HUELLA_DE_LA_FACTURA_ORIGINAL' // Huella SHA-256 de la factura original ); // 4. Información del sistema informático $cancelarFactura->sistemaInformatico = new SistemaInformatico( '77', 'Mi Sistema de Facturación', '12345678A', '12345678A', '1.0', '1' ); // 5. Envía la cancelación $cliente = new VerifactuClient(); $cliente->setIsProduction(false); $cliente->setCertificate('ruta/al/certificado.pfx', 'contraseña', true); $res = $cliente->enviarFactura($cancelarFactura);
Importante: Necesitas la huella digital (SHA-256) de la factura original que guardaste cuando la enviaste. Esta huella se obtiene del método toArray() de la factura original.
Múltiples Líneas de Desglose
Si tienes diferentes tipos de IVA o regímenes:
$cuerpoFactura->desglose = [ new LineaFactura("500.00", "105.00", "21.00"), // 21% IVA new LineaFactura("300.00", "63.00", "21.00"), // 21% IVA new LineaFactura("200.00", "42.00", "21.00") // 21% IVA ]; // El cuotaTotal debe ser la suma de impuestos: 105 + 63 + 42 = 210.00 $cuerpoFactura->cuotaTotal = "210.00"; // Total impuestos (IVA) $cuerpoFactura->importeTotal = "1210.00"; // Total factura (1000 base + 210 IVA)
Configuración
Entorno de Pruebas vs Producción
Por defecto, la librería usa el entorno de pruebas. Cuando estés listo para producción:
$client->setIsProduction(true); $qrGenerator->setIsProduction(true);
Certificados Digitales
Puedes usar certificados PFX/P12 directamente (se convierten automáticamente):
$client->setCertificate("ruta/al/certificado.pfx", "contraseña");
O si ya tienes un certificado PEM:
$client->setCertificate("ruta/al/certificado.pem", "contraseña", false);
Guardar la Huella Digital
Es importante guardar la huella digital de cada factura para poder hacer rectificativas después:
$factura = new Factura($cabeceraFactura, $cuerpoFactura); $facturaArray = $factura->toArray(); // Guarda $facturaArray en tu base de datos // La huella está en: $facturaArray['CuerpoFactura']['Huella']
Cuando necesites hacer una rectificativa, usa esa huella en RegistroAnterior.
Respuestas del Servicio
El método enviarFactura() devuelve un array con esta estructura:
[
'success' => true, // true si todo salió bien
'message' => 'Mensaje descriptivo', // Mensaje de la AEAT
'data' => [...] // Respuesta completa del servicio SOAP
]
Estados posibles:
- ✅
CORRECTO: Factura enviada correctamente - ⚠️
ACEPTADO_CON_ERRORES: Aceptada pero con advertencias - ❌
ERROR: Error en el envío
Validación Automática
La librería valida automáticamente tu factura antes de enviarla. Verifica:
- ✅ Campos obligatorios
- ✅ Formato de NIF (9 caracteres)
- ✅ Cálculo correcto de IVA (con tolerancia de ±0.02€)
- ✅ Coherencia entre tipo de operación e impuestos
Si hay errores, los verás antes de enviar:
$errors = $factura->validate(); if (!empty($errors)) { foreach ($errors as $error) { echo "- $error\n"; } }
Tipos de Factura
TipoFactura::FACTURA // F1 - Factura ordinaria TipoFactura::SIMPLIFICADA // F2 - Factura simplificada TipoFactura::SUSTITUTIVA // F3 - Factura sustitutiva TipoFactura::R1 // R1 - Rectificativa (Art 80.1 y 80.2) TipoFactura::R2 // R2 - Rectificativa (Art. 80.3) TipoFactura::R3 // R3 - Rectificativa (Art. 80.4) TipoFactura::R4 // R4 - Rectificativa (Resto) TipoFactura::R5 // R5 - Rectificativa en simplificadas
Tipos de Impuesto
TipoImpuesto::IVA // 01 - Impuesto sobre el Valor Añadido TipoImpuesto::IPSI // 02 - Impuesto sobre Producción, Servicios e Importación TipoImpuesto::IGIC // 03 - Impuesto General Indirecto Canario TipoImpuesto::OTHER // 05 - Otros
Tipos de Operación
TipoOperacion::Subject // S1 - Operación sujeta TipoOperacion::PassiveSubject // S2 - Operación sujeta con inversión del sujeto pasivo TipoOperacion::NonSubject // N1 - Operación no sujeta TipoOperacion::ExemptByArticle20 // E1 - Operación exenta según artículo 20 // ... y más variantes
Regímenes Especiales
Los más comunes:
TipoRegimen::C01 // Régimen general TipoRegimen::C02 // Exportación TipoRegimen::C07 // Criterio de caja TipoRegimen::C20 // Régimen simplificado // ... y más (C01 a C20)
Ejemplos Completos
En la carpeta examples/ encontrarás ejemplos listos para usar:
factura.php- Factura ordinaria con IVAfacturaRectificativa.php- Factura rectificativafacturaSinIva.php- Factura sin IVA (exenta/no sujeta)cancelarFactura.php- Cancelación/anulación de factura
Manejo de Errores
try { $result = $client->enviarFactura($factura); if (!$result['success']) { // Algo salió mal $errorMessage = $result['message']; $errorData = $result['data']; // Log o maneja el error como necesites error_log("Error en factura: " . $errorMessage); } else { // ¡Todo perfecto! echo "Factura enviada: " . $result['message']; } } catch (\Exception $e) { // Error de conexión, certificado, etc. echo "Error: " . $e->getMessage(); }
Códigos QR
Los códigos QR permiten que tus clientes validen las facturas fácilmente:
$qrGenerator = new VerifactuQrGenerator(); $qrGenerator->setIsProduction(false); $qrUrl = $qrGenerator->generateQr($cuerpoFactura->idFactura, $cuerpoFactura->importeTotal); // Usa $qrUrl para generar el código QR en tu PDF // Ejemplo: <img src="https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=<?= $qrUrl ?>" />
Características
- ✅ Validación automática antes del envío
- ✅ Soporte para todos los tipos de factura (ordinarias, simplificadas, rectificativas)
- ✅ Gestión de múltiples impuestos (IVA, IPSI, IGIC)
- ✅ Regímenes especiales de IVA
- ✅ Generación de códigos QR
- ✅ Cálculo automático de huella digital (SHA-256)
- ✅ Entornos de prueba y producción
- ✅ Conversión automática de certificados PFX a PEM
¿Necesitas Ayuda?
- 📖 Revisa los ejemplos en
examples/ - 🐛 Abre un issue en GitHub si encuentras un bug
- 💡 Sugiere mejoras o nuevas funcionalidades
Licencia
MIT License - Siéntete libre de usar esta librería en tus proyectos.
Autor
Arnau Llopart - @arnaullfe
¿Listo para empezar? Copia el ejemplo de arriba, ajusta tus datos, y en 5 minutos tendrás tu primera factura enviada. 🚀
arnaullfe/verifactu 适用场景与选型建议
arnaullfe/verifactu 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 51 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 10 月 30 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「españa」 「facturacion」 「Electronica」 「verifactu」 「aeat」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 arnaullfe/verifactu 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 arnaullfe/verifactu 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 arnaullfe/verifactu 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Librería PHP para interactuar con el webservice de AFIP (Argentina -> factura electrónica).
Libreria en PHP para GeoAPI.es
Cliente para realizar la integración con los servicios web de LibreDTE desde PHP.
This package allow you to convert csd to required pem files
This Package allow to conect multiple Pac providers sistems
Greenter Core
统计信息
- 总下载量: 51
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 1
- 点击次数: 24
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-10-30