A PHP package for managing italian e-invoice and notice XML formats:
- XML management through
DOMDocument
andDOMXPath
- full
FatturaElettronica
(FatturaPA) XML skeleton - smart simplified xpath strings for getting/setting values (and for adding/getting/removing elements if needed)
- multiple bodies (invoice lot)
- multiple line items (
DettaglioLinee
) - multiple generic elements with
setElementCount()
- XML normalization: remove empty elements and automatically split
Causale
in chunks if > 200 characters - optional
FatturaElettronica
validation thanks to Slamdunk/php-validatore-fattura-elettronica
(Pacchetto PHP per gestire il formato XML di fatture e notifiche come richiesto dal SdI).
(Qui la documentazione aggiornata in italiano).
Please refer to
- PHP SdICoop - Server for implementing web services required by the Italian Exchange System (aka “SdI”)
- PHP SdICoop - Client to connect to SdI web services
See Forum Italia - Fatturazione Elettronica for server configuration, interoperability tests, etc. In particular:
- Apache configuration
- Accreditamento SDICoop: configurazione SSL su Apache - Fatturazione Elettroni…
- Interoperability tests
- Test Interoperabilità Soluzioni - Fatturazione Elettronica - Forum Italia
php-xml
- tested for PHP 7+
should work on PHP 5.5too
composer require taocomp/php-e-invoice-it
- Clone/download the repository
require_once('/path/to/php-e-invoice-it/vendor/autoload.php');
Create a new FPA12 invoice:
$invoice = new FatturaElettronica('FPA12');
Create a new FPR12 invoice:
$invoice = new FatturaElettronica('FPR12');
Create a new invoice from file
$invoice = new FatturaElettronica('/path/to/invoice.xml');
$prefixPath = __DIR__ . '/tmpfiles'; $filename = 'my-custom-template.xml'; $invoice = new FatturaElettronica('FPR12'); $invoice->setValue('IdTrasmittente/IdCodice', '00011122233'); $invoice->setValue('IdTrasmittente/IdPaese', 'IT'); $invoice->setFilename($filename); $invoice->setPrefixPath($prefixPath)->save();
Set 3 bodies:
$invoice->addBody(2); // or $invoice->setBodyCount(3);
Set 4 line items for second body:
$invoice->addLineItem(3, 2); // or $invoice->setLineItemCount(4, 2);
In general, you can get/set values (and add/get/remove elements) by using a tag/path and an optional context.
Please note that:
- an absolute path is relative to the root element:
/FatturaElettronicaHeader
means/p:FatturaElettronica/FatturaElettronicaHeader
- tags and relative paths are prefixed with
(.)//
- xpath predicates are allowed:
$invoice->getValue('DettaglioLinee[2]/NumeroLinea');
Get a value:
$invoice->getValue('ModalitaPagamento');
Get a value with a context:
$invoice->getValue('NumItem', 'DatiContratto');
Invalid queries (they return more than one element):
$invoice->getValue('IdPaese'); $invoice->getValue('Sede/Indirizzo', 'FatturaElettronicaHeader');
Set a value for a specific element:
$invoice->setValue('ProgressivoInvio', 10001);
Set many single values at once:
$invoice->setValues('IdTrasmittente', array( 'IdCodice' => '09876543210', 'IdPaese' => 'IT' ));
$invoice->setValues('CedentePrestatore/Sede', array( 'Indirizzo' => 'VIA UNIVERSO 1' ));
$invoice->setValues('CessionarioCommittente', array( // CessionarioCommittente/DatiAnagrafici/CodiceFiscale 'DatiAnagrafici/CodiceFiscale' => '01234567890', // Denominazione, somewhere inside CessionarioCommittente 'Denominazione' => 'BETA SRL' ));
// Set values for second body $body2 = $invoice->getBody(2); $invoice->setValue('Numero', 44, $body2); $invoice->setValue('Data', '2018-12-12', $body2);
Set values to multiple elements at once:
$invoice->setValuesToAll('DatiGenerali', array( // All "RiferimentoNumeroLinea" somewhere inside DatiGenerali 'RiferimentoNumeroLinea' => 1, // All "IdDocumento" somewhere inside DatiGenerali 'IdDocumento' => 4455, // All "NumItem" somewhere inside DatiGenerali 'NumItem' => 1 ));
Set values from an assoc array:
$array = array( 'DatiAnagraficiVettore' => array( 'IdFiscaleIVA' => array( 'IdPaese' => 'IT', 'IdCodice' => '09876543210' ), 'Anagrafica' => array( 'Denominazione' => 'TRASPORTO SRLS' ), 'NumeroLicenzaGuida' => 'AA090909' ), 'MezzoTrasporto' => 'Mezzo', 'CausaleTrasporto' => 'La causale del traporto', 'NumeroColli' => '1', 'Descrizione' => 'La descrizione' ); $invoice->setValuesFromArray('DatiTrasporto', $array);
All but setValueToAll
and setValuesToAll
methods will throw an exception if $expr/$context
don’t return just one element.
Set:
$invoice->setStylesheet('/path/to/xsl');
Unset:
$invoice->unsetStylesheet();
You need Slamdunk/php-validatore-fattura-elettronica. If you install php-e-invoice-it
via-composer, you got it as dependency; otherwise you must download and require it manually.
$invoice->validate();
An exception is thrown (with a message) if the XML is not valid, for example:
DOMDocument::schemaValidateSource(): Element 'DatiTrasmissione': Missing child element(s). Expected is ( CodiceDestinatario ).
Set an optional default destination dir for all invoices:
FatturaElettronica::setDefaultPrefixPath('path/to/dir');
Set an optional destination dir for current invoice:
$invoice->setPrefixPath('path/to/another/dir');
Save invoice:
$invoice->save();
Specify a custom filename:
$invoice->setFilename('my-invoice.xml')->save();
Setup a \Taocomp\Einvoicing\SdicoopClient\Client
object (for connecting to webservice SdIRiceviFile):
use \Taocomp\Einvoicing\SdicoopClient\Client; use \Taocomp\Einvoicing\SdicoopClient\FileSdIBase; use \Taocomp\Einvoicing\SdicoopClient\RispostaSdIRiceviFile; Client::setPrivateKey('/path/to/client.key'); Client::setClientCert('/path/to/client.pem'); Client::setCaCert('/path/to/ca.pem'); $client = new Client(array( 'endpoint' => 'https://testservizi.fatturapa.it/ricevi_file', 'wsdl' => '/path/to/wsdl/SdIRiceviFile_v1.0.wsdl' ));
Send invoice:
$fileSdI = new FileSdIBase(); $fileSdI->load($invoice); $response = new RispostaSdIRiceviFile($client->RiceviFile($fileSdI));
NotificaEsitoCommittente:
$notice = new EsitoCommittente();
// Set some values from invoice, second body: $notice->setValuesFromInvoice($invoice, 2); // Set values $notice->setValue('IdentificativoSdI', 1234567); $notice->setValue('Esito', EsitoCommittente::EC01);
Set:
$notice->setStylesheet('/path/to/xsl');
Unset:
$notice->unsetStylesheet();
// Set filename from invoice $notice->setFilenameFromInvoice($invoice, '_EC_001'); // Save notice $notice->save();
Setup a \Taocomp\Einvoicing\SdicoopClient\Client
object (for connecting to webservice SdIRiceviNotifica):
use \Taocomp\Einvoicing\SdicoopClient\Client; use \Taocomp\Einvoicing\SdicoopClient\FileSdI; use \Taocomp\Einvoicing\SdicoopClient\RispostaSdINotificaEsito; Client::setPrivateKey('/path/to/client.key'); Client::setClientCert('/path/to/client.pem'); Client::setCaCert('/path/to/ca.pem'); $client = new Client(array( 'endpoint' => 'https://testservizi.fatturapa.it/ricevi_notifica', 'wsdl' => __DIR__ . '/../wsdl/SdIRiceviNotifica_v1.0.wsdl' ));
Send notice:
$fileSdI = new FileSdI(); $fileSdI->load($notice); $response = new RispostaSdINotificaEsito($client->NotificaEsito($fileSdI));
From inside the project root dir:
./vendor/bin/phpunit --testdox tests
We want to thank all contributors of Forum Italia - Fatturazione Elettronica who have shared their snippets and any available info.
Thanks to @Slamdunk for Slamdunk/php-validatore-fattura-elettronica!
GPLv3.