laravel-zatca maintained by hyderkamran
Laravel ZATCA E-Invoicing
A production-grade, open-source Laravel package for complete compliance with Saudi Arabia's ZATCA E-Invoicing requirements (Phase 1 & Phase 2).
Features
- E-Invoicing: Full support for B2B (Standard) and B2C (Simplified) invoices.
- XML Generation: Robust UBL 2.1 XML building, correctly typed and schema-compliant.
- QR Generation: Mandatory TLV (Tag-Length-Value) Base64 encoding for QR codes (all 9 tags supported).
- Phase 1 Compliance: Generate XML and QR codes locally.
- Phase 2 Compliance: Full API integration for Clearance (Standard) and Reporting (Simplified) workflows.
- Sandbox Support: Switch seamlessly between ZATCA Developer Portal (Sandbox) and Core API (Production).
- Cryptography Engine: Built-in support for ECDSA secp256k1 private keys, C14N XML canonicalization, and SHA-256 hashing.
- CSID Lifecycle: Artisan commands for CSR generation, compliance checks, and CSID onboarding.
- Eloquent Integration: A simple
HasZatcatrait to drop into your existingInvoicemodels.
Requirements
- PHP 8.1+
- Laravel 10.x / 11.x
ext-opensslext-simplexml
Installation
You can install the package via composer:
composer require hyderkamran/laravel-zatca
Publish the configuration file and migrations:
php artisan vendor:publish --tag="zatca-config"
php artisan vendor:publish --tag="zatca-migrations"
Run the migrations to create the zatca_certificates and zatca_submissions tables:
php artisan migrate
Configuration
Set your organization and seller details in config/zatca.php or your .env file:
ZATCA_ENVIRONMENT=sandbox
ZATCA_SELLER_NAME="Acme Corp"
ZATCA_SELLER_VAT_NUMBER="300000000000003"
ZATCA_SELLER_CR_NUMBER="1234567890"
ZATCA_ORG_NAME="Acme Corp"
ZATCA_ORG_UNIT="IT Department"
ZATCA_COMMON_NAME="acme-zatca-system"
ZATCA_EGIC="300000000000003"
Usage
1. Generate CSR & Private Key
Run the interactive command to generate a ZATCA-compliant CSR and secp256k1 private key.
php artisan zatca:generate-csr --env=sandbox --save-db
Submit this CSR to the ZATCA portal to retrieve an OTP.
(Note: Currently activate-csid command will be implemented to automatically store the CSID and secret from the OTP. For now, you can manually issue the API call via Zatca::client()->issueComplianceCsid() and store it in your DB).
2. Eloquent Trait Integration
Add the HasZatca trait to your existing Invoice model:
use Hyderkamran\LaravelZatca\Traits\HasZatca;
use Hyderkamran\LaravelZatca\Enums\InvoiceType;
class Invoice extends Model
{
use HasZatca;
public function getZatcaInvoiceType(): InvoiceType
{
return $this->is_b2b ? InvoiceType::STANDARD : InvoiceType::SIMPLIFIED;
}
public function toZatcaSeller(): array
{
return [
'name' => 'Acme Corp',
'vat_number' => '300000000000003',
// ...
];
}
public function toZatcaBuyer(): array
{
return [
'name' => $this->customer->name,
'vat_number' => $this->customer->vat_number,
];
}
public function toZatcaItems(): array
{
return $this->items->map(fn($item) => [
'name' => $item->name,
'quantity' => $item->qty,
'price' => $item->price,
])->toArray();
}
}
3. Generate XML and Submit
Once your model is configured, submission is one method call away:
$invoice = Invoice::find(1);
// Phase 1: Generate XML locally
$xml = $invoice->generateZatcaXml();
// Phase 2: Submit to ZATCA directly (auto-signs and routes to Clearance or Reporting)
$response = $invoice->submitToZatca();
if ($response->isSuccessful()) {
echo "Invoice submitted successfully!";
} else {
print_r($response->errors);
}
Fluent API (Without Models)
You can also use the Facade to build and submit invoices manually:
use Hyderkamran\LaravelZatca\Facades\Zatca;
$invoiceService = Zatca::invoice()
->simplified()
->seller(['name' => 'Acme', 'vat_number' => '300000000000003'])
->buyer(['name' => 'John Doe'])
->items([
['name' => 'Service A', 'quantity' => 1, 'price' => 100],
])
->vat(15);
// Get Base64 QR Code Image
$qrBase64 = $invoiceService->generateQrCode();
// Get valid XML
$xml = $invoiceService->generate();
// Submit
$response = Zatca::submit($invoiceService);
Credits
Support
Please open an issue in GitHub if you encounter any problems or have feature requests.
Security Vulnerabilities
If you discover a security vulnerability within this package, please send an e-mail to the maintainer. All security vulnerabilities will be promptly addressed.
License
The MIT License (MIT).