Download the PHP package khaledhajsalem/zatca-php without Composer

On this page you can find all versions of the php package khaledhajsalem/zatca-php. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package zatca-php

ZATCA PHP Package

Packagist Version Downloads License ZATCA Phase 2

A PHP package for ZATCA (Saudi Arabia) Phase 2 e-invoicing. Handles XML generation (UBL 2.1), digital signing, QR codes, and API submission — all without database dependencies.

Table of Contents


Requirements

Installation


Key Concepts

Before using this package, understand these ZATCA-specific terms:

Term What it means
Standard Invoice B2B/B2G invoice. Must be cleared by ZATCA before you can send it to the buyer. Type name: 0100000.
Simplified Invoice B2C invoice (e.g., retail receipt). Must be reported to ZATCA within 24 hours. Type name: 0200000.
Clearance ZATCA validates and approves a Standard invoice in real-time. You get back a "cleared" XML.
Reporting You send a Simplified invoice to ZATCA for record-keeping. No real-time approval needed.
PIH (Previous Invoice Hash) SHA-256 hash of the previous invoice. Creates a tamper-proof chain. First invoice uses InvoiceData::FIRST_INVOICE_HASH, the base64 SHA-256 of '0' (BR-KSA-26).
ICV (Invoice Counter Value) Sequential counter starting at 1. Must increment for every invoice.
CSR Certificate Signing Request — you generate this and send it to ZATCA to get your signing certificate.
OTP One-Time Password — ZATCA gives you this when you register your device on the Fatoora portal.

Invoice Type Codes

Code Type Method
388 Tax Invoice ->taxInvoice()
381 Credit Note ->creditNote()
383 Debit Note ->debitNote()
386 Prepayment Invoice ->prepaymentInvoice()

Party Identification Schemes

Both seller and buyer support these identification types:

Scheme ID Description
CRN Commercial Registration Number
VAT VAT Number
TIN Tax Identification Number
NAT National ID
IQA Iqama Number
GCC GCC ID
PAS Passport ID
MOM MOMRAH License
MLS MHRSD License
SAG MISA License
700 700 Number
OTH Other ID

How It Works (Lifecycle)

Here is the complete flow from setup to invoice submission:


Step 1: Generate CSR & Private Key

Do this once when setting up your system with ZATCA.

What happens next:

  1. Log in to the ZATCA Fatoora Portal
  2. Register your device — ZATCA gives you an OTP
  3. Use the OTP to request a compliance certificate (see Step 2)

Important: The OTP, compliance certificate and production certificate must all come from the same environment. For simulation, generate the OTP from the Fatoora Simulation portal; sandbox/developer-portal credentials will be rejected with "You are not authorized to use this api endpoint".


Step 2: Get Your Certificate from ZATCA


Step 3: Create & Submit an Invoice

This is the main workflow you'll use for every invoice.

Simplified Tax Invoice (B2C)

Standard Tax Invoice (B2B)

The only difference from simplified is the invoice type — everything else is the same:


Invoice Types

Summary

Type Code Name Clearance? Method
Standard Tax Invoice 388 0100000 Yes (real-time) ->standard()->taxInvoice()
Simplified Tax Invoice 388 0200000 No (report within 24h) ->simplified()->taxInvoice()
Standard Credit Note 381 0100000 Yes ->standard()->creditNote()
Simplified Credit Note 381 0200000 No ->simplified()->creditNote()
Standard Debit Note 383 0100000 Yes ->standard()->debitNote()
Simplified Debit Note 383 0200000 No ->simplified()->debitNote()
Prepayment Invoice 386 — Depends on standard/simplified ->prepaymentInvoice()

Transaction Flags (KSA-2)

The name attribute is NNPNESB: the subtype (01 standard, 02 simplified) followed by five flags. Set them with chainable methods, in any order:

Flag Method Position Allowed on simplified?
Third party ->thirdParty() P (3) Yes
Nominal supply ->nominal() N (4) Yes
Export ->export() E (5) No
Summary ->summary() S (6) Yes
Self-billed ->selfBilled() B (7) No

Pass false to clear a flag (->export(false)). generateXml() rejects the combinations ZATCA forbids:

Supply Dates

The supply date (KSA-5) defaults to the issue date. Summary invoices also need a supply end date (KSA-24):

Prepayment Adjustment

To deduct an earlier prepayment invoice (386) from a final invoice, add it with addPrepayment(). Each prepayment becomes a zero-value invoice line that references it (§9.5). PrepaidAmount becomes the sum of taxable amount and VAT, and PayableAmount is reduced by it:


Credit & Debit Notes

Credit and debit notes must reference the original invoice using addBillingReference(). Payment means are optional but recommended.


Data Reference

InvoiceData — All Setters

