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 🙏

© 2025 – Pkg Stats / Ryan Hefner

zatca-phase2

v1.0.0

Published

ZATCA Phase 2 e-invoicing integration for Node.js

Readme

ZATCA Phase 2 Integration for Node.js

A comprehensive library for integrating with the ZATCA (Zakat, Tax and Customs Authority) Phase 2 e-invoicing system in Saudi Arabia.

Features

  • Certificate generation and management
  • XML generation compliant with ZATCA standards
  • QR code generation for invoices
  • Digital signing of invoices
  • Integration with ZATCA APIs (compliance, reporting, clearance)
  • Invoice status verification
  • Credit note generation

Installation

npm install zatca-phase2

Configuration

Create a configuration file or use environment variables:

ZATCA_ORG_NAME=Your Company Name
ZATCA_TAX_NUMBER=Your VAT Registration Number
ZATCA_PRODUCTION=false
ZATCA_PIH=Your Production Integration Handler
LOG_LEVEL=info

Quick Start

const zatca = require('zatca-phase2');

// Generate CSR
async function generateCSR() {
  const organization = {
    name: 'Your Company Name',
    city: 'Riyadh',
    region: 'Riyadh Region',
    email: '[email protected]'
  };
  
  const certInfo = await zatca.generateCSR(organization);
  console.log('CSR generated:', certInfo.csr);
  return certInfo;
}

// Submit invoice
async function submitInvoice(certificateId) {
  const invoice = {
    invoiceNumber: 'INV-123',
    issueDate: new Date(),
    supplierName: 'Your Company',
    supplierTaxNumber: '123456789012345',
    customerName: 'Customer',
    customerTaxNumber: '987654321098765',
    totalAmount: 115.00,
    vatAmount: 15.00,
    items: [
      {
        name: 'Product',
        quantity: 1,
        unitPrice: 100.00,
        taxRate: 15,
        taxAmount: 15.00,
        totalAmount: 115.00
      }
    ]
  };
  
  const certInfo = {
    certificateId: certificateId,
    type: 'compliance',
    token: 'your-auth-token'
  };
  
  const response = await zatca.submitInvoice(invoice, certInfo);
  console.log('Invoice submitted:', response);
}

// Generate QR code
async function generateQRCode(invoice) {
  const qrCode = await zatca.generateQRCode(invoice);
  console.log('QR code generated:', qrCode);
  return qrCode;
}

Complete Integration Flow

The typical integration flow with ZATCA consists of the following steps:

  1. Onboarding:

    • Generate CSR (Certificate Signing Request)
    • Submit CSR to ZATCA compliance API
    • Receive CSID via email
    • Verify certificate with CSID
    • Store compliance certificate
  2. Invoice Processing:

    • Create invoice data
    • Generate invoice XML
    • Sign XML using compliance certificate
    • Submit for clearance (invoices ≥ 1000 SAR) or reporting (invoices < 1000 SAR)
    • Process ZATCA response
    • Generate QR code for the invoice
  3. Post-Processing:

    • Check invoice status
    • Create credit notes if needed

API Documentation

Certificate Management

  • zatca.certificate.generateCSR(organization) - Generate a Certificate Signing Request
  • zatca.certificate.storeCertificate(certificateId, certificate, type) - Store a certificate
  • zatca.certificate.loadCertificate(certificateId, type) - Load a certificate

API Integration

  • zatca.api.requestComplianceCertificate(csrContent) - Request compliance certificate
  • zatca.api.verifyCertificate(requestId, csid) - Verify certificate with CSID
  • zatca.api.clearInvoice(invoice, signedXml, certificate) - Clear an invoice
  • zatca.api.reportInvoice(invoice, signedXml, certificate) - Report an invoice
  • zatca.api.checkInvoiceStatus(requestId) - Check invoice status

XML Generation

  • zatca.xml.generateInvoiceXml(invoice) - Generate XML for an invoice
  • zatca.xml.generateCreditNoteXml(creditNote, originalInvoice, reason) - Generate XML for a credit note
  • zatca.xml.calculateInvoiceHash(xml) - Calculate hash for an invoice XML

