Project

zugpferd

0.0
The project is in a healthy, maintained state
Read, write and convert XRechnung and ZUGFeRD electronic invoices (e-Rechnung) according to EN 16931. Supports UBL 2.1 and UN/CEFACT CII syntaxes with dedicated classes for Invoice, Credit Note, Corrected Invoice, Self-billed Invoice, Partial Invoice and Prepayment Invoice.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 5.25
~> 13.0

Runtime

~> 1.16
 Project Readme

Zugpferd

A Ruby library for reading and writing XRechnung and ZUGFeRD electronic invoices (e-Rechnung) according to EN 16931, supporting both UBL 2.1 and UN/CEFACT CII syntaxes.

Built for Ruby developers integrating XRechnung or ZUGFeRD e-invoicing into their applications.

Features

  • Syntax-agnostic data model based on EN 16931 Business Terms (BTs)
  • UBL 2.1 Reader & Writer (Invoice and Credit Note)
  • UN/CEFACT CII Reader & Writer
  • PDF/A-3 embedding via Ghostscript — create ZUGFeRD / Factur-X hybrid invoices
  • XSD and Schematron validation (EN 16931 + XRechnung) — optional, requires Java + Saxon
  • Supported document types:
    • 380 — Commercial Invoice
    • 381 — Credit Note (UBL: separate <CreditNote> root element)
    • 384 — Corrected Invoice
    • 389 — Self-billed Invoice
    • 326 — Partial Invoice
    • 386 — Prepayment Invoice
  • No Rails dependency
  • BigDecimal for all monetary amounts

Installation

# Gemfile
gem "zugpferd"
bundle install

Or install directly:

gem install zugpferd

Usage

Reading a UBL invoice

require "zugpferd"

xml = File.read("invoice_ubl.xml")
invoice = Zugpferd::UBL::Reader.new.read(xml)

puts invoice.number          # BT-1
puts invoice.seller.name     # BG-4
puts invoice.type_code       # "380", "381", etc.

invoice.line_items.each do |line|
  puts "#{line.item.name}: #{line.line_extension_amount}"
end

Reading a CII invoice

xml = File.read("invoice_cii.xml")
invoice = Zugpferd::CII::Reader.new.read(xml)

The data model is identical regardless of whether UBL or CII is used.

Writing a UBL invoice

invoice = Zugpferd::Model::Invoice.new(
  number: "INV-2024-001",
  issue_date: Date.today,
  type_code: "380",
  currency_code: "EUR",
)

invoice.seller = Zugpferd::Model::TradeParty.new(name: "Seller GmbH")
invoice.buyer  = Zugpferd::Model::TradeParty.new(name: "Buyer AG")

# ... set line items, tax, totals, payment ...

xml = Zugpferd::UBL::Writer.new.write(invoice)
File.write("output.xml", xml)

Writing a Credit Note

credit_note = Zugpferd::Model::CreditNote.new(
  number: "CN-2024-001",
  issue_date: Date.today,
)

# The writer automatically generates <CreditNote> instead of <Invoice>
xml = Zugpferd::UBL::Writer.new.write(credit_note)

Converting between syntaxes

# Read CII, write as UBL
invoice = Zugpferd::CII::Reader.new.read(cii_xml)
ubl_xml = Zugpferd::UBL::Writer.new.write(invoice)

Creating a ZUGFeRD / Factur-X PDF

Requires Ghostscript installed on the system.

require "zugpferd"
require "zugpferd/pdf"  # explicit opt-in

xml = Zugpferd::CII::Writer.new.write(invoice)

embedder = Zugpferd::PDF::Embedder.new
embedder.embed(
  pdf_path: "rechnung.pdf",
  xml: xml,
  output_path: "rechnung_zugferd.pdf",
  version: "2p1",
  conformance_level: "XRECHNUNG"  # use "EN 16931" for non-XRechnung invoices
)

Validating an invoice

Requires Java and Saxon HE. Install via bin/setup-schemas.

require "zugpferd"
require "zugpferd/validation"  # explicit opt-in, requires Java + Saxon

xml = Zugpferd::CII::Writer.new.write(invoice)

validator = Zugpferd::Validation::SchematronValidator.new(schemas_path: "vendor/schemas")
errors = validator.validate(xml, rule_set: :xrechnung_cii)
fatals = errors.select { |e| e.flag == "fatal" }

if fatals.any?
  fatals.each { |e| puts "[#{e.id}] #{e.text}" }
end

Data Model

The model maps to the Business Groups of EN 16931:

Class Business Group Description
Model::Invoice BG-0 Commercial Invoice (380)
Model::CreditNote BG-0 Credit Note (381)
Model::CorrectedInvoice BG-0 Corrected Invoice (384)
Model::SelfBilledInvoice BG-0 Self-billed Invoice (389)
Model::PartialInvoice BG-0 Partial Invoice (326)
Model::PrepaymentInvoice BG-0 Prepayment Invoice (386)
Model::TradeParty BG-4 / BG-7 Seller / Buyer
Model::PostalAddress BG-5 / BG-8 Postal address
Model::Contact BG-6 / BG-9 Contact information
Model::LineItem BG-25 Invoice line
Model::Item BG-31 Item information
Model::Price BG-29 Price details
Model::MonetaryTotals BG-22 Document totals
Model::TaxBreakdown BG-23 VAT breakdown
Model::PaymentInstructions BG-16 Payment information
Model::AllowanceCharge BG-20 / BG-21 Allowances and charges

Requirements

  • Ruby >= 3.2
  • nokogiri ~> 1.16
  • bigdecimal ~> 3.1

Development

bundle install
bin/setup-schemas    # Downloads XSD schemas, CEN Schematron, XRechnung test suite
bundle exec rake test

License

MIT