npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dokhna-tech/zatca

v4.0.0

Published

Saudi Arabia ZATCA Phase 2 e-invoicing core library — XML build, signing, hashing, QR, and ZATCA API client.

Readme

@dokhna-tech/zatca

CI npm license

A TypeScript-first ZATCA Phase 2 e-invoicing library for Saudi Arabia. Build, sign, hash, generate QR codes, and submit invoices to the ZATCA Fatoora system. Supports single-VAT and multi-VAT (multi-tenant SaaS) deployments with a bring-your-own storage adapter pattern.

Status: v2.0.4 — lockstep-versioned across all four packages. See CHANGELOG.md for release notes.

Table of contents

Why this library exists

We tried several existing Node.js ZATCA Phase 2 packages on a real production system. Each had bugs that surfaced only against real ZATCA sandbox/production flows, and each had to be patched. We rewrote the integration from scratch and ran it against real Saudi Arabian invoices for months. This package is the extracted, decoupled, tested result — open-sourced for everyone with a paid commercial track for SaaS providers.

Features

  • Build and sign all six ZATCA Phase 2 invoice types (Simplified / Standard × Tax invoice / Credit note / Debit note).
  • Phase 1 (QR-only) fallback for pre-onboarding.
  • One-shot onboard() orchestrating key generation, CSR, compliance certificate, the six-scenario compliance test pack, and production CSID issuance.
  • Direct ZATCA Compliance, Clearance, and Reporting API clients with retry + structured error normalization.
  • Cancel and status-check APIs.
  • Certificate management helpers (verify, expiration, validity).
  • Pure functional API — no class hierarchy to learn.
  • BYO storage via a small StorageAdapter interface; reference adapters for MongoDB, PostgreSQL, in-memory.
  • Multi-tenant SaaS friendly — per-VAT-number certificate isolation and atomic hash-chain management.
  • Zero logging — the package writes nothing to stdout / stderr / disk. Errors are typed exceptions.

Quickstart

pnpm add @dokhna-tech/zatca @dokhna-tech/zatca-storage-memory
import {
  asCommercialRegistrationNumber,
  asEGSUuid,
  asVATNumber,
  issueSimplifiedTaxInvoice,
  type EGSUnitInfo,
} from "@dokhna-tech/zatca";
import { createMemoryStorageAdapter } from "@dokhna-tech/zatca-storage-memory";

const storage = createMemoryStorageAdapter();
const vatNumber = asVATNumber("301234567890003");
const egsUuid = asEGSUuid("00000000-0000-4000-8000-000000000001");

const egsInfo: EGSUnitInfo = {
  uuid: egsUuid,
  customId: "branch-01-pos-03",
  model: "Acme POS v2",
  crnNumber: asCommercialRegistrationNumber("1010010101"),
  vatName: "Acme Trading Co.",
  vatNumber,
  branchName: "Riyadh HQ",
  branchIndustry: "Retail",
  location: {
    cityName: "Riyadh",
    citySubdivision: "Olaya",
    street: "King Fahd Road",
    plotIdentification: "1234",
    building: "5678",
    postalZone: "12345",
  },
};

const issued = await issueSimplifiedTaxInvoice({
  egsInfo,
  storage,
  scope: { vatNumber, egsUuid },
  signing: {
    certificate: process.env["ZATCA_PRODUCTION_CERTIFICATE"] ?? "",
    privateKey: process.env["ZATCA_PRIVATE_KEY"] ?? "",
  },
  input: {
    kind: "simplified-tax-invoice",
    issueDate: "2026-05-13",
    issueTime: "12:00:00",
    buyerName: "Walk-in customer",
    lineItems: [
      { id: "1", name: "Coffee 250ml", quantity: 2, taxExclusivePrice: 10, vatPercent: 15 },
    ],
  },
});

// issued.signedXml / .invoiceHash / .qrCode / .invoiceNumber / .sequence

To get the certificate + key in the first place, run onboard(). For the full 15-minute path, see docs/getting-started.md.

Packages

| Package | What it is | |---------|------------| | @dokhna-tech/zatca | Core: XML build, signing, QR, ZATCA API client, onboarding | | @dokhna-tech/zatca-server | Standalone multi-tenant ZATCA service (Docker image + HTTP API + encrypted credential vault + audit log) | | @dokhna-tech/zatca-storage-memory | In-memory adapter (testing/dev) | | @dokhna-tech/zatca-storage-mongo | MongoDB adapter (Mongoose peer-dep) | | @dokhna-tech/zatca-storage-postgres | PostgreSQL adapter (pg peer-dep) |

Looking for a turnkey deployment?

Don't want to embed the SDK? @dokhna-tech/zatca-server ships as a Docker image you point at MongoDB or PostgreSQL and an HTTP API your back-office calls. Tenant onboarding, encrypted credential vault, audit log, and /metrics exposition are wired up. See examples/standalone-server/ for a docker-compose + curl walkthrough.

Examples

Four runnable example projects under examples/:

| Example | Demonstrates | |---------|--------------| | standalone-server/ | Recommended — boot @dokhna-tech/zatca-server via docker-compose (Mongo or Postgres) and onboard + issue via curl. | | single-vat-express/ | Express server, one VAT, in-memory storage, full onboarding + issuance flow. | | multi-vat-saas/ | Fastify server, multiple tenants, per-tenant scoping, MongoDB. Use when you want to embed the SDK in your own server instead of running the standalone image. | | byo-storage-prisma/ | Custom StorageAdapter against Prisma + SQLite. |

From the repo root:

pnpm install
pnpm --filter @dokhna-tech-examples/single-vat-express start

Documentation

Regenerate the API reference with pnpm docs:api.

Storage adapters

This package does not lock you into a database. The StorageAdapter interface has five methods (atomic counter increment, previous-hash lookup, record invoice, load invoice, update status). We ship three reference implementations; writing your own takes ~80 lines. See docs/storage-adapters.md.

Multi-VAT / multi-tenant

Pass a TenantScope = { vatNumber, egsUuid } into every storage call. Counters and hash chains are scoped per-tenant. Certificates are passed as parameters, never read from a global. See docs/multi-vat-saas.md.

Requirements

  • Node.js 20+
  • pnpm 9+ (for monorepo development)
  • OpenSSL CLI installed in the runtime environment (used for CSR generation during EGS onboarding). See troubleshooting.md for Lambda / Alpine recipes.
  • TypeScript 5.6+ for consumers

License

This package is dual-licensed:

  • Free for non-SaaS use under the Business Source License 1.1. On 2030-05-13 (four years from the first release), the license automatically converts to Apache License 2.0.
  • Commercial license required for SaaS / multi-tenant production use. See LICENSES/COMMERCIAL.md.

If you are unsure which applies to your use case, read the LICENSE file's "Additional Use Grant" section or contact [email protected].

The BSL model is used by MariaDB, Sentry, CockroachDB, and Couchbase. It is a source-available license, not an OSI-approved open-source license, until the Change Date.

Contributing

See CONTRIBUTING.md. Security issues: see SECURITY.md.