Signing

  • zatca.signing.signInvoice(invoice, invoiceXml, certInfo) - Sign an invoice XML
  • zatca.signing.calculateInvoiceHash(invoice, invoiceXml) - Calculate hash for an invoice

QR Code

  • zatca.qrcode.generateQRCode(invoice) - Generate QR code for an invoice

Invoice Processing

  • zatca.invoice.submitInvoice(invoice, certInfo) - Process and submit an invoice to ZATCA
  • zatca.invoice.checkInvoiceStatus(invoice) - Check status of a submitted invoice
  • zatca.invoice.createCreditNote(originalInvoice, reason, certInfo) - Create a credit note for an invoice

Project Structure

zatca-phase2/
├── lib/                          # Core library code
│   ├── api/                      # API integration
│   │   ├── client.js             # HTTP client implementation
│   │   ├── compliance.js         # Compliance API methods
│   │   ├── reporting.js          # Reporting API methods
│   │   ├── clearance.js          # Clearance API methods
│   │   └── index.js              # API module exports
│   ├── certificate/              # Certificate management
│   │   ├── generate.js           # CSR generation
│   │   ├── store.js              # Certificate storage
│   │   └── index.js              # Certificate module exports
│   ├── invoice/                  # Invoice processing
│   │   ├── submit.js             # Invoice submission
│   │   ├── status.js             # Status checking
│   │   ├── credit-note.js        # Credit note generation
│   │   └── index.js              # Invoice module exports
│   ├── qrcode/                   # QR code generation
│   │   ├── generate.js           # QR code generation
│   │   ├── tlv.js                # TLV data formatting
│   │   └── index.js              # QR code module exports
│   ├── signing/                  # XML signing
│   │   ├── sign.js               # XML signing implementation
│   │   ├── hash.js               # Hash calculation
│   │   └── index.js              # Signing module exports
│   ├── xml/                      # XML generation
│   │   ├── invoice.js            # Invoice XML generation
│   │   ├── credit-note.js        # Credit note XML generation
│   │   └── index.js              # XML module exports
│   ├── utils/                    # Utility functions
│   │   ├── date.js               # Date formatting utilities
│   │   ├── validation.js         # Data validation
│   │   ├── logger.js             # Logging utilities
│   │   └── index.js              # Utils module exports
│   ├── errors/                   # Error handling
│   │   ├── zatca-error.js        # Custom error classes
│   │   └── index.js              # Errors module exports
│   └── index.js                  # Main library entry point
├── config/                       # Configuration
│   └── default.js                # Default configuration
├── examples/                     # Example usage scripts
│   ├── generate-certificate.js   # Certificate generation example
│   ├── verify-certificate.js     # Certificate verification example
│   ├── submit-invoice.js         # Invoice submission example
│   ├── check-invoice-status.js   # Status checking example
│   └── create-credit-note.js     # Credit note example
├── test/                         # Test suite
│   ├── unit/                     # Unit tests
│   │   ├── api.test.js           # API tests
│   │   ├── certificate.test.js   # Certificate tests
│   │   └── xml.test.js           # XML tests
│   └── setup.js                  # Test setup
├── scripts/                      # Build scripts
│   └── build.js                  # Build script
├── LICENSE                       # MIT License
├── README.md                     # Documentation
├── package.json                  # Package manifest
├── .eslintrc.js                  # ESLint configuration
├── jsdoc.json                    # JSDoc configuration
└── .gitignore                    # Git ignore file

Error Handling

The library uses custom ZatcaError class for error handling:

try {
  await zatca.submitInvoice(invoice, certInfo);
} catch (error) {
  if (error.name === 'ZatcaError') {
    console.error(`Error code: ${error.code}`);
    console.error(`Error message: ${error.message}`);
    console.error(`Error details:`, error.details);
  } else {
    console.error('Unexpected error:', error);
  }
}

Examples

Certificate Generation

const zatca = require('zatca-phase2');
const fs = require('fs').promises;

