Skip to main content

Current state in Lago

Lago currently supports two types of E-Invoicing formats: Cross Industry Invoices (CII) and Universal Business Language (UBL). Both implementations follow the French E-Invoicing structure. Some EU countries may use different naming conventions, but they generally rely on the same underlying CII or UBL data structures, with country specific additions or removals. This contribution guide is intended for developers who want to extend Lago’s E-Invoicing capabilities to support additional jurisdictions or customize existing formats, especially for Peppol network compliance.

CII - Cross Industry Invoices (Factur-X)

Cross Industry Invoices represent the hybrid format combining a PDF/A-3 file with an embedded XML file. The XML structure follows the CII standard, which is widely used in Europe, including France’s Factur-X implementation. Lago supports e-invoicing for the following record types:
  • invoice
  • credit_note
  • payments
Each record type has a dedicated Builder class responsible for generating the XML document in the required format. Builder classes are located at:
app/serializers/e_invoices/<invoices|credit_notes|payments>/<factur_x|ubl>/builder.rb
The Factur-X (CII) implementation lives in the Lago API project under:
app/serializers/e_invoices/factur_x

Classes and XML Tags

ClassXML TagDescriptionParameters / Notes
FacturX::CrossIndustryInvoicersm:CrossIndustryInvoiceRoot element for the invoice and its direct childrenRequires a Ruby block
FacturX::Headerrsm:ExchangedDocumentHeader information for the documenttype_code: document type
notes: optional additional information
FacturX::LineItemram:IncludedSupplyChainTradeLineItemRepresents a single invoice line itemdata: FacturX::LineItem::Data containing item details
FacturX::TradeAgreementram:ApplicableHeaderTradeAgreementCommercial agreement detailsoptions: optional FacturX::TradeAgreement::Options
tax_registration: controls tax registration rendering, default true
FacturX::TradeDeliveryram:ApplicableHeaderTradeDeliveryDelivery information for goods or servicesdelivery_date: date goods or services were delivered
FacturX::TradeSettlementram:ApplicableHeaderTradeSettlementSettlement and payment contextRequires a Ruby block
FacturX::TradeSettlementPaymentram:SpecifiedTradeSettlementPaymentMeansPayment means used for settlementNo specific parameters
FacturX::ApplicableTradeTaxram:ApplicableTradeTaxTax information applied to the invoiceMultiple tax related parameters
FacturX::TradeAllowanceChargeram:SpecifiedTradeAllowanceChargeAllowances or charges applied to the invoiceMultiple allowance and charge parameters
FacturX::PaymentTermsram:SpecifiedTradePaymentTermsDefines payment termsNo specific parameters
FacturX::MonetarySummationram:SpecifiedTradeSettlementHeaderMonetarySummationMonetary totals and summariesamounts: FacturX::MonetarySummation::Amounts with rendered values

UBL - Universal Business Language

Universal Business Language (UBL) is another widely adopted E-Invoicing standard, particularly in the Peppol network. UBL invoices are XML-only documents that follow a specific schema defined by OASIS. The UBL implementation is located in the Lago API project under:
app/serializers/e_invoices/ubl

Contributing new jurisdictions - The example of Germany

Overview

This guide outlines the steps to contribute a new E-Invoicing format for Germany, specifically the XRechnung and ZUGFeRD formats based on UBL and CII standards. Germany supports two e-invoicing formats:

ZUGFeRD 2.3.3 (EN 16931) Factur-X

This format combines a human readable PDF with embedded XML data. It is the most commonly used option due to lower implementation and operational costs compared to fiscal EDI based processes.

XRechnung UBL Invoice

This is a pure XML electronic invoice based on UBL 2.1. It follows German XRechnung semantic requirements and is typically transmitted via the PEPPOL network using the PEPPOL BIS Billing 3.0 specification. It is used for German B2G compliance and EU wide interoperability.

Implementation notes

ZUGFeRD 2.3.3 has no differences compared to the French Factur-X implementation. Existing Factur-X code can be fully reused. XRechnung may require additional tags that are not present in the French UBL implementation. These tags should be added under the UBL folder. Example:
  • The InvoicePeriod tag is optional in standard UBL but required in XRechnung. It is currently not implemented in the French version.
  • Some tags present in the French implementation may not be valid for XRechnung. Rendering of such tags should be controlled via conditional logic based on billing_entity.country.
def serialize
  # other mandatory tags

  render_specific_tag if conditions_met?

  # other tags
end

private

def conditions_met?
  ["DE"].include?(billing_entity.country)
end

def render_specific_tag
  xml["cac"].GermanySpecificTag(value)
end
If a completely new and independent tag is required, create a dedicated class to render it. The corresponding Builder class should invoke it only when the conditions for the specific country or implementation are met.