A pure PHP library to simplify the handling and processing of CFDIs. Creates new CFDIs and parses and validates existing CFDI files.
A CFDI is a "Comprobante Fiscal Digital por Internet" of Mexico's SAT "Servicio de Administración Tributaria" (Tax Administration Service).
- Parse XML representation of CFDIs
- Write XML files from a CFDI
- Validate cryptographic signatures
- Validate CFDI status online
Requires PHP 7.2+ and Composer.
composer require anglemx/sat-cfdi
<?
use Angle\CFDI\CFDI33;
use Angle\CFDI\XmlLoader;
// ...
// ...
// ...
$xmlFile = 'invoice.xml';
$loader = new XmlLoader();
$cfdi = $loader->fileToCFDI($xmlFile);
if (!$cfdi) {
// Parsing failed
// All the helper classes and utilities keep a log of errors that are meant for internal debugging
echo "Errors:" . PHP_EOL;
echo print_r($loader->getErrors(), true) . PHP_EOL;
// And the utilities also keep a log of validations, which are user-friendly and meant for public display
echo "Validations:" . PHP_EOL;
echo print_r($loader->getValidations(), true) . PHP_EOL;
}
// Parsing success!
print_r($cfdi);
// The validations log is also available upon success
echo "Validations:" . PHP_EOL;
echo print_r($loader->getValidations(), true) . PHP_EOL;
For more implementation examples, check the Test files.
In order to make this library as robust as possible, we're using many libraries that are included by default on most environments.
- Implements XSD schema files to validate XML. (
ext-dom
,ext-libxml
) - Implements XSLT stylesheets to generate the Original Chain Sequence for signature validations. (
ext-xsl
) - Implements OpenSSL to operate and verify X.509 Certificates. (
ext-openssl
)
This library is written in english to maintain code consistency. However, some keywords are very specific to this domain.
Español | English |
---|---|
Comprobante | Invoice |
Relacionados | Related |
Emisor | Issuer |
Concepto | Item |
Impuesto | Tax |
Impuestos Trasladados | Transferred Tax |
Impuestos Retenidos | Retained Tax |
Información Aduanera | Customs Information |
Predial | Property Tax |
pending.. |
This library bundles some resources to simplify the installation process on production servers, and to allow for offline processing. All of these files are published by SAT and are made available completely free through SAT's official website.
We've bundled the production root X.509 Certificates (CA) in a convenient PEM file. If you'd prefer, you can download them from the official website and install those files locally: http://omawww.sat.gob.mx/tramitesyservicios/Paginas/certificado_sello_digital.htm
SAT publishes a list of all the certificates for every single registered and active taxpayer. You can consult any specific certificate with SAT's official tool "Recuperación de Certificados".
You can use that system to look up all of SAT's certificates by searching their RFC: SAT970701NN3
The official publication regarding CFDI is called "Anexo 20" and we are currently on CFDI version 3.3. View online.
This employs some public web services to validate the status of CFDI.
pending..
See tests/ValidatorTest.php
for a sample implementation of the Validation Steps
- STEP 1: Parse XML into an Invoice
- STEP 2: Validate properties
- STEP 3: Validate CFDI signature
- STEP 4: Validate Fiscal Stamp (TFD)
- STEP 5: Validate CFDI's UUID against SAT
To run tests with PHPUnit, simply install the dev dependencies
composer install
Create a /test-data/
directory in this library's root path, and place all the XML files inside that you would like to test.
Finally, run the tests:
php vendor/bin/phpunit tests
- Validate properties when parsing
- Validate basic business rules
- Implement cache for X.509 Certificates
- Check for Certificate Revocation status before validating
- Implement cache for XSLT 2.0 transpilation
- Documentation and more samples
- Duplicated Namespace declarations on
CFDI::toXML()
when we have any child (even if not on the root node) with a different namespace than the default for the Document. We should clean this up when pretty printing our XMLs. - Replace all instances of
Node::NODE_NS_NAME
withNode::NODE_NS_URI_NAME
insidesetChildrenFromDOMNodes()
. SeeCFDI40\Complements
for reference.
echo 'Node class: ' . get_class($node) . PHP_EOL;
echo 'Node Name: ' . $node->nodeName . PHP_EOL;
echo 'Node Prefix ' . $node->prefix . PHP_EOL;
echo 'Node Local Name: ' . $node->localName . PHP_EOL;
echo 'Node Base URI: ' . $node->baseURI . PHP_EOL;
echo 'Node Namespace URI: ' . $node->namespaceURI . PHP_EOL;
echo PHP_EOL;
Node class: DOMElement
Node Name: tfd:TimbreFiscalDigital
Node Prefix tfd
Node Local Name: TimbreFiscalDigital
Node Base URI: /Users/mundofr/GitHub/Angle/sat-cfdi/test-data/4D75D60D-48CF-434C-96A6-26DABB3AC5AF.xml
Node Namespace URI: http://www.sat.gob.mx/TimbreFiscalDigital
Node class: DOMElement
Node Name: Pagos20:Pagos
Node Prefix Pagos20
Node Local Name: Pagos
Node Base URI: /Users/mundofr/GitHub/Angle/sat-cfdi/test-data/4D75D60D-48CF-434C-96A6-26DABB3AC5AF.xml
Node Namespace URI: http://www.sat.gob.mx/Pagos20