fatoora-rs-cli

Crates.iofatoora-rs-cli
lib.rsfatoora-rs-cli
version0.1.0
created_at2026-01-18 13:53:45.06446+00
updated_at2026-01-18 13:53:45.06446+00
descriptionCommand-line interface for the fatoora ZATCA SDK
homepagehttps://github.com/mqqz/fatoora-rs
repositoryhttps://github.com/mqqz/fatoora-rs
max_upload_size
id2052383
size97,203
Mohamad Alsadhan (mqqz)

documentation

https://docs.rs/fatoora-rs-cli

README

fatoora-rs

MIT License codecov

An unofficial open-source toolkit for everything you'd need for ZATCA (Zakat, Tax and Customs Authority of Saudi Arabia) Phase 1 and 2 compliant e-invoicing

...with bindings and support for many programming languages (coming soon lol).

...and also built in Rust btw

fatoora-rs is in active early development. While the core functionality is usable, the public API is still evolving and may change as the project matures. We strive to maintain good test coverage and stability, but users should be aware that some rough edges may remain. Feedback and contributions are especially welcome at this stage.

Disclaimer: fatoora-rs is not affiliated, associated, authorized, endorsed by, or in any way officially connected with ZATCA (Zakat, Tax and Customs Authority), or any of its subsidiaries or its affiliates. The official ZATCA website can be found at https://zatca.gov.sa.

Documentation

WIP

Features

Everything done by the official ZATCA SDK

  • CSR Generation
  • Invoice Signing (All invoice types)
  • Validation (UBL only for now)
  • QR Generation
  • API Requests

But we do it faster and better e.g. ~190x faster invoice hashing than ZATCA's SDK (see bench/)

Dependencies

XML parsing/manipulation is done internally with libxml2, so you might need to install it if you haven't already see here for relevant instructions.

Usage/Examples

CSR Generation

Rust

use fatoora_core::config::EnvironmentType;
use fatoora_core::csr::CsrProperties;

let props = CsrProperties::parse_csr_config("csr.properties".as_ref())?;
let (csr, key) = props.build_with_rng(EnvironmentType::NonProduction)?;
let csr_pem = csr.to_pem(Default::default())?;
let key_pem = key.to_pkcs8_pem(Default::default())?;

CLI

fatoora-rs-cli csr --csr-config csr.properties --generated-csr csr.pem --private-key key.pem --pem
Invoice Signing

Rust

use fatoora_core::invoice::sign::InvoiceSigner;

let cert_pem = std::fs::read_to_string("cert.pem")?;
let key_pem = std::fs::read_to_string("key.pem")?;
let signer = InvoiceSigner::from_pem(cert_pem.trim(), key_pem.trim())?;
let xml = std::fs::read_to_string("invoice.xml")?;
let signed_xml = signer.sign_xml(&xml)?;

CLI

fatoora-rs-cli sign --invoice invoice.xml --cert cert.pem --key key.pem --signed-invoice signed.xml
Validation

Rust

use fatoora_core::config::Config;
use fatoora_core::invoice::validation::validate_xml_invoice_from_file;

let config = Config::new(fatoora_core::config::EnvironmentType::NonProduction);
validate_xml_invoice_from_file("invoice.xml".as_ref(), &config)?;

CLI

fatoora-rs-cli validate --invoice invoice.xml --xsd-path assets/schemas/UBL2.1/xsd/maindoc/UBL-Invoice-2.1.xsd
QR Extraction

Rust

use fatoora_core::invoice::xml::parse::parse_signed_invoice_xml;

let xml = std::fs::read_to_string("signed.xml")?;
let signed = parse_signed_invoice_xml(&xml)?;
let qr = signed.qr_code();

CLI

fatoora-rs-cli qr --invoice signed.xml
Invoice Hash

Rust

use fatoora_core::invoice::sign::invoice_hash_base64;
use libxml::parser::Parser;

let xml = std::fs::read_to_string("invoice.xml")?;
let doc = Parser::default().parse_string(&xml)?;
let hash = invoice_hash_base64(&doc)?;

CLI

fatoora-rs-cli generate-hash --invoice invoice.xml
Invoice Request Payload

Rust

use fatoora_core::invoice::xml::parse::parse_signed_invoice_xml;

let xml = std::fs::read_to_string("signed.xml")?;
let signed = parse_signed_invoice_xml(&xml)?;
let payload = serde_json::json!({
    "invoiceHash": signed.invoice_hash(),
    "uuid": signed.uuid(),
    "invoice": signed.to_xml_base64(),
});

CLI

fatoora-rs-cli invoice-request --invoice signed.xml --api-request request.json

Contributing

Contributions are always welcome!

  • Open issues for discussion before implementing any big features
  • Add relevant tests and make sure there are no formatting issues

Network tests

Live API tests run by default with the rest of the test suite. Set SKIP_ZATCA_LIVE_API=1 to disable them locally or in CI.

Roadmap

  • Increase test coverage to 100% (Inshallah)
  • Add the full validation suite (not only UBL schema)
  • Expand bindings to other languages (subject to demand)
  • PDF invoice generation

Relevant Links

Commit count: 62

cargo fmt