Method Type Required Description
setInvoiceNumber($num) string Yes Your invoice number
standard() — Yes* Set as Standard (B2B). *One of standard/simplified required
simplified() — Yes* Set as Simplified (B2C)
taxInvoice() — Yes* Tax Invoice (388). *One of tax/credit/debit/prepayment required
creditNote() — — Credit Note (381)
debitNote() — — Debit Note (383)
prepaymentInvoice() — — Prepayment (386)
setIssueDate($date) string Yes Format: Y-m-d
setIssueTime($time) string Yes Format: H:i:s
setDueDate($date) string No Format: Y-m-d
setCurrencyCode($code) string Yes ISO 4217 (e.g., SAR)
setDocumentCurrencyCode($code) string Yes Usually same as currency code
setTaxCurrencyCode($code) string Yes Must be SAR (BR-KSA-EN16931-02)
setTaxExchangeRate($rate) float If currency ≠ SAR 1 unit of the invoice currency in SAR, used for the SAR VAT total (BT-111)
setInvoiceCounter($icv) string Yes Sequential counter starting at 1
setPreviousInvoiceHash($pih) string Yes InvoiceData::FIRST_INVOICE_HASH for first invoice (the default)
thirdParty() / nominal() / export() / summary() / selfBilled() bool No KSA-2 flags. See Transaction Flags
setSupplyDate($date) string No Supply date (KSA-5). Default: issue date
setSupplyEndDate($date) string Summary Supply end date (KSA-24)
setNote($note, $lang) string No Invoice note (BT-22), optional languageID
addPrepayment($prepayment) array No Deduct a prepayment invoice. See Prepayment Adjustment
setPayableRoundingAmount($amt) float No Rounding amount (BT-114) added to the amount due
getFileName() — — File name per §14, e.g. 300000000000003_20240115T103000_INV-001.xml
setSeller($seller) SellerData Yes Seller information
setBuyer($buyer) BuyerData Yes Buyer information
addLine($line) InvoiceLineData Yes At least one line required
calculateTotals() — Yes Call after adding all lines
addBillingReference($ref) array For CN/DN Keys: id, uuid
addPaymentMeans($pm) array No Keys: code (10, 30, 42, 48, 1), instruction_note, due_date, channel_code, payment_id
addAllowance($allowance) array No Document-level discount. Keys: amount, reason (default discount), reason_code (UNTDID 5189, e.g. 95), base_amount + multiplier (percentage, both or neither; amount is computed if omitted), tax_category, tax_percent
addCharge($charge) array No Document-level charge. Same keys as addAllowance(); reason and reason_code (UNTDID 7161, e.g. FC = freight) are required

SellerData — All Setters

Method Type Required Description
setRegistrationName($name) string Yes Company legal name
setVatNumber($vat) string Yes 15-digit VAT number
setPartyIdentification($value) string Yes ID value (e.g., CRN number)
setPartyIdentificationId($scheme) string Yes Scheme: CRN, VAT, TIN, etc.
setStreetName($street) string Yes Street name
setBuildingNumber($num) string Yes Building number
setCityName($city) string Yes City name
setPostalZone($zip) string Yes Postal/ZIP code
setCountryCode($code) string Yes 2-letter code (e.g., SA)
setPlotIdentification($plot) string No Plot identification
setCitySubdivisionName($district) string Yes District name (BR-KSA-09)
setAdditionalStreetName($name) string No Additional street name

BuyerData — All Setters

Same methods as SellerData. For simplified invoices, setVatNumber() is optional.

InvoiceLineData — All Setters

Method Type Required Description
setId($id) int Yes Line number (sequential: 1, 2, 3...)
setItemName($name) string Yes Item name
setDescription($desc) string No Item description (cac:Item/cbc:Description)
setQuantity($qty) float Yes Quantity
setUnitPrice($price) float Yes Unit price (tax-exclusive)
setTaxPercent($pct) float Yes VAT percentage (e.g., 15.0). Ignored (0%) for Z, E and O lines
setTaxCategory($cat, $reasonCode, $reasonText) string No VAT category: S (default), Z, E or O. See Zero-rated, exempt & out-of-scope items
setUnitCode($code) string No UN/ECE Rec 20 unit code (default: PCE)
setItemCode($code) string No Seller's item code (BT-155)
setBuyersItemCode($code) string No Buyer's item code (BT-156)
setStandardItemCode($code, $scheme) string No Standard item ID (BT-157), e.g. GTIN
setPriceDiscount($amt) float No Per-unit discount (BT-147). setUnitPrice() is then the gross price; the net price is gross − discount
setBaseQuantity($qty) float No Units the price applies to (BT-149), e.g. 12 for a price per dozen
calculateTotals() — Yes Auto-calculates all amounts from qty × price × tax%
setAllowanceAmount($amt) float No Line-level discount total (set before calculateTotals). setUnitPrice() is the gross, pre-discount unit price.
setAllowanceReason($reason) string No Reason for the line discount (default: discount)
setAllowanceReasonCode($code) string No UNTDID 5189 code for the line discount (e.g. 95)
setChargeAmount($amt) float No Line-level charge (set before calculateTotals). Requires setChargeReason() and setChargeReasonCode()
setChargeReason($reason) string With a charge Reason for the line charge (BR-KSA-22)
setChargeReasonCode($code) string With a charge UNTDID 7161 code (e.g. CG = cleaning) (BR-KSA-20)

