A PHP package for managing italian e-invoice and notice XML formats:
- XML management through
DOMDocumentandDOMXPath - 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
Causalein chunks if > 200 characters - optional
FatturaElettronicavalidation 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:
/FatturaElettronicaHeadermeans/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.