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

@fin.cx/xinvoice

v4.2.2

Published

A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for xinvoice packages.

Downloads

13

Readme

@fin.cx/xinvoice

A comprehensive TypeScript library for creating, manipulating, and embedding XML invoice data within PDF files, supporting multiple European electronic invoice standards including ZUGFeRD (v1 & v2), Factur-X, XRechnung, UBL, and FatturaPA.

Features

  • Multi-format support: Process invoices in ZUGFeRD (v1 & v2), Factur-X, XRechnung, UBL, and FatturaPA
  • PDF handling: Extract XML from PDF/A-3 invoices and embed XML into PDFs with robust error handling
  • Validation: Validate invoices against format-specific rules with detailed error reporting
  • Conversion: Convert between different invoice formats
  • TypeScript: Fully typed API with TypeScript definitions
  • Modular architecture: Extensible design with specialized components
  • Robust error handling: Detailed error information and graceful fallbacks

Install

To install @fin.cx/xinvoice, you'll need a package manager. We recommend using pnpm:

# Using pnpm (recommended)
pnpm add @fin.cx/xinvoice

# Using npm
npm install @fin.cx/xinvoice

# Using yarn
yarn add @fin.cx/xinvoice

Usage

The @fin.cx/xinvoice module streamlines the management of electronic invoices, handling the creation, manipulation, and embedding of structured invoice data in PDF files. Below are examples of common use cases.

Basic Usage

import { XInvoice } from '@fin.cx/xinvoice';
import { promises as fs } from 'fs';

// Create a new invoice
const invoice = new XInvoice();
invoice.id = 'INV-2023-001';
invoice.from = {
  name: 'Supplier Company',
  type: 'company',
  address: {
    streetName: 'Main Street',
    houseNumber: '123',
    city: 'Berlin',
    postalCode: '10115',
    country: 'Germany',
    countryCode: 'DE'
  },
  registrationDetails: {
    vatId: 'DE123456789',
    registrationId: 'HRB 123456'
  }
};
invoice.to = {
  name: 'Customer Company',
  type: 'company',
  address: {
    streetName: 'Customer Street',
    houseNumber: '456',
    city: 'Paris',
    postalCode: '75001',
    country: 'France',
    countryCode: 'FR'
  },
  registrationDetails: {
    vatId: 'FR87654321',
    registrationId: 'RCS 654321'
  }
};

// Add payment options
invoice.paymentOptions = {
  info: 'Please transfer to our bank account',
  sepaConnection: {
    iban: 'DE89370400440532013000',
    bic: 'COBADEFFXXX'
  }
};

// Add invoice items
invoice.items = [
  {
    position: 1,
    name: 'Product A',
    articleNumber: 'PROD-001',
    unitQuantity: 2,
    unitNetPrice: 100,
    vatPercentage: 19,
    unitType: 'EA'
  },
  {
    position: 2,
    name: 'Service B',
    articleNumber: 'SERV-001',
    unitQuantity: 1,
    unitNetPrice: 200,
    vatPercentage: 19,
    unitType: 'EA'
  }
];

// Export to XML
const xml = await invoice.exportXml('zugferd');

// Load from XML
const loadedInvoice = await XInvoice.fromXml(xml);

// Load from PDF
const pdfBuffer = await fs.readFile('invoice.pdf');
const invoiceFromPdf = await XInvoice.fromPdf(pdfBuffer);

// Export to PDF with embedded XML
const pdfWithXml = await invoice.exportPdf('facturx');
await fs.writeFile('invoice-with-xml.pdf', pdfWithXml.buffer);

Working with Different Invoice Formats

// Load a ZUGFeRD invoice
const zugferdXml = await fs.readFile('zugferd-invoice.xml', 'utf8');
const zugferdInvoice = await XInvoice.fromXml(zugferdXml);

// Load a Factur-X invoice
const facturxXml = await fs.readFile('facturx-invoice.xml', 'utf8');
const facturxInvoice = await XInvoice.fromXml(facturxXml);

// Load an XRechnung invoice
const xrechnungXml = await fs.readFile('xrechnung-invoice.xml', 'utf8');
const xrechnungInvoice = await XInvoice.fromXml(xrechnungXml);

// Export as different formats
const facturxXml = await zugferdInvoice.exportXml('facturx');
const ublXml = await facturxInvoice.exportXml('ubl');
const xrechnungXml = await zugferdInvoice.exportXml('xrechnung');

PDF Handling

// Extract XML from PDF
const pdfBuffer = await fs.readFile('invoice.pdf');
const invoice = await XInvoice.fromPdf(pdfBuffer);

// Check the detected format
console.log(`Detected format: ${invoice.getFormat()}`);

// Embed XML into PDF
invoice.pdf = {
  name: 'invoice.pdf',
  id: 'invoice-1234',
  metadata: { textExtraction: '' },
  buffer: await fs.readFile('document.pdf')
};

const pdfWithInvoice = await invoice.exportPdf('facturx');
await fs.writeFile('invoice-with-xml.pdf', pdfWithInvoice.buffer);

Validating Invoices

// Validate an invoice
const validationResult = await invoice.validate();
if (validationResult.valid) {
  console.log('Invoice is valid');
} else {
  console.log('Validation errors:', validationResult.errors);
}

// Validate at different levels
const syntaxValidation = await invoice.validate(ValidationLevel.SYNTAX);
const semanticValidation = await invoice.validate(ValidationLevel.SEMANTIC);
const businessValidation = await invoice.validate(ValidationLevel.BUSINESS);

Architecture

XInvoice uses a modular architecture with specialized components:

Core Components

  • XInvoice: The main class that provides a high-level API for working with invoices
  • Decoders: Convert format-specific XML to a common invoice model
  • Encoders: Convert the common invoice model to format-specific XML
  • Validators: Validate invoices against format-specific rules
  • FormatDetector: Automatically detects invoice formats

PDF Processing

  • PDFExtractor: Extract XML from PDF files using multiple strategies:
    • Standard Extraction: Extracts XML from standard PDF/A-3 embedded files
    • Associated Files Extraction: Extracts XML from associated files (AF entry)
    • Text-based Extraction: Extracts XML by searching for patterns in the PDF text
  • PDFEmbedder: Embed XML into PDF files with robust error handling

This modular approach ensures maximum compatibility with different PDF implementations and invoice formats.

Supported Invoice Formats

| Format | Version | Read | Write | Validate | |--------|---------|------|-------|----------| | ZUGFeRD | 1.0 | ✅ | ✅ | ✅ | | ZUGFeRD | 2.0/2.1 | ✅ | ✅ | ✅ | | Factur-X | 1.0 | ✅ | ✅ | ✅ | | XRechnung | 1.2+ | ✅ | ✅ | ✅ | | UBL | 2.1 | ✅ | ✅ | ✅ | | CII | 16931 | ✅ | ✅ | ✅ | | FatturaPA | 1.2 | ✅ | ✅ | ✅ |

Advanced Usage

Custom Encoders and Decoders

// Using specific encoders
import { ZUGFeRDEncoder, FacturXEncoder, UBLEncoder } from '@fin.cx/xinvoice';

// Create ZUGFeRD XML
const zugferdEncoder = new ZUGFeRDEncoder();
const zugferdXml = await zugferdEncoder.encode(invoiceData);

// Create Factur-X XML
const facturxEncoder = new FacturXEncoder();
const facturxXml = await facturxEncoder.encode(invoiceData);

// Create UBL XML
const ublEncoder = new UBLEncoder();
const ublXml = await ublEncoder.encode(invoiceData);

// Using specific decoders
import { ZUGFeRDDecoder, FacturXDecoder } from '@fin.cx/xinvoice';

// Decode ZUGFeRD XML
const zugferdDecoder = new ZUGFeRDDecoder(zugferdXml);
const zugferdData = await zugferdDecoder.decode();

// Decode Factur-X XML
const facturxDecoder = new FacturXDecoder(facturxXml);
const facturxData = await facturxDecoder.decode();

Working with PDF Extraction and Embedding

import { PDFExtractor, PDFEmbedder } from '@fin.cx/xinvoice';

// Extract XML from PDF
const extractor = new PDFExtractor();
const extractResult = await extractor.extractXml(pdfBuffer);

if (extractResult.success) {
  console.log('Extracted XML:', extractResult.xml);
  console.log('Detected format:', extractResult.format);
  console.log('Extraction method used:', extractResult.extractorUsed);
} else {
  console.error('Extraction failed:', extractResult.error?.message);
}

// Embed XML into PDF
const embedder = new PDFEmbedder();
const embedResult = await embedder.createPdfWithXml(
  pdfBuffer,
  xmlContent,
  'factur-x.xml',
  'Factur-X XML Invoice',
  'invoice.pdf',
  'invoice-123456'
);

if (embedResult.success && embedResult.pdf) {
  await fs.writeFile('output.pdf', embedResult.pdf.buffer);
} else {
  console.error('Embedding failed:', embedResult.error?.message);
}

Format Detection

import { FormatDetector, InvoiceFormat } from '@fin.cx/xinvoice';

// Detect format from XML
const format = FormatDetector.detectFormat(xmlString);

// Check format
if (format === InvoiceFormat.ZUGFERD) {
  console.log('This is a ZUGFeRD invoice');
} else if (format === InvoiceFormat.FACTURX) {
  console.log('This is a Factur-X invoice');
} else if (format === InvoiceFormat.XRECHNUNG) {
  console.log('This is an XRechnung invoice');
} else if (format === InvoiceFormat.UBL) {
  console.log('This is a UBL invoice');
}

Development

Building the Project

# Install dependencies
pnpm install

# Build the project
pnpm run build

Running Tests

# Run all tests
pnpm test

# Run specific test
pnpm test test/test.xinvoice.ts

The library includes comprehensive test suites that verify:

  • XML creation capabilities
  • Format detection logic
  • XML encoding/decoding circularity
  • Special character handling
  • Different invoice types (invoices, credit notes)
  • PDF extraction and embedding
  • Error handling and recovery

Key Features

  1. PDF Integration

    • Embed XML invoices in PDF documents with detailed error reporting
    • Extract XML from existing PDF invoices using multiple fallback strategies
    • Handle different XML attachment methods and encodings
  2. Encoding & Decoding

    • Create standards-compliant XML from structured data
    • Parse XML invoices back to structured data
    • Support multiple format standards
    • Circular encoding/decoding integrity
  3. Format Detection

    • Automatic detection of invoice XML format
    • Support for different XML namespaces
    • Graceful handling of malformed XML
  4. Validation

    • Validate invoices against format-specific rules
    • Detailed error reporting
    • Support for different validation levels
  5. Error Handling

    • Robust error recovery mechanisms
    • Detailed error information
    • Type-safe error reporting

By embracing @fin.cx/xinvoice, you simplify the handling of electronic invoice documents, fostering seamless integration across different financial processes, thus empowering practitioners with robust, flexible tools for VAT invoices in ZUGFeRD/Factur-X compliance or equivalent digital formats.

License and Legal Information

This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the license file within this repository.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.

Company Information

Task Venture Capital GmbH
Registered at District court Bremen HRB 35230 HB, Germany

For any legal inquiries or if you require further information, please contact us via email at [email protected].

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.