Rounding: amounts are rounded half-up to 2 decimals at each step (line net, line VAT, VAT per category, totals), as the standard requires. Unit prices and quantities keep their decimals.

Tip: Call calculateTotals() on each line item, then call calculateTotals() on the invoice. This auto-fills lineExtensionAmount, taxAmount, taxExclusiveAmount, taxInclusiveAmount, and all invoice-level totals.

See also: Line discounts (BG-27) & B2B/B2C buyer party — how a line discount becomes a valid cac:AllowanceCharge, and how the buyer party differs between Standard (B2B) and Simplified (B2C) invoices.

Zero-rated, Exempt & Out-of-scope Items

Every line is standard-rated (S) by default. Use setTaxCategory() for other VAT categories. Z, E and O lines are always taxed at 0% and need a ZATCA exemption reason code. The reason text is filled in from ZATCA's official wording, except for VATEX-SA-OOS, where you must supply your own text.

Category Meaning Reason codes
S Standard rated none
Z Zero rated VATEX-SA-32, VATEX-SA-33, VATEX-SA-34-1 … VATEX-SA-34-5, VATEX-SA-35, VATEX-SA-36, VATEX-SA-EDU, VATEX-SA-HEA, VATEX-SA-MLTRY
E Exempt VATEX-SA-29, VATEX-SA-29-7, VATEX-SA-30
O Out of scope VATEX-SA-OOS

You can mix categories in one invoice. calculateTotals() builds one VAT breakdown entry (cac:TaxSubtotal) per category, rate and reason, and the XML includes it automatically. For VATEX-SA-EDU and VATEX-SA-HEA, ZATCA also requires the buyer's national ID (NAT).

A document-level allowance or charge uses the first line's category unless you set tax_category (and tax_percent for S):

Previous Invoice Hash (PIH) Chain

Every invoice references the hash of the previous invoice to create a tamper-proof chain:


Validation

validate() checks an invoice against the ZATCA business rules before anything is sent, and lists every problem at once. You don't have to wait for ZATCA to reject the invoice one error at a time.

Set 'validate' => true in the ZatcaManager config to validate automatically in processInvoice(). Errors then throw a ZatcaValidationException before signing or sending. Warnings never block.

What is checked:

Area Rules
Header Invoice number, issue date (valid, not in the future), issue time format, date formats, currency codes, ICV digits, previous invoice hash (BR-02/03, BR-KSA-04/26/34/70, BR-KSA-F-01, BR-CL-04, BR-KSA-EN16931-02)
Seller Name, VAT number format, identification and scheme, full address, 4-digit building number, 5-digit postal code, country code (BR-06, BR-KSA-08/09/37/39/40/66, BR-CL-14)
Buyer Name and address on tax invoices, VAT number format, ID when there is no VAT number, ID scheme, Saudi address fields (BR-KSA-10/14/42/44/63/67/81)
Notes Billing reference for credit/debit notes, reason warning (BR-KSA-56, BR-55, BR-KSA-17)
Payment Payment means codes 10, 30, 42, 48, 1 (BR-KSA-16)
Lines At least one line, item names, no negative values, standard rate above 0%, national ID for education/healthcare exemptions (BR-16, BR-25, BR-KSA-F-04, BR-KSA-DEC-02, BR-KSA-25/49)
Allowances/charges Non-negative amounts, standard rate above 0% (BR-S-06/07)
Flags & dates Flag combinations, supply dates, simplified summary requirements, prepayment date/time (BR-KSA-07/31/36/46/71/72, BR-KSA-F-05)

Character limits (BR-KSA-F-06) come from ZATCA's separate Data Dictionary and are not checked.


Error Handling

All exceptions extend ZatcaException and provide a getContext() method with structured error details.


Package Structure


Testing


Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

Acknowledgments

This package includes code and inspiration from:

License

This package is open-sourced software licensed under the MIT license.

Support

Changelog

See CHANGELOG.md for version history.


All versions of zatca-php with dependencies

PHP Build Version
Package Version
Requires php Version ^8.0
phpseclib/phpseclib Version ^3.0
guzzlehttp/guzzle Version ^7.0
chillerlan/php-qrcode Version ^4.3
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package khaledhajsalem/zatca-php contains the following files

Loading the files please wait ...