PHP Classes
elePHPant
Icontem

Facturae PHP: Generate XML electronic bills paid in Spain

Recommend this page to a friend!
  Info   View files Example   View files View files (14)   DownloadInstall with Composer Download .zip   Reputation   Support forum (1)   Blog    
Last Updated Ratings Unique User Downloads Download Rankings
2017-10-04 (1 month ago) RSS 2.0 feedNot enough user ratingsTotal: 84 This week: 2All time: 8,888 This week: 346Up
Version License PHP version Categories
facturae-php 1.0.4Custom (specified...5XML, PHP 5, E-Commerce
Description Author
This package is specific mainly for applications used in Spain Spain .

This package can generate XML electronic bills paid in Spain.

It takes details about products or services paid in Spain and generates XML signed using a digital certificate for the electronic bill.

In Spanish:

Genera y firma facturas electrónicas en formato XML sin necesidad de ninguna librería adicional

Innovation Award
PHP Programming Innovation award nominee
September 2017
Number 6
This package can generate XML electronic bills paid in Spain.

It takes details about products or services paid in Spain and generates XML signed using a digital certificate for the electronic bill.

In Spanish:

Genera y firma facturas electrónicas en formato XML sin necesidad de ninguna librería adicional

Manuel Lemos
  Performance   Level  
Name: José Miguel Moreno <contact>
Classes: 1 package by
Country: Spain Spain
Age: ???
All time rank: 4107110 in Spain Spain
Week rank: 333 Up14 in Spain Spain Up
Innovation award
Innovation award
Nominee: 1x

Details

Facturae-PHP Build Status

Qué es

Facturae-PHP es una clase escrita puramente en PHP que permite generar facturas siguiendo el formato estructurado de factura electrónica Facturae e incluso firmarlas con firma electrónica XAdES sin necesidad de ninguna librería o clase adicional.

Requisitos

- PHP 5.6 o superior - OpenSSL (solo para firmar facturas)

Características

Funciones previstas

  • [ ] Compatibilidad con el formato Facturae 3.2.2
  • [ ] Envío de facturas a FACe directamente desde la clase

Uso del paquete

Facturae-PHP pretende ser una clase extremadamente rápida y sencilla de usar. A continuación se incluyen varios ejemplos sobre su utilización. Para más información sobre todos los métodos de Facturae-PHP, la clase se encuentra comentada según bloques de código de phpDocumentor.

Instalación

composer require josemmo/facturae-php

Ejemplo básico usando Composer

// Sistema de carga automática de Composer
require_once __DIR__ . '/../vendor/autoload.php';

// Importamos las clases usadas
use josemmo\Facturae\Facturae;
use josemmo\Facturae\FacturaeParty;
use josemmo\Facturae\FacturaeCentre; // Esta es opcional
use josemmo\Facturae\FacturaeItem;   // Este es opcional

// Creamos la factura
$fac = new Facturae();

// Asignamos el número EMP2017120003 a la factura
// Nótese que Facturae debe recibir el lote y el
// número separados
$fac->setNumber('EMP201712', '0003');

// Asignamos el 01/12/2017 como fecha de la factura
$fac->setIssueNumber('2017-12-01');

// Incluimos los datos del vendedor
$fac->setSeller(new FacturaeParty([
    "taxNumber" => "A00000000",
    "name"      => "Perico el de los Palotes S.A.",
    "address"   => "C/ Falsa, 123",
    "postCode"  => "123456",
    "town"      => "Madrid",
    "province"  => "Madrid"
]);

// Incluimos los datos del comprador
// Con finos demostrativos el comprador será
// una persona física en vez de una empresa
$fac->setBuyer(new FacturaeParty([
    "isLegalEntity" => false,       // Importante!
    "taxNumber"     => "00000000A",
    "name"          => "Antonio",
    "firstSurname"  => "García",
    "lastSurname"   => "Pérez",
    "address"       => "Avda. Mayor, 7",
    "postCode"      => "654321",
    "town"          => "Madrid",
    "province"      => "Madrid"
]);

// Añadimos los productos a incluir en la factura
// En este caso, probaremos con tres lámpara por
// precio unitario de 20,14? con 21% de IVA ya incluído
$fac->addItem("Lámpara de pie", 20.14, 3, Facturae::TAX_IVA, 21);

// Ya solo queda firmar la factura ...
$fac->sign(
    "ruta/hacia/clave_publica.pem",
    "ruta/hacia/clave_privada.pem",
    "passphrase"
);

// ... y exportarlo a un archivo
$fac->export("ruta/de/salida.xsig");

> ##### NOTA > En caso de no utilizar Composer, se deberá sustituir en el ejemplo anterior la línea de código: > `php > require_once __DIR__ . '/../vendor/autoload.php'; > ` > Por las siguientes: > `php > require_once "../src/Facturae.php"; > require_once "../src/FacturaeParty.php"; > require_once "../src/FacturaeCentre.php"; > require_once "../src/FacturaeItem.php"; > `

Compradores y vendedores

Los compradores y vendedores son representados en Facturae-PHP con la clase FacturaeParty y pueden contener los siguientes atributos:

$empresa = new FacturaeParty([
    "isLegalEntity" => true, // Se asume true si se omite
    "taxNumber"     => "A00000000",
    "name"          => "Perico el de los Palotes S.A.",
    "address"       => "C/ Falsa, 123",
    "postCode"      => "123456",
    "town"          => "Madrid",
    "province"      => "Madrid",
    "countryCode"   => "ESP",  // Se asume España si se omite
    "book"             => "0",  // Libro
    "merchantRegister" => "RG", // Registro Mercantil
    "sheet"            => "1",  // Hoja
    "folio"            => "2",  // Folio
    "section"          => "3",  // Sección
    "volume"           => "4",  // Tomo
    "email"   => "contacto@perico.com"
    "phone"   => "910555444",
    "fax"     => "910555443"
    "website" => "http://www.perico.com/",
    "contactPeople" => "Perico",
    "cnoCnae" => "4791", // Clasif. Nacional de Act. Económicas
    "ineTownCode" => "280796" // Cód. de municipio del INE
]);

$personaFisica = new FacturaeParty([
    "isLegalEntity" => false,
    "taxNumber"     => "00000000A",
    "name"          => "Antonio",
    "firstSurname"  => "García",
    "lastSurname"   => "Pérez",
    "address"       => "Avda. Mayor, 7",
    "postCode"      => "654321",
    "town"          => "Madrid",
    "province"      => "Madrid",
    "countryCode"   => "ESP",  // Se asume España si se omite
    "email"   => "antonio@email.com"
    "phone"   => "910777888",
    "fax"     => "910777888"
    "website" => "http://www.antoniogarcia.es/",
    "contactPeople" => "Antonio García",
    "cnoCnae" => "4791", // Clasif. Nacional de Act. Económicas
    "ineTownCode" => "280796" // Cód. de municipio del INE
]);

Centros administrativos

Para poder emitir facturas a organismos públicos a través de FACe es necesario indicar los centros administrativos relacionados con la administración a facturar. Estos datos pueden obtenerse a través del directorio de organismos de FACe y deben ser indicados a Facturae-PHP de la siguiente forma:

// Tomamos como ejemplo el Ayuntamiento de San Sebastián de los Reyes
$ayto = new FacturaeParty([
    "taxNumber" => "P2813400E",
    "name"      => "Ayuntamiento de San Sebastián de los Reyes",
    "address"   => "Plaza de la Constitución, 1",
    "postCode"  => "28701",
    "town"      => "San Sebastián de los Reyes",
    "province"  => "Madrid",
    "centres"   => [
        new FacturaeCentre([
            "role"     => FacturaeCentre::ROLE_GESTOR,
            "code"     => "L01281343",
            "name"     => "Intervención Municipal",
            "address"  => "Plaza de la Constitución, 1",
            "postCode" => "28701",
            "town"     => "San Sebastián de los Reyes",
            "province" => "Madrid"
        ]),
        new FacturaeCentre([
            "role"     => FacturaeCentre::ROLE_TRAMITADOR,
            "code"     => "L01281343",
            "name"     => "Intervención Municipal",
            "address"  => "Plaza de la Constitución, 1",
            "postCode" => "28701",
            "town"     => "San Sebastián de los Reyes",
            "province" => "Madrid"
        ]),
        new FacturaeCentre([
            "role"     => FacturaeCentre::ROLE_CONTABLE,
            "code"     => "L01281343",
            "name"     => "Intervención Municipal",
            "address"  => "Plaza de la Constitución, 1",
            "postCode" => "28701",
            "town"     => "San Sebastián de los Reyes",
            "province" => "Madrid"
        ])
    ]
]);

Uso avanzado de líneas de producto

Es posible añadir una descripción además del concepto al añadir un producto al pasar un array de dos elementos en el primer parámetro del método:

// Solo concepto, sin descripción
$fac->addItem("Lámpara de pie", 20.14, 3, Facturae::TAX_IVA, 21);

// Con descripción incluída
$fac->addItem(["Lámpara de pie", "Lámpara de madera de nogal con base rectangular y luz halógena"], 20.14, 3, Facturae::TAX_IVA, 21);

También se puede añadir un elemento sin impuestos, aunque solo debe hacerse en aquellos casos en los que se tenga total certeza:

$fac->addItem("No llevo impuestos", 100, 1);

La forma adecuada de añadir elementos a los que no se les aplica IVA es la siguiente:

$fac->addItem("Llevo IVA al 0%", 100, 1, Facturae::TAX_IVA, 0);

Nótese que Facturae-PHP no limita este tipo de comportamientos, es responsabilidad del usuario crear la factura de acuerdo a la legislación aplicable.

Uso aún más avanzado de líneas de producto

Supongamos que se quieren añadir varios impuestos a una misma línea de producto. En este caso se deberá hacer uso de la API avanzada de productos de Facturae-PHP a través de la clase FacturaeItem:

// Vamos a añadir un producto utilizando la API avanzada
// que tenga IVA al 10% e IRPF al 15%
$fac->addItem(new FacturaeItem([
    "name" => "Una línea con varios impuestos",
    "description" => "Esta línea es solo para probar Facturae-PHP",
    "quantity" => 1, // Esto es opcional, es el valor por defecto si se omite
    "unitPrice" => 43.64,
    "taxes" => [
        Facturae::TAX_IVA  => 10,
        Facturae::TAX_IRPF => 15
    ]
]));

Esta API también permite indicar el importe unitario del producto sin incluir impuestos (base imponible), ya que por defecto Facturae-PHP asume lo contrario:

// Vamos a añadir 3 bombillas LED con un coste de 6,50 ? ...
// ... pero con los impuestos NO INCLUÍDOS en el precio unitario
$fac->addItem(new FacturaeItem([
    "name" => "Bombilla LED",
    "quantity" => 3,
    "unitPriceWithoutTax" => 6.5, // NOTA: no confundir con unitPrice
    "taxes" => [Facturae::TAX_IVA => 21]
]));

Como último apunte sobre la API avanzada de productos, por defecto Facturae-PHP interprenta al IRPF como un impuesto retenido (aquellos que se restan a la base imponible) y al resto de impuestos como repercutidos (se suman a la base imponible).

Si necesitas crear una factura "especial" es posible sobreescribir el comportamiento por defecto a través de la propiedad isWithheld:

// Para rizar un poco el rizo vamos a añadir una línea con IVA (repercutido)
// al 21% y también con impuestos especiales retenidos al 4%
$fac->addItem(new FacturaeItem([
  "name" => "Llevo impuestos retenidos",
  "quantity" => 1,
  "unitPrice" => 10,
  "taxes" => array(
    Facturae::TAX_IVA => 21,
    Facturae::TAX_IE  => ["rate"=>4, "isWithheld"=>true]
  )
]));

Forma de pago y vencimiento

Es posible indicar la forma de pago de una factura. Por ejemplo, en caso de pagarse al contado:

$fac->setPaymentMethod(Facturae::PAYMENT_CASH);

En caso de transferencia también debe indicarse la cuenta bancaria destinataria:

$fac->setPaymentMethod(Facturae::PAYMENT_TRANSFER, "ES7620770024003102575766");

Para establecer la fecha de vencimiento del pago:

$fac->setDueDate("2017-12-31");

Por defecto, si se establece una forma de pago y no se indica la fecha de vencimiento se interpreta la fecha de la factura como tal.

Firmado de facturas

Aunque es posible exportar las facturas sin firmarlas, es un paso obligatorio para prácticamente cualquier trámite relacionado con la Administración Pública. Para firmar facturas se necesita un certificado electrónico (generalmente expedido por la FNMT) del que extraer su clave pública y su clave privada. Los siguientes comandos permiten extraer el certificado (clave pública) y la clave privada de un archivo PFX:

openssl pkcs12 -in certificado_de_entrada.pfx -clcerts -nokeys -out clave_publica.pem
openssl pkcs12 -in certificado_de_entrada.pfx -nocerts -out clave_privada.pem

Por defecto, al firmar una factura se utilizan la fecha y hora actuales como sello de tiempo. Si se quiere indicar otro valor, se debe utilizar el siguiente método:

$fac->setSignTime("2017-01-01T12:34:56+02:00");

Otros métodos

Periodo de facturación

Es posible establecer el periodo de facturación con el siguiente método:

$fac->setBillingPeriod("2017-11-01", "2017-11-30");

Textos literales

Se pueden incluir textos literales (generalmente, declaraciones responsables del proveedor) en el XML de la factura:

$fac->addLegalLiteral("Este es un mensaje de prueba");
$fac->addLegalLiteral("Y este, otro más");

> ##### NOTA > El uso de LegalLiterals es obligatorio en determinadas facturas. Cosulta la legislación vigente para más información.

Totales de la factura

También es posible obtener un array con los totales de la factura:

$totales = $fac->getTotals();

> ##### NOTA > El método getTotals se ha dejado público al considerar que puede ser de gran utilidad para muchos programadores. > > Aún así, este método es utilizado por la clase principal para generar el documento XML de la factura y, por tanto, su salida está sujeta a cambios frecuentes para acomodar futuras funciones. > > En conclusión: si usas este método en tu proyecto lee los cambios de versión antes de actualizar.

Anexos

Constantes

|Constante|Descripción| |--------:|:----------| |Facturae::SCHEMA_3_2_1|Formato de Facturae 3.2.1| |Facturae::SIGN_POLICY_3_1|Formato de firma 3.1| ||| |Facturae::PAYMENT_CASH|Pago al contado| |Facturae::PAYMENT_TRANSFER|Pago por transferencia| ||| |Facturae::TAX_IVA|Impuesto sobre el valor añadido| |Facturae::TAX_IPSI|Impuesto sobre la producción, los servicios y la importación| |Facturae::TAX_IGIC|Impuesto general indirecto de Canarias| |Facturae::TAX_IRPF|Impuesto sobre la Renta de las personas físicas| |Facturae::TAX_OTHER|Otro| |Facturae::TAX_ITPAJD|Impuesto sobre transmisiones patrimoniales y actos jurídicos documentados| |Facturae::TAX_IE|Impuestos especiales| |Facturae::TAX_RA|Renta aduanas| |Facturae::TAX_IGTECM|Impuesto general sobre el tráfico de empresas que se aplica en Ceuta y Melilla| |Facturae::TAX_IECDPCAC|Impuesto especial sobre los combustibles derivados del petróleo en la Comunidad Autonoma Canaria| |Facturae::TAX_IIIMAB|Impuesto sobre las instalaciones que inciden sobre el medio ambiente en la Baleares| |Facturae::TAX_ICIO|Impuesto sobre las construcciones, instalaciones y obras| |Facturae::TAX_IMVDN|Impuesto municipal sobre las viviendas desocupadas en Navarra| |Facturae::TAX_IMSN|Impuesto municipal sobre solares en Navarra| |Facturae::TAX_IMGSN|Impuesto municipal sobre gastos suntuarios en Navarra| |Facturae::TAX_IMPN|Impuesto municipal sobre publicidad en Navarra| |Facturae::TAX_REIVA|Régimen especial de IVA para agencias de viajes| |Facturae::TAX_REIGIC|Régimen especial de IGIC: para agencias de viajes| |Facturae::TAX_REIPSI|Régimen especial de IPSI para agencias de viajes| ||| |FacturaeCentre::ROLE_CONTABLE<br>o FacturaeCentre::ROLE_FISCAL|Oficina contable| |FacturaeCentre::ROLE_GESTOR<br>o FacturaeCentre::ROLE_RECEPTOR|Órgano gestor| |FacturaeCentre::ROLE_TRAMITADOR<br>o FacturaeCentre::ROLE_PAGADOR|Unidad tramitadora| |FacturaeCentre::ROLE_PROPONENTE|Órgano proponente|

Herramientas de validación

Todas las facturas generadas y firmadas con Facturae-PHP son probadas con las siguientes herramientas online para garantizar el cumplimiento del estándar:

  • https://viewer.facturadirecta.com/
  • http://sedeaplicaciones2.minetur.gob.es/FacturaE/index.jsp
  • https://face.gob.es/es/facturas/validar-visualizar-facturas
  Files folder image Files  
File Role Description
Files folder imagesrc (4 files)
Files folder imagetests (3 files)
Accessible without login Plain text file .travis.yml Data Auxiliary data
Accessible without login Plain text file composer.json Data Auxiliary data
Accessible without login Plain text file composer.lock Data Auxiliary data
Accessible without login Plain text file CONTRIBUTING.md Data Auxiliary data
Accessible without login Plain text file LICENSE Lic. License text
Accessible without login Plain text file phpunit.xml Data Auxiliary data
Accessible without login Plain text file README.md Doc. Documentation

  Files folder image Files  /  src  
File Role Description
  Plain text file Facturae.php Class Class source
  Plain text file FacturaeCentre.php Class Class source
  Plain text file FacturaeItem.php Class Class source
  Plain text file FacturaeParty.php Class Class source

  Files folder image Files  /  tests  
File Role Description
  Accessible without login Plain text file FacturaeTest.php Example Example script
  Accessible without login Plain text file private.pem Data Auxiliary data
  Accessible without login Plain text file public.pem Data Auxiliary data

 Version Control Unique User Downloads Download Rankings  
 100%
Total:84
This week:2
All time:8,888
This week:346Up
User Comments (3)
Excelent work.
5 days ago (David Pascual)
77%StarStarStarStar
Excelent work.
5 days ago (David Pascual)
77%StarStarStarStar
Excelent work.
5 days ago (David Pascual)
77%StarStarStarStar