{"id":22993657,"url":"https://github.com/saleh7/php-zatca-xml","last_synced_at":"2025-04-09T14:06:14.271Z","repository":{"id":65191683,"uuid":"586937904","full_name":"Saleh7/php-zatca-xml","owner":"Saleh7","description":"PHP-ZATCA-XML is an unofficial PHP library for generating ZATCA Fatoora e-invoices. It simplifies the process of creating compliant e-invoices, generating QR codes, handling certificates, and submitting invoices to ZATCA’s servers.","archived":false,"fork":false,"pushed_at":"2025-02-27T21:45:18.000Z","size":204,"stargazers_count":29,"open_issues_count":5,"forks_count":16,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-01T16:59:59.117Z","etag":null,"topics":["certificates-generator","e-invoices","fatoora","invoice","php","qrcode","xml","zatca"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Saleh7.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2023-01-09T15:29:45.000Z","updated_at":"2025-03-24T22:02:56.000Z","dependencies_parsed_at":"2023-01-09T20:52:52.600Z","dependency_job_id":null,"html_url":"https://github.com/Saleh7/php-zatca-xml","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Saleh7%2Fphp-zatca-xml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Saleh7%2Fphp-zatca-xml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Saleh7%2Fphp-zatca-xml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Saleh7%2Fphp-zatca-xml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Saleh7","download_url":"https://codeload.github.com/Saleh7/php-zatca-xml/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248054230,"owners_count":21039952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["certificates-generator","e-invoices","fatoora","invoice","php","qrcode","xml","zatca"],"created_at":"2024-12-15T05:13:50.897Z","updated_at":"2025-04-09T14:06:14.254Z","avatar_url":"https://github.com/Saleh7.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://i.imgur.com/hLSMzHU.png\"  alt=\"php-zatca-xml\"\u003e\n\u003c/p\u003e\n\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://badgen.net/packagist/php/saleh7/php-zatca-xml\" alt=\"php Version\"\u003e\n\u003ca href=\"https://packagist.org/packages/saleh7/php-zatca-xml\"\u003e\u003cimg alt=\"Packagist Stars\" src=\"https://img.shields.io/packagist/stars/saleh7/php-zatca-xml\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/saleh7/php-zatca-xml\"\u003e\u003cimg alt=\"Packagist Downloads\" src=\"https://img.shields.io/packagist/dt/saleh7/php-zatca-xml\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/saleh7/php-zatca-xml\"\u003e\u003cimg alt=\"Packagist Version\" src=\"https://img.shields.io/packagist/v/saleh7/php-zatca-xml\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/saleh7/php-zatca-xml\"\u003e\u003cimg alt=\"License\" src=\"https://img.shields.io/badge/License-MIT-yellow.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\n\u003cp align=\"center\"\u003e\nPlease feel free to \u003ca href=\"https://github.com/Saleh7/php-zatca-xml/pulls?q=sort%3Aupdated-desc+is%3Apr+is%3Aopen\"\u003e\u003cstrong\u003econtribute\u003c/strong\u003e\u003c/a\u003e if you are missing features or tags\n\u003cbr /\u003e\n\u003ca href=\"https://github.com/Saleh7/php-zatca-xml/tree/main/examples\"\u003eView Examples\u003c/a\u003e\n·\n\u003ca href=\"https://github.com/Saleh7/php-zatca-xml/issues\"\u003eReport a bug\u003c/a\u003e\n·\n\u003ca href=\"https://github.com/Saleh7/php-zatca-xml/issues\"\u003eRequest a feature\u003c/a\u003e\n·\n\u003ca href=\"https://github.com/Saleh7/php-zatca-xml/discussions\"\u003eAsk questions\u003c/a\u003e\n\u003c/p\u003e\n\n## 📖 Introduction  \n\n**PHP-ZATCA-XML** is an unofficial PHP library for generating **ZATCA Fatoora** e-invoices. It simplifies the process of creating compliant e-invoices, generating QR codes, handling certificates, and submitting invoices to **ZATCA’s servers**.  \n\nDesigned for **easy integration**, this library provides developers with a **customizable, robust, and efficient toolkit** to automate the ZATCA e-invoicing process in PHP applications.\n\n## 🚀 Planned Features  \n\nWe are actively working on expanding the capabilities of this library. If you're a developer and would like to contribute, your help is highly appreciated! 💡  \n\n- [ ] **XML to JSON Conversion** – Support for converting invoices from XML to JSON format.  \n- [ ] **JSON/Array to Invoice** – Ability to generate invoices directly from JSON or array structures.  \n- [ ] **Simplified Invoice Creation** – Streamlined generation of **Simplified Invoices**, **Debit**, and **Credit** compliant with ZATCA simplified.  \n- [ ] **Standard Invoice Creation** – Streamlined generation **Standard Invoices**, **Debit**, and **Credit** compliant with ZATCA standards.  \n- [ ] **Invoice to PDF Conversion** – Generate PDF versions of invoices for easy sharing and record-keeping.  \n\n💡 **Got an idea?** Feel free to suggest it or contribute!  \n Let's build something great together! 🚀  \n\n## ✨ Features  \n\n- 🚀 **ZATCA-Compliant** – Easily generate valid e-invoices for ZATCA regulations  \n- 📜 **Invoice Creation** – Generate standard and simplified invoices in XML format  \n- 🔐 **Digital Signing** – Sign invoices securely to ensure compliance  \n- 🏷 **QR Code Generation** – Automatically generate QR codes for invoices  \n- 📡 **Direct Submission to ZATCA** – Send invoices directly to ZATCA’s servers  \n- ⚡ **Lightweight \u0026 Fast** – Optimized for performance and easy integration in PHP projects  \n- 🔄 **Customizable \u0026 Extensible** – Easily adapt the library to your needs  \n\n\n## 📌 Requirements  \n\n### ✅ PHP Version  \n- **PHP 8.1 or higher**\n\n### ✅ Required PHP Extensions  \nEnsure the following PHP extensions are installed and enabled:  \n- **`ext-dom`**\n- **`ext-libxml`**\n- **`ext-openssl`**\n- **`ext-hash`**\n- **`ext-mbstring`**\n\n\n## 🛠 Installation  \n\n```bash\ncomposer require saleh7/php-zatca-xml\n```\n\n## 🚀 Usage  \n\nThis library simplifies the process of generating **ZATCA-compliant** e-invoices, handling **certificates**, signing invoices, and submitting them to **ZATCA’s API**. Below are the main usage examples:\n\n---\n\n### 📜 **1. Generating a Compliance Certificate**  \n\nFirst, generate a **certificate signing request (CSR)** and private key:  \n\n```php\nuse Saleh7\\Zatca\\CertificateBuilder;\nuse Saleh7\\Zatca\\Exceptions\\CertificateBuilderException;\n\ntry {\n    (new CertificateBuilder())\n        -\u003esetOrganizationIdentifier('312345678901233') // The Organization Identifier must be 15 digits, starting andending with 3\n        // string $solutionName .. The solution provider name\n        // string $model .. The model of the unit the stamp is being generated for\n        // string $serialNumber .. # If you have multiple devices each should have a unique serial number\n        -\u003esetSerialNumber('Saleh', '1n', 'SME00023')\n        -\u003esetCommonName('My Organization') // The common name to be used in the certificate\n        -\u003esetCountryName('SA') // The Country name must be Two chars only\n        -\u003esetOrganizationName('My Company') // The name of your organization\n        -\u003esetOrganizationalUnitName('IT Department') // A subunit in your organizatio\n        -\u003esetAddress('Riyadh 1234 Street') // like Riyadh 1234 Street \n        -\u003esetInvoiceType(1100)// # Four digits, each digit acting as a bool. The order is as follows: Standard Invoice, Simplified, future use, future use \n        -\u003esetProduction(false)// true = Production |  false = Testing\n        -\u003esetBusinessCategory('Technology') // Your business category like food, real estate, etc\n        \n        -\u003egenerateAndSave('output/certificate.csr', 'output/private.pem');\n        \n    echo \"Certificate and private key saved.\\n\";\n} catch (CertificateBuilderException $e) {\n    echo \"Error: \" . $e-\u003egetMessage() . \"\\n\";\n    exit(1);\n}\n```\n\n### 🔐 **2. Requesting a Compliance Certificate from ZATCA**  \n\nOnce the CSR is generated, you need to request a **compliance certificate** from **ZATCA's API**.  \n\n```php\nuse Saleh7\\Zatca\\ZatcaAPI;\nuse Saleh7\\Zatca\\Exceptions\\ZatcaApiException;\n\n$zatcaClient = new ZatcaAPI('sandbox');\n\ntry {\n    $otp = \"123123\"; // The OTP received from ZATCA\n    $certificatePath = __DIR__ . '/output/certificate.csr';\n    \n    // Load the generated CSR\n    $csr = $zatcaClient-\u003eloadCSRFromFile($certificatePath);\n    \n    // Request the compliance certificate from ZATCA\n    $complianceResult = $zatcaClient-\u003erequestComplianceCertificate($csr, $otp);\n    \n    // Display the returned certificate and API secret\n    echo \"Compliance Certificate:\\n\" . $complianceResult-\u003egetCertificate() . \"\\n\";\n    echo \"API Secret: \" . $complianceResult-\u003egetSecret() . \"\\n\";\n    echo \"Request ID: \" . $complianceResult-\u003egetRequestId() . \"\\n\";\n\n    // Save the certificate details to a JSON file\n    $outputFile = __DIR__ . '/output/ZATCA_certificate_data.json';\n    $zatcaClient-\u003esaveToJson(\n        $complianceResult-\u003egetCertificate(),\n        $complianceResult-\u003egetSecret(),\n        $complianceResult-\u003egetRequestId(),\n        $outputFile\n    );\n    \n    echo \"Certificate data saved to {$outputFile}\\n\";\n\n} catch (ZatcaApiException $e) {\n    echo \"API Error: \" . $e-\u003egetMessage();\n} catch (\\Exception $e) {\n    echo \"Error: \" . $e-\u003egetMessage();\n}\n```\n\n### 🧾 **3. Generating an Invoice XML**  \n\nNow that we have the compliance certificate, we can generate a **ZATCA-compliant e-invoice in XML format**.\n\n```php\nuse Saleh7\\Zatca\\{\n    SignatureInformation, UBLDocumentSignatures, ExtensionContent, UBLExtension, UBLExtensions, Signature, \n    InvoiceType, AdditionalDocumentReference, TaxScheme, PartyTaxScheme, Address, LegalEntity, Delivery, \n    Party, PaymentMeans, TaxCategory, AllowanceCharge, TaxSubTotal, TaxTotal, LegalMonetaryTotal, \n    ClassifiedTaxCategory, Item, Price, InvoiceLine, GeneratorInvoice, Invoice, UnitCode, \n    OrderReference, BillingReference, Contract, Attachment, Storage\n};\n\n// --- Invoice Type ---\n$invoiceType = (new InvoiceType())\n    -\u003esetInvoice('standard') // 'standard' or 'simplified'\n    -\u003esetInvoiceType('invoice') // 'invoice', 'debit', or 'credit', 'prepayment'\n    -\u003esetIsThirdParty(false) // Third-party transaction\n    -\u003esetIsNominal(false) // Nominal transaction\n    -\u003esetIsExportInvoice(false) // Export invoice\n    -\u003esetIsSummary(false) // Summary invoice\n    -\u003esetIsSelfBilled(false); // Self-billed invoice\n\n// --- Supplier \u0026 Customer Information ---\n$taxScheme = (new TaxScheme())-\u003esetId(\"VAT\");\n\n$partyTaxSchemeSupplier = (new PartyTaxScheme())-\u003esetTaxScheme($taxScheme)-\u003esetCompanyId('311111111101113');\n$partyTaxSchemeCustomer = (new PartyTaxScheme())-\u003esetTaxScheme($taxScheme);\n\n$address = (new Address())\n    -\u003esetStreetName('Prince Sultan Street')\n    -\u003esetBuildingNumber(\"2322\")\n    -\u003esetPlotIdentification(\"2223\")\n    -\u003esetCitySubdivisionName('Riyadh')\n    -\u003esetCityName('Riyadh')\n    -\u003esetPostalZone('23333')\n    -\u003esetCountry('SA');\n\n// --- Delivery ---\n$delivery = (new Delivery())-\u003esetActualDeliveryDate(date('Y-m-d'));\n\n// --- Additional Document References ---\n$additionalDocs = [];\n$additionalDocs[] = (new AdditionalDocumentReference())\n    -\u003esetId('ICV')\n    -\u003esetUUID(\"23\"); //Invoice counter value\n$additionalDocs[] = (new AdditionalDocumentReference())\n    -\u003esetId('PIH')\n    -\u003esetAttachment($attachment); // Previous Invoice Hash\n    // -\u003esetPreviousInvoiceHash('NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZjNzljMmRiYzIzOWRkNGU5MWI0NjcyOWQ3M2EyN2ZiNTdlOQ=='); // Previous Invoice Hash\n$additionalDocs[] = (new AdditionalDocumentReference())\n    -\u003esetId('QR');\n\n$legalEntity = (new LegalEntity())-\u003esetRegistrationName('Acme Widget’s LTD');\n\n$supplierCompany = (new Party())\n    -\u003esetPartyIdentification(\"311111111111113\")\n    -\u003esetPartyIdentificationId(\"CRN\")\n    -\u003esetLegalEntity($legalEntity)\n    -\u003esetPartyTaxScheme($partyTaxSchemeSupplier)\n    -\u003esetPostalAddress($address);\n\n$supplierCustomer = (new Party())\n    -\u003esetPartyIdentification(\"311111111111113\")\n    -\u003esetPartyIdentificationId(\"NAT\")\n    -\u003esetLegalEntity($legalEntity)\n    -\u003esetPartyTaxScheme($partyTaxSchemeCustomer)\n    -\u003esetPostalAddress($address);\n\n// --- Invoice Items \u0026 Pricing ---\n$classifiedTax = (new ClassifiedTaxCategory())-\u003esetPercent(15)-\u003esetTaxScheme($taxScheme);\n$productItem = (new Item())-\u003esetName('Pencil')-\u003esetClassifiedTaxCategory($classifiedTax);\n$price = (new Price())-\u003esetUnitCode(UnitCode::UNIT)-\u003esetPriceAmount(2);\n\n$lineTaxTotal = (new TaxTotal())-\u003esetTaxAmount(0.60)-\u003esetRoundingAmount(4.60);\n\n$invoiceLine = (new InvoiceLine())\n    -\u003esetUnitCode(\"PCE\")\n    -\u003esetId(1)\n    -\u003esetItem($productItem)\n    -\u003esetLineExtensionAmount(4)\n    -\u003esetPrice($price)\n    -\u003esetTaxTotal($lineTaxTotal)\n    -\u003esetInvoicedQuantity(2);\n\n$invoiceLines = [$invoiceLine];\n\n// --- Tax Totals ---\n$taxCategory = (new TaxCategory)\n    -\u003esetPercent(15)\n    -\u003esetTaxScheme($taxScheme);\n$taxSubTotal = (new TaxSubTotal)\n    -\u003esetTaxableAmount(4)\n    -\u003esetTaxAmount(0.6)\n    -\u003esetTaxCategory($taxCategory);\n$taxTotal = (new TaxTotal)\n    -\u003eaddTaxSubTotal($taxSubTotal)\n    -\u003esetTaxAmount(0.6);\n\n// --- Legal Monetary Total ---\n$legalMonetaryTotal = (new LegalMonetaryTotal())\n    -\u003esetLineExtensionAmount(4)\n    -\u003esetTaxExclusiveAmount(4)\n    -\u003esetTaxInclusiveAmount(4.60)\n    -\u003esetPrepaidAmount(0)\n    -\u003esetPayableAmount(4.60)\n    -\u003esetAllowanceTotalAmount(0);\n\n// --- Build the Invoice ---\n$invoice = (new Invoice())\n    -\u003esetUUID('3cf5ee18-ee25-44ea-a444-2c37ba7f28be')\n    -\u003esetId('SME00023')\n    -\u003esetIssueDate(new DateTime())\n    -\u003esetIssueTime(new DateTime())\n    -\u003esetInvoiceType($invoiceType)\n    -\u003esetInvoiceCurrencyCode('SAR')\n    -\u003esetTaxCurrencyCode('SAR')\n    -\u003esetDelivery($delivery)\n    -\u003esetAccountingSupplierParty($supplierCompany)\n    -\u003esetAccountingCustomerParty($supplierCustomer)\n    -\u003esetAdditionalDocumentReferences($additionalDocs)\n    -\u003esetTaxTotal($taxTotal)\n    -\u003esetLegalMonetaryTotal($legalMonetaryTotal)\n    -\u003esetInvoiceLines($invoiceLines);\n    // ......\n// --- Generate XML ---\ntry {\n    $generatorXml = GeneratorInvoice::invoice($invoice);\n    $outputXML = $generatorXml-\u003egetXML();\n    \n    // Save the XML to a file\n    $filePath = __DIR__ . '/output/unsigned_invoice.xml';\n    (new Storage)-\u003eput($filePath, $outputXML);\n    \n    echo \"Invoice XML saved to: \" . $filePath . \"\\n\";\n\n} catch (\\Exception $e) {\n    echo \"An error occurred: \" . $e-\u003egetMessage() . \"\\n\";\n    exit(1);\n}\n```\n\n### ✍️ **4. Signing the Invoice XML**  \n\nBefore submitting the invoice to **ZATCA**, we need to **digitally sign** it using the **compliance certificate** obtained earlier.\n\n```php\nuse Saleh7\\Zatca\\Helpers\\Certificate;\nuse Saleh7\\Zatca\\InvoiceSigner;\nuse Saleh7\\Zatca\\Storage;\n\n// Load the unsigned invoice XML\n$xmlInvoice = (new Storage)-\u003eget(__DIR__ . '/output/unsigned_invoice.xml');\n\n// Load the compliance certificate data from the JSON file\n$json_certificate = (new Storage)-\u003eget(__DIR__ . '/output/ZATCA_certificate_data.json');\n\n// Decode the JSON data\n$json_data = json_decode($json_certificate, true, 512, JSON_THROW_ON_ERROR);\n\n// Extract certificate details\n$certificate = $json_data['certificate'];\n$secret = $json_data['secret'];\n\n// Load the private key\n$privateKey = (new Storage)-\u003eget(__DIR__ . '/output/private.pem');\n$cleanPrivateKey = trim(str_replace([\"-----BEGIN PRIVATE KEY-----\", \"-----END PRIVATE KEY-----\"], \"\", $privateKey));\n\n// Create a Certificate instance\n$certificate = new Certificate(\n    $certificate,\n    $cleanPrivateKey,\n    $secret\n);\n\n// Sign the invoice\n$signedInvoice = InvoiceSigner::signInvoice($xmlInvoice, $certificate)-\u003egetXML();\n// Save the signed invoice\n(new Storage)-\u003eput(__DIR__.'/output/signed_invoice.xml', $signedInvoice);\n```\n\n### 📤 **5. Submitting the Signed Invoice to ZATCA**  \n\nOnce the invoice is **digitally signed**, it can be submitted to **ZATCA’s API** for compliance validation and clearance.  \n\n\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first\nto discuss what you would like to change.\n\nPlease make sure to update tests as appropriate.\n\n## 👨‍💻 Contributors\n\n\u003cimg src=\"https://github.com/sevaske.png\" width=\"60px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003ca href=\"https://github.com/sevaske\"\u003esevaske\u003c/a\u003e\u003c/sub\u003e\n\nThank you all for your continuous support and contributions!\n\n### Special Credits\n\nThis project has also benefited from some code snippets and ideas from the [SallaApp/ZATCA](https://github.com/SallaApp/ZATCA) repository. We appreciate their contribution to the community.\n\n## License\n\nThis project is licensed under the [MIT License](https://github.com/Saleh7/php-zatca-xml/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaleh7%2Fphp-zatca-xml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaleh7%2Fphp-zatca-xml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaleh7%2Fphp-zatca-xml/lists"}