Los geht’s mit FactoorSharp
Mit FactoorSharp erstellst, liest und validierst du elektronische Rechnungen (ZUGFeRD, XRechnung, EN16931) in wenigen Minuten.
Diese Anleitung führt dich Schritt für Schritt zu deiner ersten funktionierenden Rechnung.
Nach diesem Schnellstart kannst du:
- eine Rechnung in C# erzeugen
- sie als EN16931 / ZUGFeRD XML exportieren
- optional in ein PDF/A-3 einbetten
- das Ergebnis validieren
Installation
Installiere FactoorSharp über NuGet:
dotnet add package FactoorSharp.FacturX
Oder über den Package Manager:
Install-Package FactoorSharp
Die Komponente unterstützt: .NET 6+, .NET Framework 4.6, .NET Framework 4.8 (je nach Zielplattform)
Lizenz abrufen
TODO: Registrieren und abrufen
Erste Rechnung erzeugen
Im folgenden Beispiel erzeugst du eine minimale EN16931-konforme Rechnung.
Zunächst die Kopfdaten der Rechnung mit der Kennung von Verkäufer und Käufer. Dazu gehört auch die Angabe zur Lieferung:
FacturXInvoice.SetLicense("...");
var invoice = FacturXInvoice.CreateInvoice("Invoice-01",
new DateTime(2025,09,03),
Currency.EUR)
// BG-14
.SetSeller(name: "BikeTech GmbH",
postcode: "10115",
city: "Berlin",
street: "Radweg 12",
country: CountryCodes.DE,
id: String.Empty,
globalID: new GlobalID(GlobalIDSchemeIdentifiers.GLN, "4000001123452"),
legalOrganization: new LegalOrganization(GlobalIDSchemeIdentifiers.GLN, "4000001123452", "BikeTech GmbH"))
// BG-7
.SetBuyer(name: "CityRider AG",
postcode: "20457",
city: "Hamburg",
street: "Hafenstraße 45",
country: CountryCodes.DE,
id: "DE987654321");
// BT-31
invoice.AddSellerTaxRegistration("201/113/40209", TaxRegistrationSchemeID.FC);
// BT-72 - ActualDeliverySupplyChainEvent
invoice.ActualDeliveryDate = DateTime.Today;
// alternativ: Rechnungszeitraum (BG-14)
// invoice.SetBillingPeriod(
// billingPeriodStart: DateTime.Today.AddDays(-7),
// billingPeriodEnd: DateTime.Today);
FacturXInvoice.SetLicense("...")
Dim invoice = FacturXInvoice.CreateInvoice("Invoice-01",
New DateTime(2025, 9, 3),
Currency.EUR) _
.SetSeller(name:="BikeTech GmbH",
postcode:="10115",
city:="Berlin",
street:="Radweg 12",
country:=CountryCodes.DE,
id:=String.Empty,
globalID:=New GlobalID(GlobalIDSchemeIdentifiers.GLN, "4000001123452"),
legalOrganization:=New LegalOrganization(GlobalIDSchemeIdentifiers.GLN, "4000001123452", "BikeTech GmbH")) _
.SetBuyer(name:="CityRider AG",
postcode:="20457",
city:="Hamburg",
street:="Hafenstraße 45",
country:=CountryCodes.DE,
id:="DE987654321")
' BT-31
invoice.AddSellerTaxRegistration("201/113/40209", TaxRegistrationSchemeID.FC)
' BT-72 - ActualDeliverySupplyChainEvent
invoice.ActualDeliveryDate = DateTime.Today
' alternativ: Rechnungszeitraum (BG-14)
' invoice.SetBillingPeriod(
' billingPeriodStart:=DateTime.Today.AddDays(-7),
' billingPeriodEnd:=DateTime.Today)
Als nächste ergänzen wir eine Position:
invoice.AddTradeLineItem(name: "Trekkingrad",
netUnitPrice: 799.0m,
unitCode: QuantityCodes.C62,
grossUnitPrice: 799.0m,
billedQuantity: 1,
taxType: TaxTypes.VAT,
categoryCode: TaxCategoryCodes.S,
taxPercent: 19,
sellerAssignedID: "BIKE-1");
invoice.AddTradeLineItem(name:="Trekkingrad",
netUnitPrice:=799.0D,
unitCode:=QuantityCodes.C62,
grossUnitPrice:=799.0D,
billedQuantity:=1,
taxType:=TaxTypes.VAT,
categoryCode:=TaxCategoryCodes.S,
taxPercent:=19,
sellerAssignedID:="BIKE-1")
Und den Summenblock inklusive Zahlungsbedingungen:
decimal taxTotalAmount = 799.0m / 100m * 19m;
invoice.AddApplicableTradeTax(basisAmount: 799.0m,
percent: 19m,
taxAmount: taxTotalAmount,
typeCode: TaxTypes.VAT,
categoryCode: TaxCategoryCodes.S);
invoice.PaymentTerms.Add(new PaymentTerms() // BT-20
{
DueDate = DateTime.Today.AddDays(14)
});
invoice.SetTotals(lineTotalAmount: 799.0m,
taxBasisAmount: 799.0m,
taxTotalAmount: taxTotalAmount,
grandTotalAmount: 799.0m + taxTotalAmount,
duePayableAmount: 799.0m + taxTotalAmount);
invoice.Save("e:\\factur-x.xml",
version: ZUGFeRDVersion.Version23,
profile: Profile.Extended);
Dim taxTotalAmount As Decimal = 799.0D / 100D * 19D
invoice.AddApplicableTradeTax(basisAmount:=799.0D,
percent:=19D,
taxAmount:=taxTotalAmount,
typeCode:=TaxTypes.VAT,
categoryCode:=TaxCategoryCodes.S)
invoice.PaymentTerms.Add(New PaymentTerms() With ' BT-20
{
.DueDate = DateTime.Today.AddDays(14)
})
invoice.SetTotals(lineTotalAmount:=799.0D,
taxBasisAmount:=799.0D,
taxTotalAmount:=taxTotalAmount,
grandTotalAmount:=799.0D + taxTotalAmount,
duePayableAmount:=799.0D + taxTotalAmount)
invoice.Save("e:\factur-x.xml",
version:=ZUGFeRDVersion.Version23,
profile:=Profile.Extended)
Export als XML (EN16931 / XRechnung / ZUGFeRD)
Sobald deine Rechnung aufgebaut ist, kannst du sie als XML exportieren:
invoice.Save("factur-x.xml",
version: ZUGFeRDVersion.Version23,
profile: Profile.Extended);
invoice.Save("factur-x.xml",
version:=ZUGFeRDVersion.Version23,
profile:=Profile.Extended)
Typische Profile, die für ZUGFeRD genutzt werden, sind:
- Comfort/ EN16931
- Standard für EU
- Extended
- Ausführlichstes und gebräuchlichstes Profil in Deutschland
Rechnung validieren
Damit Du sicher bist, dass alle notwendigen Angaben enthalten sind, kannst Du die Rechnung mit der Validierungsoberfläche im Kunden-Bereich von factoorsharp.de validieren.
Dies ermöglicht den Empfängern der Rechnung eine reibungslose Verarbeitung.
PDF/A-3 mit eingebetteter Rechnung erzeugen (ZUGFeRD)
Wenn Du eine PDF-Datei, z.B. aus einem Report-Generator oder Deinem ERP-System hast, kannst Du die ZUGFeRD-Informationen direkt in das PDF einbetten:
await FacturXInvoicePdfProcessor.SaveToPdfAsync(
"FacturX-Rechnung.pdf",
ZUGFeRDVersion.Version23,
Profile.Extended,
ZUGFeRDFormats.CII,
"Klassische-PDF-Rechnung.pdf");
Await FacturXInvoicePdfProcessor.SaveToPdfAsync(
"FacturX-Rechnung.pdf",
ZUGFeRDVersion.Version23,
Profile.Extended,
ZUGFeRDFormats.CII,
"Klassische-PDF-Rechnung.pdf")
Ergebnis: Ein visuell lesbares PDF im Format PDF/A-3 inklusive der maschinenlesbaren XML-Datei, die in das PDF-Dokument eingebettet ist.
Bestehende Rechnungen einlesen
FactoorSharp kann auch bestehende Rechnungen analysieren. Dabei ist es egal, ob eine XML-Datei eingelesen wird:
var invoice = FacturXInvoice.CreateInvoice("Invoice-01",
new DateTime(2025,09,03),
Currency.EUR)
.SetSeller("BikeTech GmbH", "10115", "Berlin", ...)
.SetBuyer("City Bikes AG", "20457", "Hamburg", ...);
invoice.AddTradeLineItem("Trekkingrad",
799.0m,
QuantityCodes.C62,
1);
invoice.Save("factur-x.xml",
version: ZUGFeRDVersion.Version23,
profile: Profile.Extended);
Dim invoice = FacturXInvoice.CreateInvoice("Invoice-01",
New DateTime(2025, 9, 3),
Currency.EUR) _
.SetSeller("BikeTech GmbH", "10115", "Berlin", ...) _
.SetBuyer("City Bikes AG", "20457", "Hamburg", ...)
invoice.AddTradeLineItem("Trekkingrad",
799.0D,
QuantityCodes.C62,
1)
invoice.Save("factur-x.xml",
version:=ZUGFeRDVersion.Version23,
profile:=Profile.Extended)
Oder die XML-Datei aus einer PDF-Datei ausgelesen werden muss:
var invoice = FacturXInvoice.CreateInvoice("Invoice-01",
new DateTime(2025,09,03),
Currency.EUR)
.SetSeller("BikeTech GmbH", "10115", "Berlin", ...)
.SetBuyer("City Bikes AG", "20457", "Hamburg", ...);
invoice.AddTradeLineItem("Trekkingrad",
799.0m,
QuantityCodes.C62,
1);
invoice.Save("factur-x.xml",
version: ZUGFeRDVersion.Version23,
profile: Profile.Extended);
Dim invoice = FacturXInvoice.CreateInvoice("Invoice-01",
New DateTime(2025, 9, 3),
Currency.EUR) _
.SetSeller("BikeTech GmbH", "10115", "Berlin", ...) _
.SetBuyer("City Bikes AG", "20457", "Hamburg", ...)
invoice.AddTradeLineItem("Trekkingrad",
799.0D,
QuantityCodes.C62,
1)
invoice.Save("factur-x.xml",
version:=ZUGFeRDVersion.Version23,
profile:=Profile.Extended)
Migration von ZUGFeRD-csharp
FactoorSharp ist der Nachfolger von ZUGFeRD-csharp.
Wenn du bereits damit arbeitest:
- API ist bewusst ähnlich gehalten
- Bestehende Logik lässt sich meist direkt übernehmen
- Tausche InvoiceDescriptor durch FacturXInvoice, InvoicePdfProcessor durch FacturXInvoicePdfProcessor. Fertig.
- Neue Features: bessere Validierung, neue Funktionen