1. Go to this page and download the library: Download saleh7/php-zatca-xml library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
saleh7 / php-zatca-xml example snippets
use Saleh7\Zatca\CertificateBuilder;
use Saleh7\Zatca\CertificateBuilderException;
try {
(new CertificateBuilder())
->setOrganizationIdentifier('312345678901233') // The Organization Identifier must be 15 digits, starting andending with 3
// string $solutionName .. The solution provider name
// string $model .. The model of the unit the stamp is being generated for
// string $serialNumber .. # If you have multiple devices each should have a unique serial number
->setSerialNumber('Saleh', '1n', 'SME00023')
->setCommonName('My Organization') // The common name to be used in the certificate
->setCountryName('SA') // The Country name must be Two chars only
->setOrganizationName('My Company') // The name of your organization
->setOrganizationalUnitName('IT Department') // A subunit in your organizatio
->setAddress('Riyadh 1234 Street') // like Riyadh 1234 Street
->setInvoiceType(1100)// # Four digits, each digit acting as a bool. The order is as follows: Standard Invoice, Simplified, future use, future use
->setProduction(false)// true = Production | false = Testing
->setBusinessCategory('Technology') // Your business category like food, real estate, etc
->generateAndSave('output/certificate.csr', 'output/private.pem');
echo "Certificate and private key saved.\n";
} catch (CertificateBuilderException $e) {
echo "Error: " . $e->getMessage() . "\n";
exit(1);
}
use Saleh7\Zatca\ZatcaAPI;
use Saleh7\Zatca\Exceptions\ZatcaApiException;
$zatcaClient = new ZatcaAPI('sandbox');
try {
$otp = "123123"; // The OTP received from ZATCA
$certificatePath = __DIR__ . '/output/certificate.csr';
// Load the generated CSR
$csr = $zatcaClient->loadCSRFromFile($certificatePath);
// Request the compliance certificate from ZATCA
$complianceResult = $zatcaClient->requestComplianceCertificate($csr, $otp);
// Display the returned certificate and API secret
echo "Compliance Certificate:\n" . $complianceResult->getCertificate() . "\n";
echo "API Secret: " . $complianceResult->getSecret() . "\n";
echo "Request ID: " . $complianceResult->getRequestId() . "\n";
// Save the certificate details to a JSON file
$outputFile = __DIR__ . '/output/ZATCA_certificate_data.json';
$zatcaClient->saveToJson(
$complianceResult->getCertificate(),
$complianceResult->getSecret(),
$complianceResult->getRequestId(),
$outputFile
);
echo "Certificate data saved to {$outputFile}\n";
} catch (ZatcaApiException $e) {
echo "API Error: " . $e->getMessage();
} catch (\Exception $e) {
echo "Error: " . $e->getMessage();
}
use Saleh7\Zatca\{
SignatureInformation, UBLDocumentSignatures, ExtensionContent, UBLExtension, UBLExtensions, Signature,
InvoiceType, AdditionalDocumentReference, TaxScheme, PartyTaxScheme, Address, LegalEntity, Delivery,
Party, PaymentMeans, TaxCategory, AllowanceCharge, TaxSubTotal, TaxTotal, LegalMonetaryTotal,
ClassifiedTaxCategory, Item, Price, InvoiceLine, GeneratorInvoice, Invoice, UnitCode,
OrderReference, BillingReference, Contract, Attachment
};
// --- Invoice Type ---
$invoiceType = (new InvoiceType())
->setInvoice('standard') // 'standard' or 'simplified'
->setInvoiceType('invoice') // 'invoice', 'debit', or 'credit', 'prepayment'
->setIsThirdParty(false) // Third-party transaction
->setIsNominal(false) // Nominal transaction
->setIsExportInvoice(false) // Export invoice
->setIsSummary(false) // Summary invoice
->setIsSelfBilled(false); // Self-billed invoice
// --- Supplier & Customer Information ---
$taxScheme = (new TaxScheme())->setId("VAT");
$partyTaxSchemeSupplier = (new PartyTaxScheme())->setTaxScheme($taxScheme)->setCompanyId('311111111101113');
$partyTaxSchemeCustomer = (new PartyTaxScheme())->setTaxScheme($taxScheme);
$address = (new Address())
->setStreetName('Prince Sultan Street')
->setBuildingNumber("2322")
->setPlotIdentification("2223")
->setCitySubdivisionName('Riyadh')
->setCityName('Riyadh')
->setPostalZone('23333')
->setCountry('SA');
$legalEntity = (new LegalEntity())->setRegistrationName('Acme Widget’s LTD');
$supplierCompany = (new Party())
->setPartyIdentification("311111111111113")
->setPartyIdentificationId("CRN")
->setLegalEntity($legalEntity)
->setPartyTaxScheme($partyTaxSchemeSupplier)
->setPostalAddress($address);
$supplierCustomer = (new Party())
->setPartyIdentification("311111111111113")
->setPartyIdentificationId("NAT")
->setLegalEntity($legalEntity)
->setPartyTaxScheme($partyTaxSchemeCustomer)
->setPostalAddress($address);
// --- Invoice Items & Pricing ---
$classifiedTax = (new ClassifiedTaxCategory())->setPercent(15)->setTaxScheme($taxScheme);
$productItem = (new Item())->setName('Pencil')->setClassifiedTaxCategory($classifiedTax);
$price = (new Price())->setUnitCode(UnitCode::UNIT)->setPriceAmount(2);
$lineTaxTotal = (new TaxTotal())->setTaxAmount(0.60)->setRoundingAmount(4.60);
$invoiceLine = (new InvoiceLine())
->setUnitCode("PCE")
->setId(1)
->setItem($productItem)
->setLineExtensionAmount(4)
->setPrice($price)
->setTaxTotal($lineTaxTotal)
->setInvoicedQuantity(2);
$invoiceLines = [$invoiceLine];
// --- Tax Totals ---
$taxSubTotal = (new TaxSubTotal())->setTaxableAmount(4)->setTaxAmount(0.6)->setTaxCategory($classifiedTax);
$taxTotal = (new TaxTotal())->addTaxSubTotal($taxSubTotal)->setTaxAmount(0.6);
// --- Legal Monetary Total ---
$legalMonetaryTotal = (new LegalMonetaryTotal())
->setLineExtensionAmount(4)
->setTaxExclusiveAmount(4)
->setTaxInclusiveAmount(4.60)
->setPrepaidAmount(0)
->setPayableAmount(4.60)
->setAllowanceTotalAmount(0);
// --- Build the Invoice ---
$invoice = (new Invoice())
->setUUID('3cf5ee18-ee25-44ea-a444-2c37ba7f28be')
->setId('SME00023')
->setIssueDate(new DateTime())
->setIssueTime(new DateTime())
->setInvoiceType($invoiceType)
->setInvoiceCurrencyCode('SAR')
->setTaxCurrencyCode('SAR')
->setAccountingSupplierParty($supplierCompany)
->setAccountingCustomerParty($supplierCustomer)
->setTaxTotal($taxTotal)
->setLegalMonetaryTotal($legalMonetaryTotal)
->setInvoiceLines($invoiceLines);
// ......
// --- Generate XML ---
try {
$generatorXml = new GeneratorInvoice();
$outputXML = $generatorXml->invoice($invoice);
// Save the XML to a file
$filePath = __DIR__ . '/output/unsigned_invoice.xml';
file_put_contents($filePath, $outputXML);
echo "Invoice XML saved to: " . $filePath . "\n";
} catch (\Exception $e) {
echo "An error occurred: " . $e->getMessage() . "\n";
exit(1);
}
use Saleh7\Zatca\Helpers\Certificate;
use Saleh7\Zatca\InvoiceSigner;
// Load the unsigned invoice XML
$xmlInvoice = file_get_contents(__DIR__ . '/output/unsigned_invoice.xml');
// Load the compliance certificate data from the JSON file
$json_certificate = file_get_contents(__DIR__ . '/output/ZATCA_certificate_data.json');
// Decode the JSON data
$json_data = json_decode($json_certificate, true, 512, JSON_THROW_ON_ERROR);
// Extract certificate details
$certificate = $json_data[0]['certificate'];
$secret = $json_data[0]['secret'];
// Load the private key
$privateKey = file_get_contents(__DIR__ . '/output/private.pem');
$cleanPrivateKey = trim(str_replace(["-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----"], "", $privateKey));
// Create a Certificate instance
$certificate = new Certificate(
$certificate,
$cleanPrivateKey,
$secret
);
// Sign the invoice
$signedInvoice = InvoiceSigner::signInvoice($xmlInvoice, $certificate);
// Save the signed invoice
InvoiceSigner::signInvoice($xmlInvoice, $certificate)->saveXMLFile('/output/signed_invoice.xml');
bash
composer
Loading please wait ...
Before you can download the PHP files, the dependencies should be resolved. This can take some minutes. Please be patient.