为 ZATCA 电子发票生成二维码并签名的辅助工具

dev-main 2024-09-02 05:16 UTC

This package is auto-updated.

Last update: 2024-10-02 05:26:27 UTC


README

Logo

ZATCA (Fatoora) QR-Code 实现

Picker 维护的非官方包,帮助开发者轻松实现 ZATCA (Fatoora) QR 码,这对于电子发票是必需的

需求

  • PHP >= 8.0
  • ambstring 扩展
  • ext-dom 扩展

安装

您可以通过 composer 安装此包

composer require zain4picker/zatca

(返回顶部)

用法

此库支持第一阶段和第二阶段。

第二阶段,包括将纳税人的系统与 ZATCA 集成,以及将电子发票和电子收据传输到 ZATCA。

生成 CSR

您需要通过 ZATCA API 将商户注册,以获得代表商户签署发票的权限。

use Picker\ZATCA\GenerateCSR;
use Picker\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());

在此阶段,您需要通过 API 将 CSR 分享给 ZATCA,以获得当前商户的证书

签署发票 & 生成二维码

use Picker\ZATCA\Helpers\Certificate;
use Picker\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()

以 Base64 格式生成二维码

最好使用 InvoiceSign 类在同一个过程中签署发票并为它生成二维码

<?php

use Picker\ZATCA\GenerateQrCode;
use Picker\ZATCA\Helpers\UXML;
use Picker\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==

生成 Base64(第一阶段)

use Picker\ZATCA\GenerateQrCode;

$generatedString = GenerateQrCode::fromData(
    'Picker', // seller name        
    '1234567891', // seller tax number
    '2021-07-12T14:25:09Z', // invoice date as Zulu ISO8601 @see https://en.wikipedia.org/wiki/ISO_8601
    '115.00', // invoice total amount
    '15.00' // invoice tax amount
)->toBase64();

// > Output
// AQVTYWxsYQIKMTIzNDU2Nzg5MQMUMjAyMS0wNy0xMlQxNDoyNTowOVoEBjEwMC4wMAUFMTUuMDA=

生成纯文本

use Picker\ZATCA\GenerateQrCode;
use Picker\ZATCA\Tags\InvoiceDate;
use Picker\ZATCA\Tags\InvoiceTaxAmount;
use Picker\ZATCA\Tags\InvoiceTotalAmount;
use Picker\ZATCA\Tags\Seller;
use Picker\ZATCA\Tags\TaxNumber;

$generatedString = GenerateQrCode::fromData(
    'Picker', // seller name        
    '1234567891', // seller tax number
    '2021-07-12T14:25:09Z', // invoice date as Zulu ISO8601 @see https://en.wikipedia.org/wiki/ISO_8601
    '115.00', // invoice total amount
    '15.00' // invoice tax amount
    // .....
)->toTLV();

// Render A QR Code Image
// data:image/png;base64, .........
$displayQRCodeAsBase64 = GenerateQrCode::fromData(
    'Picker', // seller name        
    '1234567891', // seller tax number
    '2021-07-12T14:25:09Z', // invoice date as Zulu ISO8601 @see https://en.wikipedia.org/wiki/ISO_8601
    '115.00', // invoice total amount
    '15.00' // invoice tax amount
    // .......
)->render();

// now you can inject the output to src of html img tag :)
// <img src="$displayQRCodeAsBase64" alt="QR Code" />

(返回顶部)

读取二维码

二维码的输出对人类不可读,并且一些二维码读取器可能显示无效输出,因为此二维码将在集成步骤完成后由 ZATCA 应用程序扫描。如果您想查看最终二维码图像的输出,可以使用以下网站

https://www.onlinebarcodereader.com/

image

测试

composer test

(返回顶部)

支持

我们的团队始终在这里帮助您。遇到问题了吗?想报告一个错误?您可以在 Github 上使用 问题跟踪器 提交一个。如果您还有任何问题,请通过加入 Telegram 上的 Picker 全球开发者社区或通过 支持电子邮件 联系我们

贡献

贡献使得开源社区成为一个如此令人惊叹的学习、灵感和创造的地方。您所做出的任何贡献都将被 高度赞赏

如果您有任何改进的建议,请分叉存储库并创建一个拉取请求。您也可以简单地打开一个带有“增强”标签的问题。别忘了给项目加星!再次感谢!

  1. 分叉项目
  2. 创建您的功能分支 (git checkout -b feature/AmazingFeature)
  3. 提交您的更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 打开拉取请求

(返回顶部)

安全

如果您发现任何安全问题,请通过电子邮件 security@picker.sd 联系我们,而不是使用问题跟踪器。

鸣谢

许可

MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件

(返回顶部)