v1.0.0
15 Sep 2026First release.
Added
Zatca::encode()for the Saudi ZATCA QR payload — phase one tags 1–5 and phase two tags 6–9 — verified against the ASCII and Arabic vectors published by the reference implementation the Saudi market uses.Zatca::decode()andZatca::looksLikePayload(): reading a payload back into its fields, which no other package in this space does.Check::payload()with twelve reason codes,codes(),messages()and the decoded invoice, so a caller need not decode twice.Check::vatNumber()on its own, verifying the fifteen-digit shape beginning and ending with 3 — all that Saudi Arabia publishes a rule for.Amount::format(), which produces the same string as JavaScript'stoFixedfor every input by rounding the exact decimal expansion half-away-from-zero. Neithernumber_formatnorsprintfdoes: the first turns0.015into0.02, the second turns0.125into0.12.Timestamp::format(), which passes an ISO 8601 string through byte for byte so a signed timestamp is never invalidated by reformatting.- A
TlvExceptionnaming the tag when a value is longer than the 255 bytes a one-byte length field can hold, rather than wrapping silently. - A
SaudiVatNumbervalidation rule, registered assaudi_vat_numberfor the string form, whose message says which part failed. - A
Zatcafacade and a publishableconfig/zatca.phpholding the VAT rate and tolerance. - Eleven shared vectors generated by the JavaScript twin and read by both test suites, so the two packages are held to one file rather than to each other.
- Zero dependencies, including no QR library.