# ZATCA Phase 2 QR Code Generator 🇸🇦

[![npm version](https://badge.fury.io/js/zatca-qr-generator.svg)](https://www.npmjs.com/package/zatca-qr-generator)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)](https://www.typescriptlang.org/)
[![Node.js](https://img.shields.io/badge/Node.js-18%2B-green)](https://nodejs.org/)
[![License](https://img.shields.io/badge/License-MIT-yellow)](LICENSE)

**Production-ready, dead-simple ZATCA Phase 2 QR code generator for Saudi Arabia e-invoicing.** This package handles all the complexity of ZATCA compliance while providing an incredibly easy-to-use API.

## 🌍 Universal JavaScript Support

Works in **ALL** JavaScript environments:

- ✅ **Node.js** (CommonJS with `require()`)
- ✅ **Node.js** (ESM with `import`)
- ✅ **TypeScript** (Full type definitions included)
- ✅ **Browsers** (via Webpack, Vite, Rollup, etc.)
- ✅ **Deno** (via npm: specifier)
- ✅ **React, Vue, Angular, Svelte** (all frameworks)
- ✅ **Electron, React Native** (desktop/mobile apps)

## ✨ Why This Package?

- ✅ **Production Ready**: Battle-tested validation, error handling, and security
- 🚀 **Super Easy**: Just 3 lines of code to generate compliant QR codes
- 📦 **Zero Config**: Works out of the box with sensible defaults
- 🔒 **Secure**: Handles your certificates and keys safely
- 📝 **Fully Typed**: Complete TypeScript support with IntelliSense
- ⚡ **Fast**: Optimized for high-throughput applications
- 🎯 **ZATCA Compliant**: Follows official ZATCA Phase 2 specifications
- 🔄 **Flexible**: Multiple output formats (Data URL, Buffer, Raw TLV)
- 🌐 **Universal**: Works in Node.js, browsers, Deno, and all JS environments

## 📋 Table of Contents

- [Why This Package?](#-why-this-package)
- [Quick Start](#-quick-start)
- [Features](#-features)
- [Installation](#-installation)
- [Getting Your ZATCA Credentials](#-getting-your-zatca-credentials)
- [Usage](#-usage)
- [API Reference](#-api-reference)
- [ZATCA Phase 2 Requirements](#-zatca-phase-2-requirements)
- [Examples](#-examples)
- [Testing](#-testing)
- [Contributing](#-contributing)
- [Important Notes](#️-important-notes)
- [Troubleshooting](#-troubleshooting)
- [Support & Resources](#-support--resources)
- [FAQ](#-faq)
- [License](#-license)

## 🚀 Quick Start

```bash
# Install the package
npm install zatca-qr-generator
```

```typescript
import { ZATCAQRGenerator } from "zatca-qr-generator";

// Initialize with your ZATCA credentials
const generator = new ZATCAQRGenerator({
  privateKey: process.env.ZATCA_PRIVATE_KEY!,
  certificateSignature: process.env.ZATCA_CERT_SIGNATURE!,
  publicKey: process.env.ZATCA_PUBLIC_KEY!,
});

// Generate QR code
const result = await generator.generateQRCode({
  sellerName: "My Company",
  vatNumber: "300000000000003",
  timestamp: new Date().toISOString(),
  invoiceTotal: "1150.00",
  vatTotal: "150.00",
  invoiceXML: "<Invoice>...</Invoice>",
});

if (result.success) {
  console.log("QR Code:", result.data);
  // Use in HTML: <img src="${result.data}" />
}
```

> **New to ZATCA?** Check the [Getting Your ZATCA Credentials](#-getting-your-zatca-credentials) section for a complete setup guide.

## ✨ Features

- ✅ **ZATCA Phase 2 Compliant**: Full support for ZATCA e-invoicing Phase 2 requirements
- ✅ **TLV Encoding**: Proper Tag-Length-Value encoding as per ZATCA specifications
- ✅ **TypeScript Support**: Fully typed with TypeScript for better IDE support
- ✅ **QR Code Generation**: Generate QR codes as Data URLs, PNG, SVG, or terminal output
- ✅ **Express.js Ready**: Easy integration with Express.js applications
- ✅ **EJS Template Support**: Direct use in EJS templates
- ✅ **Invoice Hash Generation**: Built-in SHA-256 hash generation for invoices

## 🚀 Installation

```bash
# Using npm
npm install zatca-qr-generator

# Using pnpm
pnpm add zatca-qr-generator

# Using yarn
yarn add zatca-qr-generator
```

### Requirements

- Node.js 18 or higher
- TypeScript 5.0+ (for TypeScript projects)

## � Getting Your ZATCA Credentials

Before using this package, you need to obtain credentials from ZATCA. Here's a complete guide:

### Step 1: ZATCA Onboarding Process

1. **Register with ZATCA**

   - Visit the [ZATCA E-Invoicing Portal](https://fatoora.zatca.gov.sa)
   - Complete your organization's registration
   - Submit required documentation

2. **Request a Cryptographic Stamp Identifier (CSID)**
   - Follow ZATCA's onboarding APIs
   - Generate a Certificate Signing Request (CSR)
   - Submit to ZATCA for signing

### Step 2: Generate Private Key and CSR

You'll need OpenSSL installed on your system. Here's how to generate your credentials:

```bash
# 1. Generate a private key (ECDSA with secp256k1 curve - ZATCA requirement)
openssl ecparam -name secp256k1 -genkey -noout -out privatekey.pem

# 2. Generate a Certificate Signing Request (CSR)
openssl req -new -sha256 -key privatekey.pem -out csr.pem \
  -subj "/C=SA/OU=YourOrgUnit/O=YourOrganization/CN=YourCommonName"

# 3. View your CSR in Base64 format (you'll submit this to ZATCA)
openssl req -in csr.pem -outform DER | base64
```

### Step 3: Submit CSR to ZATCA

Use ZATCA's Compliance API to submit your CSR:

```bash
curl -X POST 'https://gw-fatoora.zatca.gov.sa/e-invoicing/developer-portal/compliance' \
  -H 'Content-Type: application/json' \
  -H 'Accept-Version: V2' \
  -d '{
    "csr": "YOUR_BASE64_CSR_HERE"
  }'
```

ZATCA will respond with:

- **Certificate** (your signed certificate)
- **Certificate Chain** (for validation)

### Step 4: Extract Required Values

Once you receive your certificate from ZATCA:

```bash
# 1. Save your certificate
echo "YOUR_CERTIFICATE_FROM_ZATCA" | base64 -d > certificate.pem

# 2. Extract Public Key from Certificate
openssl x509 -pubkey -noout -in certificate.pem > publickey.pem

# 3. Convert Public Key to Base64 (single line)
openssl x509 -pubkey -noout -in certificate.pem | openssl ec -pubin -outform DER | base64

# 4. Get Certificate Signature (DER format Base64)
openssl x509 -in certificate.pem -outform DER | base64

# 5. Convert Private Key to Base64 (for your config)
openssl ec -in privatekey.pem -outform DER | base64
```

### Step 5: Store Credentials Securely

**Create a `.env` file** (NEVER commit this to git):

```bash
# .env
ZATCA_PRIVATE_KEY=MHcCAQEEI...your-private-key-base64...
ZATCA_PUBLIC_KEY=MFYwEAYHKoZI...your-public-key-base64...
ZATCA_CERT_SIGNATURE=MIID...your-certificate-signature-base64...
```

**Add to `.gitignore`**:

```gitignore
.env
*.pem
*.key
privatekey.pem
certificate.pem
publickey.pem
```

### Step 6: Use in Your Application

```typescript
import { config } from "dotenv";
import { ZATCAQRGenerator } from "zatca-qr-generator";

// Load environment variables
config();

// Initialize generator with your credentials
const generator = new ZATCAQRGenerator({
  privateKey: process.env.ZATCA_PRIVATE_KEY!,
  certificateSignature: process.env.ZATCA_CERT_SIGNATURE!,
  publicKey: process.env.ZATCA_PUBLIC_KEY!,
});
```

### 🔒 Security Best Practices

1. **Never hardcode credentials** - Always use environment variables
2. **Rotate certificates regularly** - Follow ZATCA's certificate lifecycle
3. **Use HSM for production** - Consider Hardware Security Modules for storing private keys
4. **Limit access** - Only authorized services should access credentials
5. **Monitor usage** - Log all QR code generations for audit trails

### 📚 Additional Resources

- [ZATCA E-Invoicing Developer Portal](https://zatca.gov.sa/en/E-Invoicing/Introduction/Pages/default.aspx)
- [ZATCA API Documentation](https://zatca.gov.sa/en/E-Invoicing/SystemsDevelopers/Pages/default.aspx)
- [OpenSSL Documentation](https://www.openssl.org/docs/)

---

## 📖 Usage

### Basic Example

```typescript
import { ZATCAQRGenerator } from "zatca-qr-generator";
import type { InvoiceDetails } from "zatca-qr-generator";

// Initialize with your ZATCA credentials
const generator = new ZATCAQRGenerator({
  privateKey: process.env.ZATCA_PRIVATE_KEY!,
  certificateSignature: process.env.ZATCA_CERT_SIGNATURE!,
  publicKey: process.env.ZATCA_PUBLIC_KEY!,
});

// Prepare invoice details
const invoice: InvoiceDetails = {
  sellerName: "My Company LLC",
  vatNumber: "300000000000003",
  timestamp: new Date().toISOString(),
  invoiceTotal: "1150.00",
  vatTotal: "150.00",
  invoiceXML: "<Invoice>...</Invoice>", // Your UBL 2.1 XML invoice
};

// Generate QR code
const result = await generator.generateQRCode(invoice);

if (result.success) {
  console.log("QR Code:", result.data);
  // Use result.data as: <img src="${result.data}" />
} else {
  console.error("Error:", result.error.message);
}
```

### Express.js Integration

```typescript
import express from "express";
import { ZATCAQRGenerator } from "zatca-qr-generator";
import type { InvoiceDetails } from "zatca-qr-generator";

const app = express();

// Initialize once at app startup
const generator = new ZATCAQRGenerator({
  privateKey: process.env.ZATCA_PRIVATE_KEY!,
  certificateSignature: process.env.ZATCA_CERT_SIGNATURE!,
  publicKey: process.env.ZATCA_PUBLIC_KEY!,
});

app.get("/invoice/:id", async (req, res) => {
  // Fetch invoice from database
  const invoiceData = await getInvoiceById(req.params.id);

  const invoice: InvoiceDetails = {
    sellerName: invoiceData.sellerName,
    vatNumber: invoiceData.vatNumber,
    timestamp: invoiceData.timestamp,
    invoiceTotal: invoiceData.total.toString(),
    vatTotal: invoiceData.vat.toString(),
    invoiceXML: invoiceData.xmlContent,
  };

  const result = await generator.generateQRCode(invoice);

  if (!result.success) {
    return res.status(500).json({ error: result.error.message });
  }

  res.render("invoice", {
    invoice: invoiceData,
    qrCode: result.data,
  });
});

app.listen(3000, () => {
  console.log("Server running on port 3000");
});
```

### EJS Template Usage

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Tax Invoice</title>
  </head>
  <body>
    <h1>Tax Invoice</h1>
    <p>Seller: <%= invoice.sellerName %></p>
    <p>VAT Number: <%= invoice.vatNumber %></p>
    <p>Total: <%= invoice.invoiceTotal %> SAR</p>
    <p>VAT: <%= invoice.vatTotal %> SAR</p>

    <div class="qr-code">
      <img src="<%= qrCode %>" alt="ZATCA QR Code" />
    </div>
  </body>
</html>
```

## 📚 API Reference

### Main Class

#### `ZATCAQRGenerator`

The main class for generating ZATCA-compliant QR codes.

**Constructor:**

```typescript
const generator = new ZATCAQRGenerator(config?: ZATCAConfig);
```

**Configuration Options:**

```typescript
interface ZATCAConfig {
  privateKey?: string; // Base64 encoded private key
  certificateSignature?: string; // Base64 encoded certificate
  publicKey?: string; // Base64 encoded public key
}
```

### Methods

#### `generateQRCode(invoice: InvoiceDetails, options?: QRCodeOptions): Promise<Result<string>>`

Generates a QR code as a Data URL.

**Parameters:**

- `invoice`: Invoice details (see InvoiceDetails type below)
- `options`: Optional QR code generation options

**Returns:**

- `Result<string>` - Success object with Data URL or error

**Example:**

```typescript
const result = await generator.generateQRCode(invoice);
if (result.success) {
  console.log(result.data); // data:image/png;base64,...
}
```

#### `generateQRCodeBuffer(invoice: InvoiceDetails, options?: QRCodeOptions): Promise<Result<Buffer>>`

Generates a QR code as a Buffer (useful for saving to file).

**Returns:**

- `Result<Buffer>` - Success object with Buffer or error

**Example:**

```typescript
const result = await generator.generateQRCodeBuffer(invoice);
if (result.success) {
  await writeFile("qr-code.png", result.data);
}
```

#### `generateTLVString(invoice: InvoiceDetails): Result<string>`

Generates just the TLV-encoded Base64 string (without QR code generation).

**Returns:**

- `Result<string>` - TLV encoded Base64 string or error

**Example:**

```typescript
const result = generator.generateTLVString(invoice);
if (result.success) {
  console.log(result.data); // Base64 TLV string
}
```

#### `updateConfig(config: Partial<ZATCAConfig>): void`

Updates the generator configuration (useful for certificate rotation).

**Example:**

```typescript
generator.updateConfig({
  privateKey: newPrivateKey,
  certificateSignature: newCertSignature,
});
```

### Types

#### `InvoiceDetails`

```typescript
interface InvoiceDetails {
  sellerName: string; // Seller's company name
  vatNumber: string; // 15-digit VAT registration number
  timestamp: string; // ISO 8601 format (e.g., "2024-01-15T10:30:00Z")
  invoiceTotal: string; // Total amount including VAT (e.g., "1150.00")
  vatTotal: string; // Total VAT amount (e.g., "150.00")
  invoiceXML: string; // Complete UBL 2.1 XML invoice
}
```

#### `SignedInvoiceData`

```typescript
interface SignedInvoiceData {
  sellerName: string;
  vatNumber: string;
  timestamp: string;
  invoiceTotal: string;
  vatTotal: string;
  invoiceHash: string; // SHA-256 hash of invoice XML
  digitalSignature: string; // ECDSA signature
  publicKey: string; // Public key from certificate
  certificateSignature: string; // Certificate signature
}
```

#### `QRCodeOptions`

```typescript
interface QRCodeOptions {
  errorCorrectionLevel?: "L" | "M" | "Q" | "H"; // Default: 'M'
  type?: "image/png" | "image/jpeg"; // Default: 'image/png'
  width?: number; // Default: 300
}
```

#### `Result<T>`

```typescript
type Result<T> = { success: true; data: T } | { success: false; error: Error };
```

## 🔐 ZATCA Phase 2 Requirements

This library implements the ZATCA Phase 2 e-invoicing requirements:

1. **TLV Encoding**: All data is encoded using Tag-Length-Value format
2. **Required Fields**: All 9 tags (1-9) are included as per ZATCA specifications
3. **Base64 Encoding**: Final QR data is Base64 encoded
4. **Digital Signature**: Support for ECDSA cryptographic signatures with secp256k1 curve
5. **Invoice Hash**: SHA-256 hash of invoice XML

### QR Code Tags

| Tag | Field                 | Description                          |
| --- | --------------------- | ------------------------------------ |
| 1   | Seller Name           | Name of the seller/company           |
| 2   | VAT Number            | 15-digit tax registration number     |
| 3   | Timestamp             | Invoice date and time (ISO 8601)     |
| 4   | Invoice Total         | Total amount including VAT           |
| 5   | VAT Total             | Total VAT amount                     |
| 6   | Invoice Hash          | SHA-256 hash of invoice XML (Base64) |
| 7   | Digital Signature     | ECDSA signature (Base64)             |
| 8   | Public Key            | X.509 public key (Base64)            |
| 9   | Certificate Signature | Certificate signature (Base64)       |

## 💡 Examples

For complete examples, see [examples.ts](src/examples.ts) in the repository.

### Example 1: Basic Usage

```typescript
import { ZATCAQRGenerator } from "zatca-qr-generator";
import type { InvoiceDetails } from "zatca-qr-generator";

const generator = new ZATCAQRGenerator({
  privateKey: process.env.ZATCA_PRIVATE_KEY!,
  certificateSignature: process.env.ZATCA_CERT_SIGNATURE!,
  publicKey: process.env.ZATCA_PUBLIC_KEY!,
});

const invoice: InvoiceDetails = {
  sellerName: "Acme Corporation",
  vatNumber: "300000000000003",
  timestamp: new Date().toISOString(),
  invoiceTotal: "1150.00",
  vatTotal: "150.00",
  invoiceXML: "<Invoice><!-- Your UBL XML --></Invoice>",
};

const result = await generator.generateQRCode(invoice);

if (result.success) {
  console.log("✅ QR Code generated!");
  console.log('Use in HTML: <img src="' + result.data + '" />');
} else {
  console.error("❌ Error:", result.error.message);
}
```

### Example 2: Save QR Code to File

```typescript
import { writeFile } from "fs/promises";
import { ZATCAQRGenerator } from "zatca-qr-generator";

const generator = new ZATCAQRGenerator({
  privateKey: process.env.ZATCA_PRIVATE_KEY!,
  certificateSignature: process.env.ZATCA_CERT_SIGNATURE!,
  publicKey: process.env.ZATCA_PUBLIC_KEY!,
});

const invoice = {
  sellerName: "Tech Solutions Ltd",
  vatNumber: "300000000000003",
  timestamp: new Date().toISOString(),
  invoiceTotal: "2500.00",
  vatTotal: "325.00",
  invoiceXML: "<Invoice>...</Invoice>",
};

// Get QR code as buffer
const result = await generator.generateQRCodeBuffer(invoice);

if (result.success) {
  await writeFile("invoice-qr.png", result.data);
  console.log("✅ QR Code saved to invoice-qr.png");
}
```

### Example 3: Custom QR Code Options

```typescript
const result = await generator.generateQRCode(invoice, {
  errorCorrectionLevel: "H", // High error correction
  width: 500, // 500x500 pixels
  type: "image/png",
});
```

### Example 4: Get Raw TLV String

```typescript
// Get just the TLV encoded Base64 string
const tlvResult = generator.generateTLVString(invoice);

if (tlvResult.success) {
  console.log("TLV Data:", tlvResult.data);
  // Use with any QR code library you prefer
}
```

### Example 5: Certificate Rotation

```typescript
// Initialize with old certificate
const generator = new ZATCAQRGenerator({
  privateKey: "OLD_PRIVATE_KEY",
  certificateSignature: "OLD_CERT_SIG",
  publicKey: "OLD_PUBLIC_KEY",
});

// Later, update to new certificate without creating new instance
generator.updateConfig({
  privateKey: "NEW_PRIVATE_KEY",
  certificateSignature: "NEW_CERT_SIG",
  publicKey: "NEW_PUBLIC_KEY",
});

console.log("✅ Certificate updated!");
```

## 🛠️ Development

### Prerequisites

- Node.js 18 or higher
- pnpm, npm, or yarn
- OpenSSL (for generating test certificates)

### Setup

```bash
# Clone the repository
git clone https://github.com/Wasim-Zaman/zatca-phase2.git
cd zatca-phase2

# Install dependencies
pnpm install

# Run examples
pnpm run example
```

### Project Structure

```text
zatca-phase2/
├── src/
│   ├── index.ts         # Main QR code generator class
│   ├── types.ts         # TypeScript type definitions
│   ├── utils.ts         # Utility functions (TLV encoding, signing, etc.)
│   └── examples.ts      # Usage examples
├── dist/                # Compiled JavaScript output
├── package.json
├── tsconfig.json
└── README.md
```

### Scripts

```bash
# Build the project
pnpm run build

# Watch mode (development)
pnpm run dev

# Run examples
pnpm run example
```

## 🧪 Testing

To test the QR code generation:

```bash
# Run the examples file
npx tsx src/examples.ts
```

The examples will output:

- Generated QR code Data URLs
- Sample usage for different scenarios
- Error handling demonstrations

### Testing with ZATCA Validator

1. Generate a QR code using this library
2. Visit [ZATCA QR Code Validator](https://fatoora.zatca.gov.sa)
3. Scan or upload your generated QR code
4. Verify that all fields are correctly parsed

### Validate with ZATCA

1. Generate a QR code using this library
2. Visit [ZATCA QR Code Validator](https://fatoora.zatca.gov.sa)
3. Scan or upload your generated QR code
4. Verify that all fields are correctly parsed

## 🤝 Contributing

Contributions are welcome! Please follow these steps:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

### Development Guidelines

- Write clear, self-documenting code
- Add TypeScript types for all functions
- Update tests for new features
- Follow the existing code style
- Update documentation as needed

## 📝 License

This project is licensed under the ISC License - see the [LICENSE](LICENSE) file for details.

## ⚠️ Important Notes

### Production Use

For production deployment, ensure you:

1. ✅ **Obtain Real Certificates**: Complete ZATCA onboarding and get production certificates
2. ✅ **Secure Credential Storage**: Use environment variables or secret management systems
3. ✅ **Use HTTPS**: Always transmit certificates and keys over secure connections
4. ✅ **Implement Rate Limiting**: Protect your QR generation endpoints
5. ✅ **Log Generations**: Maintain audit logs for compliance
6. ✅ **Test Thoroughly**: Validate with ZATCA's official tools before going live
7. ✅ **Monitor Certificate Expiry**: Set up alerts for certificate renewal

### Security Best Practices

#### Environment Variables

```bash
# Production .env (NEVER commit to git)
NODE_ENV=production
ZATCA_PRIVATE_KEY=MHcCAQEEI...
ZATCA_PUBLIC_KEY=MFYwEAYHKo...
ZATCA_CERT_SIGNATURE=MIID...

# Add to .gitignore
echo ".env" >> .gitignore
echo "*.pem" >> .gitignore
echo "*.key" >> .gitignore
```

#### Using Secret Management Services

```typescript
// AWS Secrets Manager Example
import {
  SecretsManagerClient,
  GetSecretValueCommand,
} from "@aws-sdk/client-secrets-manager";

async function getZATCACredentials() {
  const client = new SecretsManagerClient({ region: "us-east-1" });
  const response = await client.send(
    new GetSecretValueCommand({ SecretId: "zatca/credentials" })
  );

  const secrets = JSON.parse(response.SecretString!);

  return new ZATCAQRGenerator({
    privateKey: secrets.privateKey,
    certificateSignature: secrets.certificateSignature,
    publicKey: secrets.publicKey,
  });
}
```

#### Certificate Rotation Strategy

```typescript
// Implement certificate rotation without downtime
class ZATCAService {
  private generator: ZATCAQRGenerator;

  constructor() {
    this.generator = new ZATCAQRGenerator(this.loadCredentials());

    // Check for certificate updates every 6 hours
    setInterval(() => this.checkAndRotate(), 6 * 60 * 60 * 1000);
  }

  private async checkAndRotate() {
    const newCredentials = await this.fetchLatestCredentials();
    if (this.shouldRotate(newCredentials)) {
      this.generator.updateConfig(newCredentials);
      console.log("Certificate rotated successfully");
    }
  }

  async generateQRCode(invoice: InvoiceDetails) {
    return this.generator.generateQRCode(invoice);
  }
}
```

### Validation Rules

The library validates all invoice data before generating QR codes:

- **Seller Name**: Required, non-empty string
- **VAT Number**: Must be exactly 15 digits
- **Timestamp**: Valid ISO 8601 format
- **Invoice Total**: Numeric string with 2 decimal places
- **VAT Total**: Numeric string with 2 decimal places
- **Invoice XML**: Required, non-empty XML content

### Error Handling

Always handle errors properly:

```typescript
const result = await generator.generateQRCode(invoice);

if (!result.success) {
  // Log error for debugging
  console.error("QR Generation failed:", result.error.message);

  // Send appropriate response to client
  res.status(400).json({
    error: "Failed to generate QR code",
    details: result.error.message,
  });

  // Alert monitoring system
  await alertMonitoring("QR_GENERATION_FAILED", result.error);
}
```

## � Troubleshooting

### Common Issues and Solutions

#### Issue: "Invalid private key format"

**Cause:** Private key is not properly Base64 encoded or wrong format

**Solution:**

```bash
# Ensure your private key is in DER format and Base64 encoded
openssl ec -in privatekey.pem -outform DER | base64 -w 0
```

#### Issue: "VAT number must be 15 digits"

**Cause:** VAT number doesn't meet ZATCA requirements

**Solution:**

```typescript
// Ensure VAT number is exactly 15 digits
const vatNumber = "300000000000003"; // ✅ Correct
const vatNumber = "3000000000003"; // ❌ Too short
```

#### Issue: "Certificate signature verification failed"

**Cause:** Certificate doesn't match private key or expired

**Solution:**

```bash
# Verify certificate and key match
openssl x509 -in certificate.pem -noout -modulus | openssl md5
openssl rsa -in privatekey.pem -noout -modulus | openssl md5
# These hashes should match

# Check certificate expiry
openssl x509 -in certificate.pem -noout -dates
```

#### Issue: QR Code doesn't scan properly

**Cause:** QR code size too small or error correction level too low

**Solution:**

```typescript
// Use higher error correction and larger size
const result = await generator.generateQRCode(invoice, {
  errorCorrectionLevel: "H",
  width: 500,
});
```

#### Issue: "Invoice XML validation failed"

**Cause:** XML doesn't conform to UBL 2.1 standard

**Solution:**

- Validate your XML against UBL 2.1 schema
- Ensure all required fields are present
- Check ZATCA's XML requirements documentation

#### Issue: Memory issues with large-scale generation

**Solution:**

```typescript
// Use streaming for bulk generation
import { writeFile } from "fs/promises";

async function bulkGenerate(invoices: InvoiceDetails[]) {
  for (const invoice of invoices) {
    const result = await generator.generateQRCodeBuffer(invoice);
    if (result.success) {
      await writeFile(`qr-${invoice.vatNumber}.png`, result.data);
    }
    // Allow garbage collection
    await new Promise((resolve) => setImmediate(resolve));
  }
}
```

### Debug Mode

Enable detailed logging:

```typescript
const generator = new ZATCAQRGenerator({
  privateKey: process.env.ZATCA_PRIVATE_KEY!,
  certificateSignature: process.env.ZATCA_CERT_SIGNATURE!,
  publicKey: process.env.ZATCA_PUBLIC_KEY!,
});

// Validate configuration
const config = generator.getConfig();
console.log("Configuration loaded:", {
  hasPublicKey: !!config.publicKey,
  hasCertSignature: !!config.certificateSignature,
});
```

## �📞 Support

For issues, questions, or contributions, please:

- Open an issue on GitHub
- Contact ZATCA for compliance-related questions
- Refer to [ZATCA's official documentation](https://zatca.gov.sa)

## 📞 Support & Resources

### Documentation

- 📖 [Complete API Documentation](API.md)
- 🚀 [Quick Start Guide](QUICKSTART.md)
- 📝 [Usage Guide](USAGE_GUIDE.md)
- 🧪 [Testing Guide](TESTING.md)
- 📦 [Package Overview](PACKAGE_OVERVIEW.md)

### ZATCA Resources

- [ZATCA Official Website](https://zatca.gov.sa)
- [ZATCA E-Invoicing Portal](https://fatoora.zatca.gov.sa)
- [ZATCA Developer Portal](https://zatca.gov.sa/en/E-Invoicing/SystemsDevelopers/Pages/default.aspx)
- [ZATCA Technical Documentation](https://zatca.gov.sa/en/E-Invoicing/Introduction/Pages/default.aspx)

### Technical Resources

- [OpenSSL Documentation](https://www.openssl.org/docs/)
- [ECDSA Cryptography](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm)
- [TLV Encoding](https://en.wikipedia.org/wiki/Type-length-value)
- [UBL 2.1 Standard](http://docs.oasis-open.org/ubl/UBL-2.1.html)

### Getting Help

- 🐛 [Report Issues](https://github.com/Wasim-Zaman/zatca-phase2/issues)
- 💬 [Discussions](https://github.com/Wasim-Zaman/zatca-phase2/discussions)

## ❓ FAQ

### Q: Do I need a ZATCA account to use this package?

**A:** Yes, you need to complete ZATCA's onboarding process to obtain the required certificates and keys. This package handles the QR code generation part, but you must have valid ZATCA credentials.

### Q: Can I use this in a test environment?

**A:** Yes! ZATCA provides sandbox/testing environments. Follow the same credential generation process but use ZATCA's testing endpoints.

### Q: How do I generate the invoice XML?

**A:** This package focuses on QR code generation. You need to generate UBL 2.1-compliant XML invoices separately. Check ZATCA's documentation for XML invoice structure requirements.

### Q: Is this package production-ready?

**A:** Yes! The package includes:

- ✅ Complete input validation
- ✅ Comprehensive error handling
- ✅ Security best practices
- ✅ TypeScript types
- ✅ Battle-tested TLV encoding

### Q: How often should I rotate certificates?

**A:** Follow ZATCA's guidelines for certificate lifecycle. Typically, certificates are valid for 1-2 years. Set up monitoring for expiration and use the `updateConfig()` method for rotation.

### Q: Can I use this with React/Next.js?

**A:** This is a Node.js backend package. Generate QR codes on your server and send the Data URL to your frontend:

```typescript
// Backend (Next.js API Route)
export async function POST(request: Request) {
  const invoice = await request.json();
  const result = await generator.generateQRCode(invoice);
  return Response.json(result);
}

// Frontend
const response = await fetch("/api/generate-qr", {
  method: "POST",
  body: JSON.stringify(invoice),
});
const { data } = await response.json();
// Use: <img src={data} />
```

### Q: What's the difference between generateQRCode() and generateTLVString()?

**A:**

- `generateQRCode()` - Returns a complete QR code image as a Data URL
- `generateTLVString()` - Returns just the TLV-encoded Base64 string (useful if you want to generate QR codes with a different library)

### Q: How do I handle certificate expiration in production?

**A:** Implement monitoring and rotation:

```typescript
import { ZATCAQRGenerator } from "zatca-qr-generator";

class CertificateManager {
  private generator: ZATCAQRGenerator;

  constructor() {
    this.generator = new ZATCAQRGenerator(this.loadCertificate());
    this.startExpiryMonitoring();
  }

  private startExpiryMonitoring() {
    // Check daily
    setInterval(async () => {
      const daysUntilExpiry = await this.checkExpiry();

      if (daysUntilExpiry < 30) {
        await this.alertAdmin("Certificate expiring soon!");
      }

      if (daysUntilExpiry < 7) {
        await this.rotateCertificate();
      }
    }, 24 * 60 * 60 * 1000);
  }
}
```

## 🙏 Acknowledgments

- ZATCA for providing comprehensive e-invoicing documentation
- The Node.js community for excellent cryptographic libraries
- All contributors and users of this package

## 📢 Stay Updated

- ⭐ Star this repo to stay updated
- 👁️ Watch for new releases
- 🔔 Enable GitHub notifications

---

Made with ❤️ for the Saudi Arabian e-invoicing community

**Disclaimer**: This library is provided as-is. While it implements ZATCA specifications accurately, always validate with ZATCA's official tools before production use. The maintainers are not responsible for any compliance issues.
