msalem/zatca

Easy-to-use Laravel package for ZATCA (Saudi Arabian E-Invoicing) Phase 1 and Phase 2 integration

Maintainers

Package info

github.com/mahmoud-msalem/zatca

pkg:composer/msalem/zatca

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-08-21 20:44 UTC

This package is auto-updated.

Last update: 2026-08-21 21:53:25 UTC


README

Easy-to-use Laravel package for ZATCA (Saudi Arabian E-Invoicing) Phase 1 and Phase 2 integration.

Features

  • Phase 1: Simple QR Code generation for invoices
  • Phase 2: Full E-Invoicing integration with ZATCA
    • CSR (Certificate Signing Request) generation
    • Compliance CSID acquisition
    • Production CSID acquisition
    • Invoice signing and submission
    • Support for both B2B (reporting) and B2C (clearance) invoices

Installation

  1. Require the package
composer require mSalem/zatca

Usage

Phase 1: QR Code Generation

Generate simple QR codes for invoices (for Phase 1 compliance):

use MSalem\Zatca\Facades\Zatca;


// Generate as base64 PNG
$qrCodeBase64 = Zatca::phaseOne()
    ->sellerName('My Company')
    ->vatNumber('123456789123456')
    ->timestamp(now())
    ->totalWithVat('115.00')
    ->vatTotal('15.00')
    ->generateBase64();

Phase 2: Full E-Invoicing Integration

Step 1: Generate CSR (Certificate Signing Request)

use MSalem\Zatca\Facades\Zatca;
use MSalem\Zatca\Enum\Environment;

$cSRRequestDto = CSRRequestDto::fromArray([
        'vatNumber' => '310461435700003',
        'solutionName' => 'myErp',
        'version' => '1.0.0',
        'serialNumber' => '1-TST|2-TST|3-' . uniqid(),
        'commonName' => 'TST-886431145-399999999900003',
        'organizationName' => 'My Test Company',
        'organizationalUnit' => 'Riyad Branch',
        'registeredAddress' => 'Riyadh',
        'environment' => Environment::SANDBOX,
        'businessCategory' => 'Retail',
    ]);

$result = Zatca::csr()->generateCSR($cSRRequestDto);

// Returns:
// [
//     'csrContent' => '...',
//     'privatekey' => '...',
// ]

Step 2: Get Compliance Certificate

Get an OTP from the ZATCA portal:

$csrContent = '...' // get it from step 1 (Generate CSR (Certificate Signing Request));
$otp = '123345'; // From ZATCA portal
$environment = Environment::SANDBOX;

$result = Zatca::api($environment)->getComplianceCSID($csrContent, $otp);

// Save the certificate and secret
// [
//     'requestID' => 
//     'binarySecurityToken' => '...', // certificate
//     'secret' => '...', // secret
// ]

Step 3: Sign and Submit Invoice

// Load your XML invoice (must conform to ZATCA UBL 2.1 format)
$xmlInvoice = file_get_contents(storage_path('app/zatca/invoices/invoice.xml'));

// Load certificate, secret, and private key
$binarySecurityToken = '';
$secret = '';
$privateKey = '';

// Sign the invoice
$signedData = Zatca::invoice()->signInvoice(
    $xmlInvoice,
    $binarySecurityToken,
    $privateKey,
    $secret
);

// Extract UUID from XML
$doc = new \DOMDocument();
$doc->loadXML($xmlInvoice);
$xpath = new \DOMXPath($doc);
$uuid = $xpath->query('//cbc:UUID')->item(0)->nodeValue;
$environment = Environment::SANDBOX;
// Report invoice (B2B - Standard invoices)
$result = Zatca::api($environment)->reportInvoice(
    $signedData['signed_invoice'],
    $signedData['hash'],
    $uuid,
    $binarySecurityToken,
    $secret
);

// Or clear invoice (B2C - Simplified invoices)
$result = Zatca::api($environment)->clearInvoice(
    $signedData['signed_invoice'],
    $signedData['hash'],
    $uuid,
    $binarySecurityToken,
    $secret
);

Step 4: Get Production CSID (After Compliance Testing)

$complianceRequestId = 'request-id-from-compliance';
$binarySecurityToken = '';
$secret = '';
$environment = Environment::SANDBOX;

$result = Zatca::api($environment)->getProductionCSID(
    $complianceRequestId,
    $certificate,
    $secret
);

// Save production certificate and secret
// [
//     'requestID' => 
//     'binarySecurityToken' => '...', // certificate
//     'secret' => '...', // secret
// ]

API Reference

Phase One

Zatca::phaseOne()
    ->sellerName(string $name)
    ->vatNumber(string $vatNumber)
    ->timestamp($timestamp)
    ->totalWithVat(string $total)
    ->vatTotal(string $vat)
    ->generateBase64(): string

(CSR Generation)

Zatca::csr()->generateCSR(array $merchantData): array

Zatca API's

Zatca::api($environment)->getComplianceCSID(string $csrContent, string $otp): array
Zatca::api($environment)->checkInvoiceCompliance(string $signedInvoice, string $invoiceHash, string $uuid, string $binarySecurityToken, string $secret): array
Zatca::api($environment)->getProductionCSID(string $complianceRequestId, string $binarySecurityToken, string $secret): array
Zatca::api($environment)->reportInvoice(string $signedInvoice, string $invoiceHash, string $uuid, string $binarySecurityToken, string $secret): array
Zatca::api($environment)->clearInvoice(string $signedInvoice, string $invoiceHash, string $uuid, string $binarySecurityToken, string $secret): array

ZatcaInvoiceService

Zatca::invoice()->signInvoice(string $xmlInvoice, string $privateKey, string $binarySecurityToken, string $secret): array

Requirements

  • PHP 8.1 or higher
  • Laravel 11.0 or higher
  • salla/zatca package

License

MIT License

Credits

Built with ❤️ by Mahmoud Salem.