salla / zatca
A helper to generate the QR code and signed it for ZATCA e-invoicing
Requires
- php: >=8.0
- ext-dom: *
- ext-mbstring: *
- chillerlan/php-qrcode: ^4.3
- josemmo/uxml: ^0.1.4
- phpseclib/phpseclib: ~3.0
- robrichards/xmlseclibs: ^3.1
Requires (Dev)
- phpunit/phpunit: ~8.0
README
ZATCA (Fatoora) QR-Code Implementation
An unofficial package maintained by Salla to help developers to implement ZATCA (Fatoora) QR code easily which required for e-invoicing
Explore our blogs »
Report Bug ·
Request Feature
· </Salla Developers>
Requirements
- PHP >= 8.0
- A mbstring extension
- An ext-dom extension
Installation
You can install the package via composer:
$ composer require salla/zatca
Usage
This library supports both Phase 1 and Phase 2.
Phase 2, include mandates integration of a taxpayer's system with the ZATCA, along with the transmission of e-invoices and e-notes to the ZATCA.
Generating CSR
You need to onboard the merchant via the ZATCA APIs to had the authority to signing the invoice on behalf of the merchant.
use Salla\ZATCA\GenerateCSR; use Salla\ZATCA\Models\CSRRequest; $data = CSRRequest::make() ->setUID('string $OrganizationIdentifier') ->setSerialNumber('string $solutionName', 'string $version', 'string $serialNumber') ->setCommonName('string $commonName') ->setCountryName('SA') ->setOrganizationName('string $organizationName') ->setOrganizationalUnitName('string $organizationalUnitName') ->setRegisteredAddress('string $registeredAddress') ->setInvoiceType(true, true) //invoice types , the default is true, true ->setCurrentZatcaEnv('string $currentEnv') //support all modes ['sandbox','simulation','core'] ->setBusinessCategory('string $businessCategory'); $CSR = GenerateCSR::fromRequest($data)->initialize()->generate(); // writing the private_key to file openssl_pkey_export_to_file($CSR->getPrivateKey(), 'output file path name'); //writing the csr_content to file file_put_contents('output file path name', $CSR->getCsrContent());
At this stage you need to share the CSR to the ZATCA via APIs to get the certification for the current merchant
Signing Invoices & Generate QA code
use Salla\ZATCA\Helpers\Certificate; use Salla\ZATCA\Models\InvoiceSign; $xmlInvoice = 'xml invoice text'; $certificate = (new Certificate( 'certificate plain text (base64 decoded)', // get from ZATCA when you exchange the CSR via APIs 'private key plain text' // generated at stage one ))->setSecretKey('secret key text'); // get from ZATCA when you exchange the CSR via APIs $invoice = (new InvoiceSign($xmlInvoice, $certificate))->sign(); // invoice Hash: $invoice->getHash() // invoice signed as XML: $invoice->getInvoice() // Invoice QR code as base64: $invoice->getQRCode()
Generating QR Code As Base64
it's better to use
InvoiceSign
class to sign the invoice and generate the QR code for it in the same process
<?php use Salla\ZATCA\GenerateQrCode; use Salla\ZATCA\Helpers\UXML; use Salla\ZATCA\Helpers\Certificate; $xmlInvoice = 'xml invoice text'; $certificate = (new Certificate( 'certificate plain text (base64 decoded)', // get from ZATCA when you exchange the CSR via APIs 'private key plain text' // generated at stage one ))->setSecretKey('secret key text'); // get from ZATCA when you exchange the CSR via APIs $tags = UXML::fromString($xmlInvoice)->toTagsArray($certificate); $QRCodeAsBase64 = GenerateQrCode::fromArray($tags)->toBase64(); // Invoice Hash: $tags[5]->getValue() // Digital Signature: $tags[6]->getValue() //$QRCodeAsBase64 output will be like this //AQ1TYWxsYSAtIFNhbGxhAg8zMTA0NjE0MzU3MDAwMDMDFDIwMjMtMTItMzFUMjE6MDA6MDBaBAY0MDguNjkFBTUzLjMxBiw1TXZmVmZTWGRSZzgyMWU4Q0E3bE1WcDdNS1J4Q2FBWWZHTm90THlHNUg4PQdgTUVRQ0lEOGthSTF1Z29EcWJkN3NEVmFCVE9yOUswWlVwRkZNY2hON2FsNGgyTEhrQWlCYnZxZktkK0xaN0hEc0FMakxmeTA0dTBMNVRhcjhxenowYjBlb0EzMUtIdz09CFgwVjAQBgcqhkjOPQIBBgUrgQQACgNCAATmBleqoCAfxDveLQVAKCvHSjNxoudWhRNQ8zThTxzBtgjAqZQ7vBJWvu2Ut0MxYa8vq7O4tgusgmcLBDhK/xNCCUcwRQIhAIhuJ6o4ETNSosMEf/OLVbp+TZqi2IGSxsgyC54yZgQAAiB3lwym6zpkPspQrT+luMte/ifw4THG+waV+SmXNSukmQ==
Generate Base64 (phase one)
use Salla\ZATCA\GenerateQrCode; use Salla\ZATCA\Tags\InvoiceDate; use Salla\ZATCA\Tags\InvoiceTaxAmount; use Salla\ZATCA\Tags\InvoiceTotalAmount; use Salla\ZATCA\Tags\Seller; use Salla\ZATCA\Tags\TaxNumber; $generatedString = GenerateQrCode::fromArray([ new Seller('Salla'), // seller name new TaxNumber('1234567891'), // seller tax number new InvoiceDate('2021-07-12T14:25:09Z'), // invoice date as Zulu ISO8601 @see https://en.wikipedia.org/wiki/ISO_8601 new InvoiceTotalAmount('100.00'), // invoice total amount new InvoiceTaxAmount('15.00') // invoice tax amount ])->toBase64(); // > Output // AQVTYWxsYQIKMTIzNDU2Nzg5MQMUMjAyMS0wNy0xMlQxNDoyNTowOVoEBjEwMC4wMAUFMTUuMDA=
Generate Plain
use Salla\ZATCA\GenerateQrCode; use Salla\ZATCA\Tags\InvoiceDate; use Salla\ZATCA\Tags\InvoiceTaxAmount; use Salla\ZATCA\Tags\InvoiceTotalAmount; use Salla\ZATCA\Tags\Seller; use Salla\ZATCA\Tags\TaxNumber; $generatedString = GenerateQrCode::fromArray([ new Seller('Salla'), // seller name new TaxNumber('1234567891'), // seller tax number new InvoiceDate('2021-07-12T14:25:09Z'), // invoice date as Zulu ISO8601 @see https://en.wikipedia.org/wiki/ISO_8601 new InvoiceTotalAmount('100.00'), // invoice total amount new InvoiceTaxAmount('15.00') // invoice tax amount // ..... ])->toTLV(); // Render A QR Code Image // data:image/png;base64, ......... $displayQRCodeAsBase64 = GenerateQrCode::fromArray([ new Seller('Salla'), // seller name new TaxNumber('1234567891'), // seller tax number new InvoiceDate('2021-07-12T14:25:09Z'), // invoice date as Zulu ISO8601 @see https://en.wikipedia.org/wiki/ISO_8601 new InvoiceTotalAmount('100.00'), // invoice total amount new InvoiceTaxAmount('15.00') // invoice tax amount // ....... ])->render(); // now you can inject the output to src of html img tag :) // <img src="$displayQRCodeAsBase64" alt="QR Code" />
Read The QR-Code
The output of the QR-Code is not readable for the human 👀, and some of QR-Code readers may show an invalid output because this QR-Code will be scanned by the ZATCA apps later after all the steps of integration are completed. If you are interested to see the output of your final QR-Code Image, you can use the following website:
https://www.onlinebarcodereader.com/
Testing
composer test
Support
The team is always here to help you. Happen to face an issue? Want to report a bug? You can submit one here on Github using the Issue Tracker. If you still have any questions, please contact us by joining the Salla Global Developer Community on Telegram or via the Support Email
Contributing
Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Security
If you discover any securitys-related issues, please email security@salla.sa instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.