PHP FacturaE
Librería PHP moderna para generar, validar y firmar facturas electrónicas FacturaE. API fluent, firma XAdES-EPES, cero dependencias.
Introducción
PHP FacturaE es una librería moderna y tipada para generar, validar y firmar facturas electrónicas en formato FacturaE — el estándar oficial de facturación electrónica en España.
¿Qué es FacturaE?
FacturaE es el formato de factura electrónica basado en XML exigido por las Administraciones Públicas españolas (AAPP) y ampliamente adoptado en el sector privado. Está gestionado por la Agencia Tributaria (AEAT) y garantiza el cumplimiento fiscal y la interoperabilidad.
¿Por qué PHP FacturaE?
PHP FacturaE proporciona una API fluent y tipada que hace que crear facturas conformes sea intuitivo y libre de errores:
Invoice::create('FAC-001') ->series('A') ->date('2025-03-01') ->seller(Party::company('B12345678', 'Mi Empresa S.L.') ->address('C/ Mayor 10', '28013', 'Madrid', 'Madrid')) ->buyer(Party::person('12345678Z', 'Laura', 'Gómez', 'Ruiz') ->address('C/ Sol 3', '28012', 'Madrid', 'Madrid')) ->line('Diseño logotipo', price: 450.00, vat: 21) ->transferPayment(iban: 'ES91 2100 0418 4502 0005 1332', dueDate: '2025-03-31') ->export('factura.xml');Características principales
- API fluent con Enums — Sin arrays asociativos ni constantes sueltas — todo tipado con enums y propiedades readonly de PHP 8.2+
- Firma digital XAdES-EPES — Soporte nativo para certificados PKCS#12 (.pfx) y PEM con sellado de tiempo TSA opcional
- Validación XSD — Validación automática contra los esquemas oficiales FacturaE 3.2, 3.2.1 y 3.2.2
- Cero dependencias — Solo extensiones PHP estándar:
ext-openssl,ext-dom— sin paquetes externos
Soporte fiscal completo
- 29 tipos impositivos incluyendo IVA, IRPF, IGIC, recargo de equivalencia e impuestos especiales
- 19 métodos de pago desde transferencia hasta tarjeta y domiciliación
- 36 unidades de medida desde unidades hasta kWh y horas
- 22 motivos de corrección para facturas rectificativas
Rendimiento
- ~0.2 ms por factura simple
- ~22 ms para 100 facturas
- Generación XML eficiente con huella de memoria mínima
Casos de uso
- Plataformas SaaS que generan facturas para clientes españoles
- E-commerce que necesita formato FacturaE para ventas B2B
- Software de contabilidad con integración FACe/FACeB2B
- Autónomos y agencias que facturan a la Administración Pública
Arquitectura
La librería está organizada en namespaces enfocados:
Invoice— Punto de entrada principal con API fluentParty— Entidades vendedor/comprador (empresas e individuos)Entities/— Líneas, pagos, adjuntos, desglose fiscal, direccionesEnums/— Tipos impositivos, métodos de pago, tipos de factura, motivos de correcciónExporter/— Generación XMLSigner/— Firma digital XAdES-EPESValidation/— Validación contra esquemas
Cada clase usa propiedades readonly y tipos estrictos (PHP 8.2+) para máxima seguridad y soporte de autocompletado en el IDE.
Instalación
Requisitos
PHP FacturaE requiere PHP 8.2 o superior.
Extensiones PHP necesarias:
ext-openssl— Necesaria para firmas digitales XAdES-EPES y manejo de certificadosext-dom— Necesaria para generación y manipulación de XML
Instalación vía Composer
composer require php-facturae/php-facturaeVerificar la instalación
<?php
require_once 'vendor/autoload.php';
use PhpFacturae\Invoice;use PhpFacturae\Party;
$invoice = Invoice::create('TEST-001') ->seller(Party::company('B12345678', 'Empresa Test')) ->buyer(Party::company('B87654321', 'Empresa Cliente')) ->line('Producto de prueba', price: 100.00, vat: 21);
echo "✓ PHP FacturaE está correctamente instalado!\n";echo "Número de factura: " . $invoice->getNumber() . "\n";Autoloading
PHP FacturaE usa autoloading PSR-4:
PhpFacturae\Invoicemapea asrc/Invoice.phpPhpFacturae\Partymapea asrc/Party.phpPhpFacturae\Entities\Linemapea asrc/Entities/Line.php
Dependencias de desarrollo
composer install --devIncluye PHPUnit 11.0+ y PHPStan 2.0+ (nivel 8).
# Ejecutar testsvendor/bin/phpunit
# Ejecutar análisis estáticovendor/bin/phpstan analyse src --level=8Solución de problemas
«ext-openssl is missing» — Instala php8.2-openssl (Ubuntu/Debian) o actívalo en php.ini (Windows).
«ext-dom is missing» — Instala php8.2-xml (Ubuntu/Debian).
«Class ‘PhpFacturae\Invoice’ not found» — Asegúrate de incluir vendor/autoload.php. Ejecuta composer dump-autoload si es necesario.
Opcional: Sellado de tiempo TSA
Para soporte de autoridad de sellado de tiempo (TSA), necesitarás ext-curl:
sudo apt-get install php8.2-curlInicio rápido
Tu primera factura
<?php
require_once 'vendor/autoload.php';
use PhpFacturae\Invoice;use PhpFacturae\Party;
$invoice = Invoice::create('FAC-001') ->series('A') ->date('2025-03-01') ->seller( Party::company('B12345678', 'Mi Empresa S.L.') ->address('C/ Mayor 10', '28013', 'Madrid', 'Madrid') ->email('info@miempresa.es') ) ->buyer( Party::person('12345678Z', 'Laura', 'Gómez', 'Ruiz') ->address('C/ Sol 3', '28012', 'Madrid', 'Madrid') ->email('laura@example.com') ) ->line('Diseño de logotipo', price: 450.00, vat: 21) ->transferPayment( iban: 'ES91 2100 0418 4502 0005 1332', dueDate: '2025-03-31' ) ->export('factura.xml');
echo "✓ Factura generada: factura.xml\n";Escenarios fiscales avanzados
IVA + retención de IRPF:
$invoice->line( description: 'Consultoría informática', price: 500.00, vat: 21, irpf: 15);Canarias (IGIC):
$invoice->line('Producto enviado a Canarias', price: 100, igic: 7);Recargo de equivalencia:
$invoice->line('Producto minorista', price: 100, vat: 21, surcharge: 5.2);Línea exenta:
$invoice->exemptLine('Curso de formación', price: 2000, reason: 'Exenta según Art. 20 LIVA');Múltiples impuestos por línea
use PhpFacturae\Entities\TaxBreakdown;use PhpFacturae\Enums\Tax;
$invoice->customLine( description: 'Producto con múltiples impuestos', price: 300.00, taxes: [ new TaxBreakdown(Tax::IGIC, 7), new TaxBreakdown(Tax::REIGIC, 0.5), ]);Pagos fraccionados
use PhpFacturae\Enums\PaymentMethod;
$invoice->splitPayments( method: PaymentMethod::Transfer, installments: 3, firstDueDate: '2025-04-01', intervalDays: 30, iban: 'ES91 2100 0418 4502 0005 1332');Validación
use PhpFacturae\Exceptions\InvoiceValidationException;
try { $invoice->export('factura.xml');} catch (InvoiceValidationException $e) { echo "Errores de validación:\n"; foreach ($e->getErrors() as $error) { echo " - $error\n"; }}Factura
La clase Invoice es el corazón de PHP FacturaE. Proporciona una API fluent para construir documentos XML FacturaE conformes con validación automática, cálculo de impuestos y firma digital.
Crear una factura
use PhpFacturae\Invoice;
$invoice = Invoice::create('2024-001') ->date('2024-03-09') ->seller($seller) ->buyer($buyer) ->line('Servicio', price: 100, vat: 21) ->transferPayment('ES12 3456 7890 1234 5678 9012');Configuración básica
Series y fechas:
$invoice->series('A') ->date('2024-03-09') ->operationDate('2024-03-01') ->billingPeriod(from: '2024-03-01', to: '2024-03-31');Esquema y tipo:
use PhpFacturae\Enums\Schema;use PhpFacturae\Enums\InvoiceType;
$invoice->schema(Schema::V3_2_2) ->type(InvoiceType::Full);Versiones de esquema: V3_2, V3_2_1, V3_2_2 (por defecto).
Tipos de factura: Full (FC), Simplified (FA), SimplifiedRectified (AF).
Moneda y descripción:
$invoice->currency('EUR') ->description('Servicios de consultoría mensual');Descuentos y cargos generales
$invoice->generalDiscount('Descuento cliente VIP', rate: 10);$invoice->generalDiscount('Pronto pago', amount: 50.00);$invoice->generalCharge('Gastos de envío', amount: 15.00);Facturas rectificativas
use PhpFacturae\Enums\CorrectionReason;use PhpFacturae\Enums\CorrectionMethod;
$invoice->corrects( invoiceNumber: '2024-001', reason: CorrectionReason::TransactionDetail, method: CorrectionMethod::FullReplacement, series: 'A');Adjuntos
$invoice->attachFile('/ruta/al/contrato.pdf', 'Contrato firmado');Exportar a XML
$xml = $invoice->toXml();$invoice->export('/ruta/a/factura.xml');Firma digital
use PhpFacturae\Signer;
$invoice->sign(Signer::pfx('certificado.pfx', 'password')) ->export('factura-firmada.xml');Referencia de métodos
| Método | Parámetros | Descripción |
|---|---|---|
create() | string $number | Constructor estático |
series() | string $series | Establecer serie |
date() | string|DateTimeImmutable $date | Fecha de emisión |
operationDate() | string|DateTimeImmutable $date | Fecha de operación |
billingPeriod() | $from, $to | Periodo de facturación |
schema() | Schema $schema | Versión FacturaE |
type() | InvoiceType $type | Tipo de factura |
currency() | string $currency | Moneda (ISO 4217) |
description() | string $description | Descripción |
seller() | Party $seller | Vendedor |
buyer() | Party $buyer | Comprador |
line() | Ver Líneas e impuestos | Añadir línea |
exemptLine() | Ver Líneas e impuestos | Línea exenta |
customLine() | Ver Líneas e impuestos | Línea con impuestos custom |
transferPayment() | string $iban, ?string $dueDate, ?float $amount | Pago por transferencia |
cashPayment() | ?string $dueDate, ?float $amount | Pago en efectivo |
cardPayment() | ?string $dueDate, ?float $amount | Pago con tarjeta |
directDebitPayment() | string $iban, ?string $dueDate, ?float $amount | Domiciliación |
splitPayments() | Ver Pagos | Pagos fraccionados |
sign() | InvoiceSigner $signer | Firmar factura |
toXml() | — | Generar XML |
export() | string $path | Exportar a archivo |
Partes
Toda factura FacturaE requiere dos partes: un vendedor (emisor) y un comprador (receptor).
Empresas
use PhpFacturae\Party;
$empresa = Party::company( taxNumber: 'B12345678', name: 'Acme Corporation S.L.');Personas físicas
$persona = Party::person( taxNumber: '12345678Z', name: 'Juan', firstSurname: 'García', lastSurname: 'López');Dirección
$party->address( street: 'Gran Vía 1, 3ª Planta', postalCode: '28013', town: 'Madrid', province: 'Madrid', countryCode: 'ESP');El código de país usa ISO 3166-1 alpha-3 (ESP, FRA, DEU, etc.).
Datos de contacto
$party->email('info@ejemplo.com') ->phone('+34 91 123 4567') ->fax('+34 91 123 4568') ->website('https://ejemplo.com') ->contactPeople('Juan García, Departamento de Contabilidad');Nombre comercial
$party->tradeName('Acme Tech');Centros administrativos (FACe)
$comprador = Party::company('Q2819002D', 'Ministerio de Hacienda') ->centre(role: '01', code: 'L01281901', name: 'Oficina Contable') ->centre(role: '02', code: 'L01281902', name: 'Unidad Tramitadora') ->centre(role: '03', code: 'L01281903', name: 'Oficina Gestora');Registro Mercantil
$party->merchantRegister( register: 'Madrid', book: '1234', folio: '56', sheet: 'M-123456', section: '8', volume: '789');Códigos de actividad económica
$party->cnoCnae('6201');$party->ineTownCode('28079');Partes internacionales
$compradorExtranjero = Party::company('FR12345678901', 'Société Française SARL') ->address( street: '10 Avenue des Champs-Élysées', postalCode: '75008', town: 'Paris', province: 'Île-de-France', countryCode: 'FRA' );Líneas e impuestos
Líneas básicas
$invoice->line( description: 'Ordenador portátil', quantity: 2, price: 899.99, vat: 21);Firma del método
public function line( string $description, float $price, float $quantity = 1, ?float $vat = null, ?float $irpf = null, ?float $igic = null, ?float $surcharge = null, ?float $ie = null, bool $ieWithheld = false, ?float $discount = null, ?string $articleCode = null, ?string $detailedDescription = null, ?UnitOfMeasure $unit = null,): selfAtajos fiscales
IVA:
$invoice->line('Licencia software', price: 100, vat: 21); // General 21%$invoice->line('Libro', price: 20, vat: 10); // Reducido 10%$invoice->line('Alimento esencial', price: 15, vat: 4); // Superreducido 4%IRPF (retención):
$invoice->line('Asesoría legal', price: 2000, vat: 21, irpf: 15);IGIC (Canarias):
$invoice->line('Producto', price: 100, igic: 7);No combines IVA e IGIC en la misma línea.
Recargo de equivalencia:
$invoice->line('Producto minorista', price: 100, vat: 21, surcharge: 5.2);Tipos de recargo: IVA 21% → 5.2%, IVA 10% → 1.4%, IVA 4% → 0.5%.
Impuestos especiales (IE):
$invoice->line('Alcohol', price: 50, vat: 21, ie: 10);Descuentos por línea
$invoice->line('Producto', quantity: 10, price: 100, discount: 20, vat: 21);// Subtotal: 1000, Descuento -20% = 800, IVA +168, Total: 968Códigos de artículo y unidades
use PhpFacturae\Enums\UnitOfMeasure;
$invoice->line('Electricidad', quantity: 150.5, price: 0.15, unit: UnitOfMeasure::KWh, vat: 21, articleCode: 'ELEC-001');Líneas exentas
$invoice->exemptLine( description: 'Curso de formación profesional', price: 2000, reason: 'Exenta según Artículo 20 LIVA');Configuración fiscal personalizada
use PhpFacturae\Entities\TaxBreakdown;use PhpFacturae\Enums\Tax;
$invoice->customLine( description: 'Servicio complejo', price: 1000, taxes: [ new TaxBreakdown(Tax::IVA, rate: 21), new TaxBreakdown(Tax::IRPF, rate: 15), ]);Enum Tax (29 tipos)
Tax::IVA // Impuesto sobre el Valor AñadidoTax::IPSI // Impuesto sobre la Producción (Ceuta y Melilla)Tax::IGIC // Impuesto General Indirecto CanarioTax::IRPF // Retención del IRPFTax::IRNR // Impuesto sobre la Renta de No ResidentesTax::IE // Impuesto EspecialTax::RA // Recargo de equivalencia agrarioTax::ITPAJD // Impuesto de Transmisiones PatrimonialesTax::REIVA // Recargo de equivalencia (IVA)Tax::REIGIC // Recargo de equivalencia (IGIC)Tax::REIPSI // Recargo de equivalencia (IPSI)// ... y 18 más especializadosPagos
Métodos de pago
Transferencia bancaria:
$invoice->transferPayment( iban: 'ES12 3456 7890 1234 5678 9012', dueDate: '2024-04-09');Pago en efectivo:
$invoice->cashPayment();Pago con tarjeta:
$invoice->cardPayment(dueDate: '2024-03-09');Domiciliación bancaria:
$invoice->directDebitPayment( iban: 'ES98 7654 3210 9876 5432 1098', dueDate: '2024-04-09');Pagos fraccionados
use PhpFacturae\Enums\PaymentMethod;
$invoice->splitPayments( method: PaymentMethod::Transfer, installments: 3, firstDueDate: '2024-04-09', intervalDays: 30, iban: 'ES12 3456 7890 1234 5678 9012');Importes personalizados por plazo
use PhpFacturae\Entities\Payment;
$invoice->payment(new Payment( method: PaymentMethod::Transfer, dueDate: new DateTimeImmutable('2024-04-09'), amount: 1000.00, iban: 'ES12 3456 7890 1234 5678 9012'));Enum PaymentMethod (19 métodos)
PaymentMethod::Cash // 01 — EfectivoPaymentMethod::DirectDebit // 02 — DomiciliaciónPaymentMethod::Receipt // 03 — ReciboPaymentMethod::Transfer // 04 — TransferenciaPaymentMethod::AcceptedBillOfExchange // 05 — Letra de cambio aceptadaPaymentMethod::DocumentaryCredit // 06 — Crédito documentarioPaymentMethod::ContractAward // 07 — Adjudicación de contratoPaymentMethod::BillOfExchange // 08 — Letra de cambioPaymentMethod::TransferablePromissory // 09 — Pagaré transferiblePaymentMethod::PromissoryNote // 10 — Pagaré no a la ordenPaymentMethod::Cheque // 11 — ChequePaymentMethod::Reimbursement // 12 — ReposiciónPaymentMethod::Special // 13 — EspecialPaymentMethod::Setoff // 14 — CompensaciónPaymentMethod::Postgiro // 15 — Giro postalPaymentMethod::CertifiedCheque // 16 — Cheque conformadoPaymentMethod::BankersDraft // 17 — Cheque bancarioPaymentMethod::CashOnDelivery // 18 — Contra reembolsoPaymentMethod::Card // 19 — TarjetaFormato IBAN
Los IBAN se normalizan automáticamente — los espacios y guiones se eliminan internamente.
Firma digital
PHP FacturaE soporta firma digital con XAdES-EPES conforme a la política de firma FacturaE v3.1.
Certificados PKCS#12 (.pfx / .p12)
use PhpFacturae\Signer;
$signer = Signer::pfx('certificado.pfx', 'miPasswordSeguro');$invoice->sign($signer);Certificados PEM
$signer = Signer::pem( certPath: 'certificado.pem', keyPath: 'clave-privada.pem', passphrase: 'passwordClave');Sellado de tiempo (TSA)
$signer = Signer::pfx('certificado.pfx', 'password') ->timestamp('https://freetsa.org/tsr');Con autenticación:
->timestamp( url: 'https://tsa.ejemplo.com/tsr', user: 'miUsuario', password: 'miPassword')Detalles criptográficos
- Canonicalización: C14N (Canonical XML 1.0)
- Algoritmo de resumen: SHA-256
- Algoritmo de firma: RSA-SHA256
- Transformación: Firma envolvente (enveloped signature)
Conversión de certificados
# PEM a PKCS#12openssl pkcs12 -export -in certificado.pem -inkey clave-privada.pem -out certificado.pfx
# PKCS#12 a PEMopenssl pkcs12 -in certificado.pfx -out certificado.pem -nodes
# Eliminar passphrase de clave PEMopenssl rsa -in clave-cifrada.pem -out clave-descifrada.pemVerificar firmas
xmlsec1 --verify factura-firmada.xmlFacturas rectificativas
Rectificativa básica
use PhpFacturae\Enums\CorrectionReason;use PhpFacturae\Enums\CorrectionMethod;
$invoice = Invoice::create('FAC-002') ->date('2024-02-15') ->seller($seller) ->buyer($buyer) ->line('Servicio corregido', price: 1000.00, vat: 21) ->corrects( invoiceNumber: 'FAC-001', reason: CorrectionReason::TaxableBase, method: CorrectionMethod::FullReplacement ) ->toXml();Motivos de corrección (22 tipos)
Administrativos (01-09): Número de factura, serie, fecha de emisión, nombre del emisor, nombre del receptor, NIF del emisor, NIF del receptor, dirección del emisor, dirección del receptor.
De transacción (10-16): Detalle de la operación, tipo impositivo, cuota impositiva, periodo fiscal, clase de factura, literales legales, base imponible.
De cálculo fiscal (80-85): Cálculo de cuotas repercutidas, cálculo de cuotas retenidas, base modificada por devoluciones, base modificada por descuentos, base modificada por resolución judicial, base modificada por insolvencia.
Métodos de corrección
FullReplacement(01) — Sustitución completa (el más habitual)Differences(02) — Solo las diferenciasVolumeDiscount(03) — Descuento por volumenTaxAuthorityAuthorized(04) — Autorizado por la AEAT
Correcciones con periodo fiscal
$invoice->corrects( invoiceNumber: 'FAC-2024-001', reason: CorrectionReason::TaxPeriod, method: CorrectionMethod::FullReplacement, periodStart: '2024-01-01', periodEnd: '2024-03-31');Descuentos y cargos
Descuentos generales
$invoice->generalDiscount('Descuento cliente VIP', amount: 50.00);$invoice->generalDiscount('Descuento por volumen', rate: 10);Cargos generales
$invoice->generalCharge('Gastos de envío', amount: 15.00);$invoice->generalCharge('Recargo por urgencia', rate: 5);Los descuentos y cargos generales se aplican al total bruto antes de impuestos.
Descuentos a nivel de línea
->line('Producto', price: 100.00, vat: 21, discount: 10)Adjuntos
Uso rápido
$invoice->attachFile('/ruta/al/contrato.pdf', 'Contrato de servicio firmado');Usando la entidad Attachment
use PhpFacturae\Entities\Attachment;
// Desde archivo$adjunto = Attachment::fromFile('/ruta/al/doc.pdf', 'Contrato');
// Desde datos en bruto$adjunto = Attachment::fromData($pdfData, 'application/pdf', 'Informe');
$invoice->attach($adjunto);Múltiples adjuntos
$invoice ->attachFile('/ruta/al/contrato.pdf', 'Contrato') ->attachFile('/ruta/al/albaran.pdf', 'Albarán de entrega');Mantén los adjuntos por debajo de 5 MB cuando sea posible.
Validación
La validación ocurre automáticamente al llamar a toXml() o export().
Reglas de validación
- Vendedor obligatorio (con dirección)
- Comprador obligatorio (con dirección)
- Al menos una línea de factura
- Número de factura obligatorio
- El periodo de facturación requiere fecha de inicio y fin
- La fecha de inicio del periodo debe ser anterior a la de fin
Manejo de errores de validación
use PhpFacturae\Exceptions\InvoiceValidationException;
try { $xml = $invoice->toXml();} catch (InvoiceValidationException $e) { foreach ($e->errors as $error) { echo "- $error\n"; }}Validación de esquema XSD
use PhpFacturae\Enums\Schema;
$invoice->schema(Schema::V3_2_2); // Por defectoDisponibles: V3_2, V3_2_1, V3_2_2.
Integración FACe
FACe (Punto General de Entrada de Facturas Electrónicas) es la plataforma centralizada de facturación electrónica para la Administración Pública española.
Centros administrativos (DIR3)
$entidadPublica = Party::company('Q2826004D', 'Ayuntamiento de Las Rozas') ->address('Plaza Mayor 1', '28230', 'Las Rozas', 'Madrid') ->centre(role: '01', code: 'L01282249', name: 'Oficina Contable') ->centre(role: '02', code: 'L01282249', name: 'Ayuntamiento') ->centre(role: '03', code: 'L01282249', name: 'Unidad Contratación');Códigos de rol
| Código | Rol | Nombre |
|---|---|---|
01 | Oficina contable | Oficina contable |
02 | Órgano gestor | Órgano gestor |
03 | Unidad tramitadora | Unidad tramitadora |
04 | Órgano proponente | Órgano proponente |
Cómo encontrar códigos DIR3
- Solicitar directamente a la entidad
- Buscar en dir3.redsara.es
- Revisar órdenes de compra
- Documentación de FACe
Checklist FACe
- ✅ Códigos DIR3 válidos para centros (01, 02, 03)
- ✅ NIF correcto de la entidad pública (P/S/Q + 7 dígitos + letra)
- ✅ Dirección completa de ambas partes
- ✅ IBAN válido para el pago
- ✅ Fecha de vencimiento (normalmente 30-60-90 días)
- ✅ Literal legal mencionando Ley 25/2013
Ejemplo: Factura básica
use PhpFacturae\Invoice;use PhpFacturae\Party;
$invoice = Invoice::create('FAC-001') ->series('A') ->date('2024-01-15') ->seller( Party::company('A00000000', 'Empresa Test S.L.') ->address('C/ Test, 1', '28001', 'Madrid', 'Madrid') ->email('admin@empresa.es') ) ->buyer( Party::person('00000000A', 'Juan', 'García', 'López') ->address('C/ Comprador, 5', '08001', 'Barcelona', 'Barcelona') ) ->line('Servicio de consultoría', price: 1000.00, vat: 21) ->transferPayment( iban: 'ES91 2100 0418 4502 0005 1332', dueDate: '2024-02-15' ) ->export('factura-001.xsig');Ejemplo: Canarias (IGIC)
use PhpFacturae\Invoice;use PhpFacturae\Party;
$invoice = Invoice::create('FAC-2024-0001') ->series('A') ->date('2024-12-15') ->seller( Party::company('B76123456', 'Atlantic Systems S.L.') ->tradeName('Atsys') ->address('C/ Triana, 52', '35002', 'Las Palmas de Gran Canaria', 'Las Palmas') ->email('info@atsys.es') ) ->buyer( Party::company('A28000001', 'Cliente Demo S.L.') ->address('C/ Gran Vía, 1', '28013', 'Madrid', 'Madrid') ) ->line('Desarrollo web', price: 1200.00, igic: 7) ->line('Mantenimiento WordPress (3 meses)', price: 150.00, quantity: 3, igic: 7) ->line('Certificado SSL', price: 45.50, igic: 7) ->transferPayment( iban: 'ES91 2100 0418 4502 0005 1332', dueDate: '2025-01-15' ) ->legalLiteral('Factura exenta de IVA por aplicación del REF Canario. IGIC al tipo general.') ->export('factura-canaria.xsig');Tipos IGIC: 0% (superreducido), 3% (reducido), 7% (general), 15% (incrementado).
Ejemplo: Administración Pública (FACe)
use PhpFacturae\Invoice;use PhpFacturae\Party;
$invoice = Invoice::create('FAC-FACE-001') ->series('F') ->date('2024-12-15') ->seller( Party::company('B12345678', 'Consultoría IT S.L.') ->address('C/ Serrano, 25', '28001', 'Madrid', 'Madrid') ) ->buyer( Party::company('S2800001A', 'Ministerio de Educación') ->address('C/ Alcalá, 36', '28014', 'Madrid', 'Madrid') ->centre('01', 'EA0001234') ->centre('02', 'EA0001234') ->centre('03', 'EA0001234') ) ->line('Consultoría sistema educativo', price: 15000.00, vat: 21) ->line('Licencias software (50 usuarios)', price: 5000.00, vat: 21) ->transferPayment( iban: 'ES91 2100 0418 4502 0005 1332', dueDate: '2025-02-15' ) ->legalLiteral('Factura destinada a Administración Pública. Ley 25/2013.') ->export('factura-face.xsig');Ejemplo: Pagos fraccionados
use PhpFacturae\Invoice;use PhpFacturae\Party;use PhpFacturae\Enums\PaymentMethod;
$invoice = Invoice::create('FAC-008') ->series('F') ->date('2024-10-01') ->seller( Party::company('B76123456', 'Atlantic Systems S.L.') ->address('C/ Triana, 52', '35002', 'Las Palmas de Gran Canaria', 'Las Palmas') ) ->buyer( Party::company('A28000001', 'Cliente Demo S.L.') ->address('C/ Gran Vía, 1', '28013', 'Madrid', 'Madrid') ) ->line('Desarrollo aplicación móvil', price: 6000.00, igic: 7) ->splitPayments( method: PaymentMethod::Transfer, installments: 3, firstDueDate: '2024-11-01', intervalDays: 30, iban: 'ES91 2100 0418 4502 0005 1332' ) ->export('factura-pagos-fraccionados.xsig');Total: 6.000 € + 7% IGIC = 6.420 € en 3 plazos de 2.140 € cada uno.
Para calendarios personalizados, usa objetos Payment manuales:
use PhpFacturae\Entities\Payment;
$invoice ->payment(new Payment( method: PaymentMethod::Transfer, dueDate: new \DateTimeImmutable('2024-12-30'), amount: 12100.00, iban: 'ES91 2100 0418 4502 0005 1332' )) ->payment(new Payment( method: PaymentMethod::Transfer, dueDate: new \DateTimeImmutable('2025-01-30'), amount: 12100.00, iban: 'ES91 2100 0418 4502 0005 1332' ));