async function onboarding() {
  try {
    // Generate CSR
    const certInfo = await zatca.certificate.generateCSR({
      name: 'Your Company Name',
      city: 'Riyadh',
      region: 'Riyadh Region',
      email: '[email protected]'
    });
    
    console.log('CSR generated with ID:', certInfo.certificateId);
    console.log('CSR content:', certInfo.csr);
    
    // Request compliance certificate
    const response = await zatca.api.requestComplianceCertificate(certInfo.csr);
    console.log('Request ID:', response.requestID);
    
    // Save request ID for later verification
    await fs.writeFile('request-id.txt', response.requestID);
    
    console.log('Please check your email for CSID and run the verification step');
  } catch (error) {
    console.error('Onboarding failed:', error);
  }
}

async function verifyCertificate() {
  try {
    // Read saved request ID
    const requestId = await fs.readFile('request-id.txt', 'utf8');
    
    // Get CSID from user
    const csid = process.argv[2];
    if (!csid) {
      console.error('Please provide CSID as argument');
      process.exit(1);
    }
    
    // Get certificate ID
    const certificateId = process.argv[3];
    if (!certificateId) {
      console.error('Please provide certificate ID as argument');
      process.exit(1);
    }
    
    // Verify certificate
    const response = await zatca.api.verifyCertificate(requestId, csid);
    
    // Store certificate
    await zatca.certificate.storeCertificate(
      certificateId,
      response.certificate,
      'compliance'
    );
    
    console.log('Certificate verified and stored successfully!');
  } catch (error) {
    console.error('Verification failed:', error);
  }
}

Invoice Submission

const zatca = require('zatca-phase2');
const fs = require('fs').promises;

async function submitInvoice() {
   try {
      // Prepare invoice data
      const invoice = {
         invoiceNumber: `INV-${Date.now()}`,
         issueDate: new Date(),
         supplierName: 'Your Company',
         supplierTaxNumber: '123456789012345',
         customerName: 'Customer XYZ',
         customerTaxNumber: '987654321098765',
         totalAmount: 1150.00,
         vatAmount: 150.00,
         items: [
            {
               name: 'Product A',
               quantity: 1,
               unitPrice: 1000.00,
               taxRate: 15,
               taxAmount: 150.00,
               totalAmount: 1150.00
            }
         ]
      };

      // Get certificate ID
      const certificateId = process.argv[2];
      if (!certificateId) {
         console.error('Please provide certificate ID as argument');
         process.exit(1);
      }

      // Certificate info
      const certInfo = {
         certificateId: certificateId,
         type: 'compliance',
         token: 'your-auth-token'
      };

      // Submit invoice
      const response = await zatca.submitInvoice(invoice, certInfo);

      console.log('Invoice submitted successfully!');
      console.log('Request ID:', response.requestID);

      // Generate QR code
      const qrCode = await zatca.generateQRCode(invoice);
      console.log('QR code generated:', qrCode.substring(0, 50) + '...');

      // Save request ID for later status check
      await fs.writeFile('invoice-request-id.txt', response.requestID);
   } catch (error) {
      console.error('Invoice submission failed:', error);
   }
}

async function checkInvoiceStatus() {
   try {
      // Read saved request ID
      const requestId = await fs.readFile('invoice-request-id.txt', 'utf8');

      // Create invoice object with zatcaResponse
      const invoice = {
         zatcaResponse: { requestID: requestId }
      };

      // Check status
      const statusResponse = await zatca.invoice.checkInvoiceStatus(invoice);

      console.log('Invoice status:', statusResponse.status);
      console.log('Full response:', statusResponse);
   } catch (error) {
      console.error('Status check failed:', error);
   }
}

ZATCA Compliance Requirements

This library implements the technical requirements specified in the ZATCA e-invoicing Phase 2 documentation, including:

  1. Generation of compliant e-invoices in XML format
  2. Digital signing of invoices
  3. QR code generation for simplified invoices
  4. Integration with ZATCA's APIs:
    • Compliance (onboarding)
    • Clearance (for invoices ≥ 1000 SAR)
    • Reporting (for invoices < 1000 SAR)

License

MIT