Quick start: create a ZUGFeRD invoice in VB.NET and embed it in PDF/A-3

SDK members
AddPaymentMeans() AddProduct_Comfort() AddTradePaymentTerms() AddTradeTax() BuyerAddressLine1 BuyerCity BuyerCountry BuyerName BuyerPostCode CreateInvoice()
Business terms
BT-1 Invoice number BT-2 Invoice issue date BT-5 Invoice currency code BT-31 Seller VAT identifier BT-81 Payment means type code BT-20 Payment terms BG-25 Invoice line BG-23 VAT breakdown
Code samples
VB.NET
Published

This quick start shows the complete path to an EN 16931 e-invoice with the Aloaha ZUGFeRD SDK: create the object, set the invoice header, seller and buyer, payment, one line item, VAT and totals – then save the XML and embed it in a PDF/A-3. The example is an invoice for 10 × EUR 5.00 net at 19 % VAT.

1. Create the object and choose the profile

Dim LicenseKey As String = "YOUR-LICENCE-KEY"   ' trial licence: info@aloaha.com
' fix the number format culture for the conversion
Dim culturebackup = System.Threading.Thread.CurrentThread.CurrentCulture
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.GetCultureInfo("de-DE")

Dim alo As New Aloaha_ZUGFeRD.XML(Aloaha_ZUGFeRD.iXML.ZUGFeRDProfile.comfort, False, LicenseKey)   ' profile EN 16931 (COMFORT)

For an XRechnung to German public authorities, also set alo.isKOSIT = True and alo.LeitwegID. Which profile fits is explained in the profile comparison.

2. Invoice header

alo.CreateInvoice("RE-2026-0001", "Invoice as per order", alo.TodayDate.Document_Date, alo.TodayDate.Document_DateFormat, , "", "EUR")
alo.InvoiceCurrencyCode = "EUR"                          ' BT-5
alo.Document_Type = Aloaha_ZUGFeRD.iXML.DocumentType.Invoice

The second parameter of CreateInvoice is an invoice note (BT-22), not the invoice type. Set the type (BT-3) afterwards with Document_Type.

3. Seller and buyer

' seller with VAT ID (BT-31)
alo.WriteSeller("Muster GmbH", "20095", "Hamburg", "Hauptstr. 1", "", "DE", "DE123456789")
alo.WriteSellerContactPerson("Erika Muster", "Sales", "sales@muster.example", "+49 40 123456")
alo.set_URIUniversalCommunication("invoice@muster.example", "EM", True)    ' BT-34

' buyer
alo.BuyerName = "Kunde AG"
alo.BuyerAddressLine1 = "Marktplatz 5"
alo.BuyerPostCode = "80331"
alo.BuyerCity = "München"
alo.BuyerCountry = "DE"
alo.set_URIUniversalCommunication("purchasing@kunde.example", "EM", False)     ' BT-49

4. Payment

alo.AddPaymentMeans(alo.PaymentMeansCode(Aloaha_ZUGFeRD.iXML.Payment_Means.SEPA_credit_transfer), "SEPA credit transfer", "DE02120300000000202051", "Muster GmbH", "", "BYLADEM1001", "", "", False)
alo.AddTradePaymentTerms("Payable within 30 days net")       ' BT-20
alo.PaymentReference = "RE-2026-0001"

5. Invoice line

Dim VatCat As String = alo.VatCategoryCode(Aloaha_ZUGFeRD.iXML.VAT_Category.StandardRate)
alo.AddProduct_Comfort("1", "", "ART-100", "10.00", "C62", "Paper A4", "500 sheets",
                       "", "EUR", "", "C62", False, "", "", "", "5.00", "EUR", "1.00",
                       "C62", "VAT", VatCat, "19.00", "", "50.00", "EUR", "", "")

Units of measure are fixed codes (UN/ECE Recommendation 20, e.g. C62 = piece). All parameters of AddProduct_Comfort are explained in the article Adding invoice lines with AddProduct_Comfort (German).

6. VAT and totals

' VAT breakdown (BG-23): 19 % on EUR 50.00
alo.AddTradeTax("9.50", "EUR", "50.00", "EUR", "VAT", VatCat, "19.00")

' totals (BG-22): line total, grand total, amount due, tax basis, tax
alo.WriteTotals("50.00", "59.50", "59.50", "50.00", "9.50")

If the invoice has allowances, the tax basis is the net amount after allowances – see BR-S-08, BR-S-09 and BR-CO-17.

7. Save the XML and embed it in PDF/A-3

alo.SaveXML("C:\Invoices\RE-2026-0001.xml")
If alo.Last_Error <> "" Then Console.WriteLine(alo.Last_Error)

' hybrid ZUGFeRD invoice: embed the XML into your existing PDF invoice
alo.MergeXMLIntoPDF("C:\Invoices\RE-2026-0001.xml", "C:\Invoices\RE-2026-0001.pdf",
                    "C:\Invoices\RE-2026-0001_zugferd.pdf", True, "", LicenseKey)

System.Threading.Thread.CurrentThread.CurrentCulture = culturebackup

If you do not have a PDF yet, create it with CreateDocFromXML directly from the XML and a DOCX template – see merging ZUGFeRD XML with a DOCX template (German). A larger example with allowances and two VAT rates is the sample code for XRechnung.

Other languages: Delphi, VB6, VB5 and VBA, or without programming against the SDK: CSV and zugcmd.

Frequently asked questions

Does this also work with C# or VB6?

Yes. The Aloaha ZUGFeRD SDK is a .NET library with a COM interface; the same methods are available in C#, VB.NET, VB6/VBA and other COM-capable languages.

Which profile should I use?

For most B2B invoices the EN 16931 (COMFORT) profile; for German public authorities the XRechnung (isKOSIT = True plus Leitweg-ID).

How do I find errors in the generated invoice?

After SaveXML, Last_Error contains an error message if the file could not be created. To check the content, validate the XML against the EN 16931 and XRechnung rules.

Business terms in this article: BT-1 BT-2 BT-5 BT-31 BT-81 BT-20 BG-25 BG-23 BG-22 BT-34 BT-49 BT-10