ZUGFeRD-csharp
14.1.0
See the version list below for details.
dotnet add package ZUGFeRD-csharp --version 14.1.0
NuGet\Install-Package ZUGFeRD-csharp -Version 14.1.0
<PackageReference Include="ZUGFeRD-csharp" Version="14.1.0" />
paket add ZUGFeRD-csharp --version 14.1.0
#r "nuget: ZUGFeRD-csharp, 14.1.0"
// Install ZUGFeRD-csharp as a Cake Addin #addin nuget:?package=ZUGFeRD-csharp&version=14.1.0 // Install ZUGFeRD-csharp as a Cake Tool #tool nuget:?package=ZUGFeRD-csharp&version=14.1.0
Part of the ZUGFeRD community: https://github.com/zugferd
Sponsoring
Implementing and maintaining this library is a lot of hard work. I'm doing this in my spare time, there is no company behind developing ZUGFeRD-csharp. Support me in this work and help making this library better:
In particular, I am searching for sponsors for:
- Complete UBL format support (reading and writing)
- Validation using the standard XSL
- Invoice visualization
Introduction
The ZUGFeRD library allows to create XML files as required by German electronic invoice initiative ZUGFeRD as well invoices in the successor Factur-X. One special profile of Factur-X is the German XRechnung format. The library is meant to be as simple as possible, however it is not straight forward to use as the resulting XML file contains a complete invoice in XML format. Please take a look at the ZUGFeRD-Test project to find sample creation code. This code creates the same XML file as shipped with the ZUGFeRD information package.
Relationship between the different standards
Since there are a lot of terms and standards around electronic invoices, I'd like to lay out my understanding:
- ZUGFeRD was developed by a German initiative as a standard for electronic invoices (https://www.ferd-net.de/).
- ZUGFeRD 2.1 is identical to the German/French cooperation Factur-X (ZUGFeRD 2.1 = Factur-X 1.0) (https://www.ferd-net.de/standards/what-is-factur-x/index.html).
- The standard Factur-X 1.0 (respectively ZUGFeRD 2.1) is conform with the European norm EN 16931.
- EN 16931 in turn is based on worldwide UN/CEFACT standard 'Cross Industry Invoice' (CII).
- XRechnung as another German standard is a subset of EN 16931. It is defined by another party called KoSIT (https://www.xoev.de/). It comes with its own validation rules (https://www.ferd-net.de/standards/what-is-xrechnung/index.html).
- This means that both Factur-X 1.0 (respectively ZUGFeRD 2.1) and XRechnung are conform with EN 16931. This does not automatically result that those invoices are per se identical
- To achieve compatibility, ZUGFeRD 2.1.1 introduced a XRechnung reference profile to guarantee compatibility between the two sister formats
License
Subject to the Apache license http://www.apache.org/licenses/LICENSE-2.0.html
Installation
Just use nuget or Visual Studio Package Manager and download 'ZUGFeRD-csharp'.
You can find more information about the nuget package here:
https://www.nuget.org/packages/ZUGFeRD-csharp/
Building on your own
Prerequisites:
- Visual Studio >= 2017
- .net Framework >= 4.6.1 (for .net Standard 2.0 support)
Open ZUGFeRD/ZUGFeRD.sln solution file. Choose Release or Debug mode and hit 'Build'. That's it.
For running the tests, open ZUGFeRD-Test/ZUGFeRD-Test.sln and run the unit tests. The tests show good cases on how to use the library.
Step-by-step guide for creating invoices
Central class for users is class InvoiceDescriptor. This class does not only allow to read and set all ZUGFeRD attributes and structures but also allows to load and save ZUGFeRD files.
However, the standard has become quite large during the recent years. So it is worthwhile to go through the creation process step by step.
Creating an invoice
InvoiceDescriptor desc = InvoiceDescriptor.CreateInvoice("471102", new DateTime(2013, 6, 5), CurrencyCodes.EUR, "GE2020211-471102");
desc.Name = "WARENRECHNUNG";
desc.ReferenceOrderNo = "AB-312";
desc.AddNote("Rechnung gemäß Bestellung Nr. 2013-471331 vom 01.03.2013.");
desc.AddNote("Es bestehen Rabatt- und Bonusvereinbarungen.", "AAK");
desc.SetBuyer("Kunden Mitte AG", "69876", "Frankfurt", "Kundenstraße 15", CountryCodes.DE, "88", new GlobalID(GlobalIDSchemeIdentifiers.GLN, "4000001123452"));
desc.AddBuyerTaxRegistration("DE234567890", TaxRegistrationSchemeID.VA);
desc.SetBuyerContact("Hans Muster");
desc.SetSeller("Lieferant GmbH", "80333", "München", "Lieferantenstraße 20", CountryCodes.DE, "88", new GlobalID(GlobalIDSchemeIdentifiers.GLN, "4000001123452"));
desc.AddSellerTaxRegistration("201/113/40209", TaxRegistrationSchemeID.FC);
desc.AddSellerTaxRegistration("DE123456789", TaxRegistrationSchemeID.VA);
desc.SetBuyerOrderReferenceDocument("2013-471331", new DateTime(2013, 03, 01));
desc.SetDeliveryNoteReferenceDocument("2013-51111", new DateTime(2013, 6, 3));
desc.ActualDeliveryDate = new DateTime(2013, 6, 3);
desc.SetTotals(202.76m, 5.80m, 14.73m, 193.83m, 21.31m, 215.14m, 50.0m, 165.14m);
desc.AddApplicableTradeTax(129.37m, 7m, TaxTypes.VAT, TaxCategoryCodes.S);
desc.AddApplicableTradeTax(64.46m, 19m, TaxTypes.VAT, TaxCategoryCodes.S);
desc.AddLogisticsServiceCharge(5.80m, "Versandkosten", TaxTypes.VAT, TaxCategoryCodes.S, 7m);
desc.SetTradePaymentTerms("Zahlbar innerhalb 30 Tagen netto bis 04.07.2013, 3% Skonto innerhalb 10 Tagen bis 15.06.2013", new DateTime(2013, 07, 04));
Optionally, to support Peppol, an electronic address can be passed:
desc.SetSellerElectronicAddress("DE123456789", ElectronicAddressSchemeIdentifiers.GermanyVatNumber);
desc.SetBuyerElectronicAddress("LU987654321", ElectronicAddressSchemeIdentifiers.LuxemburgVatNumber);
The fields are only necessary if you want to send the XRechnung via the Peppol network. A description of the fields can be found in the following documents:
https://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf
In Luxembourg, it has been mandatory since this year to process all invoices via Peppol:
In Germany, this has so far only been necessary for invoices in the course of a public contract from the federal government:
https://www.e-rechnung-bund.de/ubertragungskanale/peppol/
Adding line items
Handling of line ids
The library allows to operate in two modes: you can either let the library generate the line ids automatically or you can alternatively pass distinct line ids. This is helpful if you want to convert existing invoices, e.g. from ERP systems, to ZUGFeRD/ Factur-X.
To let the library create line ids, you can use:
InvoiceDescriptor desc = InvoiceDescriptor.CreateInvoice("471102", new DateTime(2013, 6, 5), CurrencyCodes.EUR, "GE2020211-471102");
desc.AddTradeLineItem("Item name", "Detail description", QuantityCodes.PCE, ....);
This will generate an invoice with trade line item numbered as '1'.
To pass pre-defined line ids, this is the way to go:
InvoiceDescriptor desc = InvoiceDescriptor.CreateInvoice("471102", new DateTime(2013, 6, 5), CurrencyCodes.EUR, "GE2020211-471102");
desc.AddTradeLineItem(lineId: "0001", "Item name", "Detail description", QuantityCodes.PCE, ....);
desc.AddTradeLineItem(lineId: "0002", "Item name", "Detail description", QuantityCodes.PCE, ....);
which will generate an invoice with two trade line items, with the first one as number '0001' and the second one as number '0002'.
Working with product characteristics
Product characteristics are used to add information for the specified trade product in the 'ApplicableProductCharacteristic' section. One trade product can have one or more product characteristics, which can contain description, value, typecode and value measurand elements.
// you can optionally add product characteristics:
desc.TradeLineItems.Add(new TradeLineItem()
{
ApplicableProductCharacteristics = new List<ApplicableProductCharacteristic>
{
new ApplicableProductCharacteristic()
{
Description = "Description",
Value = "Value"
}
}
});
Document references
The library allows to add special references to an invoice which are pretty rare but nevertheless supported:
// you can optionally add a reference to a procuring project:
desc.SpecifiedProcuringProject = new SpecifiedProcuringProject {Name = "Projekt AB-312", ID = "AB-312"};
// you can optionally reference a contract:
desc.ContractReferencedDocument = new ContractReferencedDocument {ID = "AB-312-1", Date = new DateTime(2013,1,1)};
Storing the invoice
FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.Write);
desc.Save(stream, ZUGFeRDVersion.Version2, Profile.XRechnung);
stream.Flush();
stream.Close();
Support for ZUGFeRD 1.x, ZUGFeRD 2.x
In order to load ZUGFeRD files, you call InvoiceDescriptor.Load(), passing a file path like this:
InvoiceDescriptor descriptor = InvoiceDescriptor.Load("zugferd.xml");
alternatively, you can pass an open stream object:
Stream stream = new FileStream("zugferd.xml", FileMode.Open, FileAccess.Read);
InvoiceDescriptor descriptor = InvoiceDescriptor.Load(stream);
The library will automatically detect the ZUGFeRD version of the file and parse accordingly. It will automatically be chosen which XRechnung version to use depending on the current date. The lifecycle of the stream is not influenced by the ZUGFeRD library, i.e. the library expects an open stream and will not close if after reading from it.
For saving ZUGFeRD files, use InvoiceDescriptor.Save(). Here, you can also pass a stream object:
InvoiceDescriptor descriptor = InvoiceDescriptor.CreateInvoice(......);
// fill attributes and structures
FileStream stream = new FileStream(filename, FileMode.Create, FileAccess.Write);
descriptor.Save(stream, ZUGFeRDVersion.Version1, Profile.Basic);
stream.Flush();
stream.Close();
As you see, the library does not influence the lifecycle of the stream, i.e. it is not automatically closed by the library. Just as opening the stream, flushing and closing is the duty of the calling function.
Alternatively, you can pass a file path:
InvoiceDescriptor descriptor = InvoiceDescriptor.CreateInvoice(......);
// fill attributes and structures
descriptor.Save("zugferd.xml", ZUGFeRDVersion.Version1, Profile.Basic);
Optionally, you can pass the ZUGFeRD version to use, default currently is version 1.x, e.g.:
InvoiceDescriptor descriptor = InvoiceDescriptor.CreateInvoice(......);
// fill attributes and structures
descriptor.Save("zugferd-v1.xml", ZUGFeRDVersion.Version1, Profile.Basic); // save as version 1.x
descriptor.Save("zugferd-v2.xml", ZUGFeRDVersion.Version2, Profile.Basic); // save as version 2.0
descriptor.Save("zugferd-v2.xml", ZUGFeRDVersion.Version21, Profile.Basic); // save as version 2.1
For reading and writing XRechnung invoices, please see below.
Support for XRechnung
In general, creating XRechnung files is straight forward and just like creating any other ZUGFeRD version and profile:
descriptor.Save("xrechnung.xml", ZUGFeRDVersion.Version21, Profile.XRechnung);
This will save the invoice as XRechnung 3.0.1 as valid from 2024/02/01.
Make sure to also add a business process which is required starting with XRechnung 3.0.1:
desc.BusinessProcess = "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0";
Furthermore, XRechnung comes with some special features. One of these features is the ability to embed binary files as attachments to the xrechnung.xml
document:
InvoiceDescriptor desc = _createInvoice();
byte[] data = System.IO.File.ReadAllBytes("my-calculation.xlsx");
desc.AddAdditionalReferencedDocument(
issuerAssignedID: "calculation-sheet",
typeCode: AdditionalReferencedDocumentTypeCode.ReferenceDocument,
name: "Calculation as the basis for the invoice",
attachmentBinaryObject: data,
filename: "my-calculation.xlsx");
desc.Save("xrechnung.xml", ZUGFeRDVersion.Version21, Profile.XRechnung);
The resulting xrechnung.xml
file will then contain the calculation file content. As this is not standardized, the decision was to encode the attachments in base64.
Please note that there are only few mime-types supported by the XRechnung standard. The supported mime-types are defined in BG-24 and BT-125. At the time of writing this tutorial, those are also listed in the discussion you find over here: https://projekte.kosit.org/xrechnung/xrechnung/-/issues/59
- application/pdf
- image/png
- image/jpeg
- text/csv
- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- application/vnd.oasis.opendocument.spreadsheet
- application/xml
Support for E-Reporting
For french companies, a dedicated profile exists called E-Reporting. This profile is implemented on top of XRechnung/ Factur-X. It is used when transactions are done to customers who don't make use of VAT. One example are private customers (in B2C scenarios). The other example is when selling to entities beyond France. More information can be found here: https://www.impots.gouv.fr/e-reporting-la-transmission-de-donnees-de-transaction-ladministration (French) And here: https://www.roedl.de/themen/frankreich-e-invoice-reporting-umsatzsteuer-digital (german)
Thanks to @Athilla, this profile is also supported by ZUGFeRD-csharp.
The information that is written into the invoice descriptor is identical to standard XRechnung/ Factur-X invoices, you just need to adjust the profile:
descriptor.Save("xrechnung.xml", ZUGFeRDVersion.Version21, Profile.EReporting);
This information needs to be sent to the tax authorities. Different due dates apply for implementation for different sizes of companies.
Support for profiles
The library contains support for all profiles that are supported by the ZUGFeRD formats:
Profile | Version1 | Version20 | Version22 |
---|---|---|---|
MINIMUM | X | X | |
BASIC WL | X | X | |
BASIC | X | X | X |
COMFORT/EN16391 | X | X | X |
XRECHNUNG | X | ||
EXTENDED | X | X | X |
Please note that version 1 implementation of the library is not strict, i.e. it will output all information available into the invoice xml, regardless of the profiles that is used. Reading various files with different profiles will generate the correct output.
If you want to write the invoice xml with a certain ZUGFeRD version and a certain profile, make sure to use the parameters of the Save method:
descriptor.Save("zugferd-v1.xml", ZUGFeRDVersion.Version1, Profile.Basic); // save as version 1.x, profile Basic
descriptor.Save("zugferd-v20.xml", ZUGFeRDVersion.Version20, Profile.Basic); // save as version 2.0, profile Basic
descriptor.Save("zugferd-v22.xml", ZUGFeRDVersion.Version22, Profile.Basic); // save as version 2.1, profile Basic
descriptor.Save("zugferd-v22-xrechnung.xml", ZUGFeRDVersion.Version22, Profile.XRechnung); // save as version 2.1, profile XRechnung
Extracting xml attachments from pdf files
I am frequently asked how to extract the ZUGFeRD/ Factur-X/ XRechnung attachment from existing PDF files.
There is a nice article on stackoverflow on how this can be achieved using itextsharp:
https://stackoverflow.com/a/6334252
and this one covers the same with itext7 which is the successor of itextsharp:
https://stackoverflow.com/a/37804285
Writing xml attachments to pdf files
It is also possible to add the xml ZUGFeRD or XRechnung attachment to pdf files using itextsharp. You find information about this here:
Thanks
- The solution is used in CKS.DMS and supported by CKSolution: https://www.cksolution.de
- ZUGFeRD 2.1 implementation was done by https://netco-solution.de and used in netCo.Butler
Links
You can find more information about ZUGFeRD here: https://www.ferd-net.de/
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.1
- No dependencies.
-
.NETFramework 4.8
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
-
.NETStandard 2.1
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
15.0.0 | 4,262 | 10/29/2024 |
14.1.0 | 19,438 | 8/16/2024 |
14.0.0 | 705 | 8/11/2024 |
13.0.0 | 14,395 | 7/9/2024 |
12.8.0 | 40,318 | 3/13/2024 |
12.7.0 | 2,341 | 3/4/2024 |
12.6.0 | 1,369 | 2/27/2024 |
12.5.0 | 4,850 | 1/25/2024 |
12.4.0 | 6,096 | 12/11/2023 |
12.3.1 | 4,400 | 11/23/2023 |
12.3.0 | 545 | 11/23/2023 |
12.2.0 | 3,769 | 10/27/2023 |
12.1.2 | 3,311 | 10/5/2023 |
12.1.1 | 1,835 | 9/24/2023 |
12.1.0 | 589 | 9/24/2023 |
12.0.1 | 8,284 | 8/3/2023 |
12.0.0 | 1,772 | 7/30/2023 |
11.3.0 | 2,520 | 7/11/2023 |
11.2.0 | 12,671 | 7/3/2023 |
11.1.0 | 13,976 | 5/21/2023 |
11.0.0 | 1,284 | 5/1/2023 |
10.0.0 | 23,465 | 1/10/2023 |
9.0.0 | 17,760 | 6/29/2022 |
8.0.0 | 1,410 | 6/16/2022 |
7.0.1 | 10,229 | 2/7/2022 |
7.0.0 | 1,648 | 12/28/2021 |
6.2.0 | 2,690 | 10/31/2021 |
6.1.0 | 58,084 | 7/29/2021 |
6.0.0 | 4,244 | 3/8/2021 |
5.0.1 | 13,391 | 1/7/2021 |
5.0.0 | 1,909 | 11/10/2020 |
4.0.0 | 2,879 | 9/15/2020 |
4.0.0-beta | 983 | 9/7/2020 |
3.2.1 | 2,076 | 8/11/2020 |
3.2.0 | 1,247 | 8/5/2020 |
3.1.0 | 1,203 | 7/30/2020 |
3.0.1 | 1,269 | 7/28/2020 |
3.0.0 | 2,263 | 7/9/2020 |
2.11.0 | 7,175 | 3/29/2020 |
2.10.0 | 10,166 | 2/17/2020 |
2.9.0 | 2,029 | 7/29/2019 |
2.8.0 | 1,256 | 7/3/2019 |
2.7.1 | 1,851 | 11/9/2018 |
2.7.0 | 1,469 | 10/29/2018 |
2.6.0 | 1,685 | 9/6/2018 |
2.5.1 | 2,148 | 2/15/2018 |
2.5.0 | 1,608 | 9/19/2017 |
2.4.1 | 1,723 | 7/18/2017 |
2.4.0 | 1,534 | 7/18/2017 |
2.3.0 | 1,774 | 4/12/2017 |
2.2.0 | 1,705 | 4/7/2017 |
2.1.0 | 1,851 | 12/29/2016 |
2.0.0 | 1,738 | 10/27/2016 |
1.21.0 | 1,624 | 10/20/2016 |
1.20.0 | 1,598 | 10/12/2016 |
1.19.0 | 1,685 | 10/12/2016 |
1.18.0 | 1,634 | 8/29/2016 |
1.17.0 | 1,611 | 8/18/2016 |
1.16.0 | 1,987 | 7/28/2016 |
1.15.0 | 1,981 | 7/28/2016 |
1.14.0 | 1,656 | 7/25/2016 |
1.13.0 | 1,691 | 7/19/2016 |
1.12.0 | 1,613 | 6/20/2016 |
1.11.0 | 1,668 | 6/19/2016 |
1.10.0 | 1,615 | 6/17/2016 |
1.9.0 | 2,120 | 5/30/2016 |
1.8.9 | 1,781 | 5/30/2016 |
1.8.8 | 1,736 | 4/7/2016 |
1.8.7 | 1,678 | 3/24/2016 |
1.8.6 | 1,789 | 10/13/2015 |
1.8.5 | 1,770 | 5/16/2015 |
1.8.4 | 1,697 | 5/16/2015 |
1.8.3 | 1,836 | 10/18/2014 |
1.8.2 | 1,892 | 8/24/2014 |
1.8.1 | 1,784 | 8/22/2014 |
1.8.0 | 1,835 | 2/10/2014 |
1.7.4 | 1,761 | 1/25/2014 |
1.7.3 | 1,778 | 1/24/2014 |
1.7.2 | 1,754 | 1/22/2014 |
1.7.1 | 1,774 | 1/21/2014 |
1.7.0 | 1,737 | 1/20/2014 |
1.6.1 | 1,747 | 1/18/2014 |
1.6.0 | 1,774 | 1/18/2014 |
1.5.0 | 1,807 | 1/17/2014 |
1.4.0 | 1,748 | 1/15/2014 |
1.3.0 | 1,810 | 1/14/2014 |
1.2.0 | 2,034 | 11/24/2013 |
1.1.0 | 1,836 | 11/22/2013 |
1.0.0 | 3,736 | 11/17/2013 |
14.1.0: Correct reading of test indicator, allow to work with both qdt and udt data types. Full overview: https://github.com/stephanstapel/ZUGFeRD-csharp/releases/tag/14.1.0
14.0.0: Lots of changes, for breaking changes see https://github.com/stephanstapel/ZUGFeRD-csharp/releases/tag/14.0.0
13.0.0: Breaking changes on item level, various fixes
12.8.0: Added more targets
12.7.0: Support for EReporting, bugfixes
12.6.0: XRechnung 3 enthancements, refactoring
12.5.0: various bugfixes
12.4.0: additional ElectronicAddressSchemeIdentifiers
12.3.1: bug fix for all party types
12.3.0: enhanced standard conformance for all party types