ZUGFeRD 2.2-2.3.x import for Dynamics 365 for Finance

ZUGFeRD 2.2-2.3.x import for Dynamics 365 for Finance

ZUGFeRD (Zentraler User Guide des Forums elektronische Rechnung Deutschland) is an e-invoicing format combining a human-readable PDF/A-3 and an embedded XML file using the CII (Cross-Industry Invoice) syntax. The CII syntax may also be used in the xRechnung, which is a pure XML version of the German e-Invoice. From 2025, the ability to receive and process electronic invoices becomes mandatory for B2B transactions in Germany.

Microsoft’s current solution in Dynamics 365 for Finance provides support specifically for the UBL (Universal Business Language) format of the xRechnung: Import vendor electronic invoices – Finance | Dynamics 365 | Microsoft Learn. It enables the import of vendor invoices received in this format, mapping them as pending vendor invoices in D365. The invoice may be uploaded directly into the system or placed in a SharePoint folder for unattended processing.

We are happy to announce the release of the CII (Cross-Industry Invoice) dialect of the xRechnung / ZUGFeRD electronic invoice. This solution is implemented via Electronic Reporting (ER) configurations, which means it does not require any customisations and can be easily installed across all active versions of D365. It sits on top of the standard Invoice model v280, Vendor Invoice Mapping to Destination v280.46, side by side with the configuration Vendor Invoice Import v280.7.

The functionality aligns with the standard Microsoft UBL import, utilizing the key data elements for processing and ensuring PO matching:

  • Header: Invoice ID, Invoice date, Due date, Vendor ID, Currency code, PO number, a header-level note and header attachments (in XML embedded MIME documents).
  • Lines: Line number, Item ID, Quantity, Sales unit of measure, Sales price, Discount (percentage discounts are converted to absolute values as the XML schema doesn’t support percentages), Price unit, Name, Description, and Line amount (excluding VAT).

The solution supports the ZUGFeRD 2.2 or ZUGFeRD 2.3.x / Factur-X 1.0x with the profile EN 16931 (also known as the “COMFORT” profile) or the EXTENDED profile. Both meets all tax law requirements and must be accepted by customers unless explicitly denied.

In contrary, ZUGFeRD 1.0 is no longer permitted in Germany when it comes to complying with the current legal requirements for electronic invoices, and therefore not supported.

Price

The solution is offered at a fixed fee per end customer / D365 tenant:
VersionPriceDeliverablesNotes
Light€890The Vendor invoice import CII Electronic Reporting configurationThis option does not require any X++ customisations or 3rd party software and can be installed and used right away.
Light+€1200Same as the Light version but with 5 hours of prepaid support and installation 

Your can acquire the solution on the official Microsoft AppSource marketplace: ZUGFeRD CII import (microsoft.com)

 

Setup and use

 
  1. Follow the steps outlined in the Microsoft’s guidance Import vendor electronic invoices – Finance | Dynamics 365 | Microsoft Learn:
  2. Import the same three configurations from Microsoft (Prerequisites);
  3. Import the configuration Vendor invoice import CII.xml provided to you;
  4. Open Accounts payable > Setup > Accounts payable parameters; on the Electronic documents tab, select the imported Vendor invoice import CII format.
  5. To run either one of the formats – UBL or CII – by choice, you may download and import a complimentary X++ extension with an additional parameter CII vendor invoice and an own menu item underneath the standard one: VendImportInvoice_CII.axpp. In the batch execution mode this does not matter, because each of the formats becomes its own Electronic source with a set of SharePoint folders etc.
  6. Prepare the master data: make sure the vendors are stored with proper VAT numbers in Dynamics 365 for Finance.
  7. Make sure that the vendor’s external item ID mapping exists. Any Buyer Assigned ID (our item number) potentially sent by the vendor is neglected by the Microsoft’s mapping, and the conversion to the internal Item ID is always handled via the external item IDs. Under these conditions, the import works as expected and the PO lines may be matched.
  8. Make sure that the units of measure are properly mapped to the UNECE Recommendation No. 20 list called “Codes for Units of Measure Used in International Trade”. E.q. the UNECE unit H87 must be mapped to either PCS or EA or STK, see also a longer list in https://erconsult.eu/de/blog/aktueller-stand-der-erechnung-in-d365-for-finance-deutschland/
  9. Perform an interactive test upload by using the function Accounts payable > Periodic tasks > Import vendor invoices (or Import CII vendor invoices if you installed and configured the above extension from step 5). Beware: contrary to the UBL format, the CII (“COMFORT”) invoice does not include any line-by-line reference to the purchase order lines. Just the PO number is sent in the header. We assume that the numeration of the invoice lines mostly follows the PO lines numeration. If not, the standard mapping will fall back to the matching by the line purchase price.
  10. Configure the batch mode with Electronic sources as outlined in the guidance at step 1.

Useful links

Austrian Peppol-UBL e-invoice

E-Invoice in D365
E-Invoice in D365

Austrian Peppol-UBL e-invoice

…in its version 304.13.25 does not work out of the box in Dynamics 365 for Finance, unfortunately. First and foremost, the public entity’s order number (the Customer requisition at the sales header order or in the project contract funding source details) is a must! As you specify the Customer requisition, a reference to the PO line number reference becomes mandatory, too. Yet this invoice line-level field is either malformed or missing. Moreover, Austria always requires an email address of the supplier (us) which is disabled or not working in all 4 standard ER formats. This can be the default e-mail address of the company in the legal entity settings.

As a good start, I recommend the excellent blog series E-Invoice in D365FO for Norway – Part 1 (Intro) – DynFOTech

The core configuration includes specifying the Endpoint ID of the supplier (ours) under Bank account / Routing number in the legal entity parameters, and providing the conversion of the units of measure into the UN standard, see the blog above.  For every unit of measure there must be an own Code ‘axis’ to compensate for the well known design flaw in the external code values cardinality in Dynamics 365 for SCM:

Then, to finally make it work, you have to extend all 4 standard electronic formats from Microsoft and make at least the following changes:

Format changes

Issue/Deficiency Path Peppol Sales invoice Peppol Project Invoice Peppol Sales Credit Note Peppol Project Credit Note
Mandatory Seller/ElectronicMail cac:AccountingSupplierParty/cac:Party/cbc:ElectronicMail must be enabled all the way down, and mapped like this: IF(Invoice.InvoiceBase.CompanyContact.ElectronicMail<>"", Invoice.InvoiceBase.CompanyContact.ElectronicMail, Invoice.InvoiceBase.CompanyInfo.Email) IF(ProjectInvoice.InvoiceBase.Contact.ElectronicMail<>"", ProjectInvoice.InvoiceBase.Contact.ElectronicMail, ProjectInvoice.InvoiceBase.CompanyInfo.Email) IF(Invoice.InvoiceBase.CompanyContact.ElectronicMail<>"", Invoice.InvoiceBase.CompanyContact.ElectronicMail, Invoice.InvoiceBase .CompanyInfo.Email) IF(ProjectInvoice.InvoiceBase.Contact.ElectronicMail<>"", ProjectInvoice.InvoiceBase.Contact.ElectronicMail, ProjectInvoice.InvoiceBase.CompanyInfo.EMail)
Wrong OrderLineRef.ID, namely taken from ProjTransId = alphanumeric instead of numeric Every of the five cac:InvoiceLine/cac:OrderLineReference/cbc:LineID must be unique and therefore enumerated. In the the Project Credit note the tags are missing completely and need to be added from scratch (5x) ('$ATLineNumberCollection'.Collect(1) + '$ATLineNumberCollection'.Sum(false))-1 ('$ATLineNumberCollection'.Collect(1) + '$ATLineNumberCollection'.Sum(false))-1
Missing PaymentMeans, i.e. our (beneficiary) bank account cac:PaymentMeans/cac:PayeeFinancialAccount/cbc:ID, schemeID and .../cac:FinancialInstitutionBranch/cbc:ID must be enabled all the way down and mapped ProjectInvoice.InvoiceBase.CompanyInfo.BankAccount.IBAN ProjectInvoice.InvoiceBase.CompanyInfo.BankAccount.SWIFT
Missing OrderReference (their PO number) cac:OrderReference/cbc:ID must be enabled Invoice.PurchaseOrder
Missing or wrongly formatted line quantity; the sign is properly displayed in Denmark only 🙂 cac:CreditNoteLine/cbc:CreditedQuantity must be enabled IF(OR(Invoice.InvoiceBase.CompanyInfo.PostalAddress.Country="DK", Invoice.InvoiceBase.CompanyInfo.PostalAddress.Country="AT"), -(@.LineBase.Quantity), @.LineBase.Quantity) -(@.LineBase.Quantity)
The ActualDeliveryDate ("Leistungsdatum") refers to the date or the corrected invoice. The data is not really known and not properly mapped, here is a stub: cac:Delivery/cbc:ActualDeliveryDate is completely missing and needs to be added first Invoice.InvoiceBase. ShipmentDate ProjectInvoice. InvoiceBase.VATRegisterDate
The root node bears no name, hence the format cannot be assigned a destination Call the root node "XMLHeader", for example X X

With regards to the collection $ATLineNumberCollection for the enumeration of invoice lines, refer to respective blog below.

Useful links

 

ZUGFeRD 2.3.x export / Factur-X 1.07.x for Dynamics 365 FO

ZUGFeRD 2.3.x export / Factur-X 1.07.x for Dynamics 365 FO

We are excited to announce the release of the common German-French electronic invoice ZUGFeRD / Factur-X in Dynamics 365 for Finance and SCM. This plug-and-play solution in its “Light” version does not require any customisation and can be easily installed in the standard Electronic Reporting module of D365. It supports the ZUGFeRD 2.2-2.3.3 / Factur-X 1.07.2-3 profile EN 16931, also known as the “COMFORT” profile, “BASIC” and the “EXTENDED” profile. Both profiles meet all tax law requirements and must be accepted by customers unless explicitly denied.

In the ZUGFeRD/Factur-X standard, the invoicing information is included in an XML payload attached to a human-readable PDF file (see https://de.wikipedia.org/wiki/ZUGFeRD). This is in contrast to the Italian electronic invoicing system, where a PDF is embedded in a Base64 encoded block within an XML. The PDF document is just a visualisation of the electronic content, what counts is the XML attachment. The XML file is always named factur-x.xml and it is attached to at the PDF document level, not to a single PDF page:

Here is an example: factur-x.xml

Our solution, which utilizes Configurable business documents in D365, supports Sales invoices with separate buyer, seller, and order accounts, as well as the Free text invoice. Other types of invoices such as the Project invoices, can be provided upon request at a discounted price. Our solution also handles form notes, line and header notes and footers, line discounts, total discounts, and cash discounts, document level and line level charges, properly reflecting VAT for domestic, EU, and export sales. The settlement instructions orchestrate a SEPA credit transfer or a SEPA direct debit withdrawal; partially prepaid invoices are properly interpreted.

In addition, the EXTENDED profile introduces structured cash discounts, HS (customs Harmonized System = Intrastat) codes, countries of origin, standardised VATEX exemption codes, and more. To ensure backward compatibility and in response to customer requests, support for the BASIC and XRECHNUNG profiles has also been added.

The solution is available in French, German, British and American English, Spanish. The PDF itself may be rendered in German, French, Britisch and American English, Spanish and Dutch.

Price

The solution is offered at a fixed fee per end customer / D365 tenant:
VersionPriceDeliverablesNotes
Light€890A ZUGFeRD Sales invoice ER configuration, the XML file onlyThis option does not require any X++ customisations or 3rd party software and can be installed and used right away.
Light+€1200Same as the Light version but with 5 hours of prepaid support and installation 
Heavy€2200Contains the full solution, including a PDF template, and a PDF post-processor with 8 hours of prepaid support.Includes the iTextSharp 5.5.13.2 .NET library under the GNU Affero General Public License
Includes the BouncyCastle 1.8.9 .NET cryptographic library under a variant of the MIT license.

You may acquire the solution on the official Microsoft App Source portal: https://appsource.microsoft.com/en-us/product/dynamics-365-for-operations/er-consultgmbh1674479095356.zugferd_light_plus

Setup and use

 

Basic setup: “Light” and “Heavy”

  1. For the ease of installation, configuration and integration, the standard Invoice model Invoice model v 277 and the standard Invoice model mapping are used (the recent mapping is 277.273 as of 31.03.2025 ), make sure they have been imported upfront. 
  2. Import the Electronic configuration “ZUGFeRD Sales invoice” provided to you (Organisation administration > Electronic reporting > Configurations, button Exchange / Load from XML file). Optionally, import the custom Invoice model mapping (ZUGFeRD), see below, and the “ZUGFeRD Free text invoice“. 
  1. Under the button Configurations / Application specific parameters / Setup, provide a mapping of the VAT (en-us: Sales tax) Print codes to the ZUGFeRD categories S, K, AE, G, O (for example, the 19% and 7% VAT belong to the “S” category). Also provide a mapping of the D365 Unit of measure codes to the UNECE Recommendation No. 20 list called “Codes for Units of Measure Used in International Trade” (see Codes for Units of Measure used in International Trade: Recommendation N°.20 – Revision 7 | UNECE). For instance, a piece has the standard code H87. A sample parameter setup can be downloaded here: 03-01-2023 03.29.45 pm_ZUGFeRD Sales invoice.277.11 Once both the mappings have been established, set the Application specific parameters State to Completed.
  2. Pay attention to the sample VAT print codes on the screenshot above: the standard Invoice model mapping does not pass the tax rates to the report, and the VAT Print code must contain the VAT rate in numbers, if applicable. In other words, they should look like “19%” and “7%” in Germany or “20%” and “5,5%” in France.

The current Microsoft Invoice model mapping Sales invoice does not pass the EU Tax directives into the report. By default, the report relies on the non-EU Tax exempt codes in the same way as the standard Excel invoice does. The provided Invoice model mapping (ZUGFeRD) changes that and makes the Tax directives available. Should there be both a Tax directive and an Exemption code in your VAT setup, the Exemption code wins and it will be shown in the tag

<ram:ApplicableTradeTax>
...
<ram:ExemptionReason>Tax-free EC shipments with tax registration number</ram:ExemptionReason>
...
</ram:ApplicableTradeTax>

  1. The mapping of the sales units of measure is against the language-specific, translated unit texts (if exists), not the UoM symbol used in D365 globally, i.e. not pcs but Stk. You may find them in the Organization administration > Setup > Units form, button Unit texts. This Stk. then becomes H87 in the output file. The configuration translates the local units of measure to one of the H87, KGM, MTR, LTR, TNE, CMT, HUR, DAY, GRM, MIN, MON, WEE, MMT, SEC, C26, YRD, APZ, FOT, GLL, INH, ONZ, LBT.

The Years class is used as a fallback: no translation is applied and the unit text falls through as it is; for example, a UN mapped to Years remans UN in the output file.

To perform some post-processing, translate one unit to many as 1:N (for example, the unit ea may be translated to either C62 - an abstract units of service - or pieces H87 depending on the context), you may derive your own format version from the ZUGFeRD Sales invoice and extend the formula model.InvoiceLines.$SalesUnit2UN in the format Mapping.

ZUGFeRD Form setup

  1. Open Sales ledger (en-us: Accounts receivable) > Setup > Forms > Form setup. Make sure that the VAT specification option is set to Registration currency. You may also wish to display external item numbers: Item number in forms = Both.
  2. On the Invoice and Free text invoice tabs, make sure the option Print VAT number on invoice is ON: it is mandatory.  The option Print delivery note specifications should be better set, too: it populates the <ActualDeliverySupplyChainEvent> and the <DeliveryNoteReferencedDocument> tags. The Include documents…  parameters activate the display of line and header notes.

Show in sheet: Configuration, Size etc. activates the line inventory dimensions, where the [translated] name becomes the Description and the code becomes the Value of an ApplicableProductCharacteristic:


<ram:ApplicableProductCharacteristic>
<ram:Description>Size</ram:Description>
<ram:Value>1440</ram:Value>
</ram:ApplicableProductCharacteristic>

  1. Finally, open Print management and select the Report format = ZUGFeRD Sales invoice at the Customer invoice node. Specify a Footer, too. Repeat it for the the ZUGFeRD Free text invoice, if needed. 
  2. Create a new ER destination (Organisation administration > Electronic reporting > Electronic reporting destination) for the report ZUGFeRD Sales invoice, and the ZUGFeRD Free text invoice if needed. Under File destination, add a new line, choose the factur-x file component and divert it to a destination of your choice (for instance, the Screen).
The Light version setup ends here.
 
 

Supplementary setup: “Heavy”

  1. For the Heavy version, first deploy the X++ customisations and libraries from the D365 deployable package provided to you.
  2. Create a new File document type in the Organisation administration > Document management > Document types list. Set the Name of the document type exactly like this: ZUGFeRD.
  3. In the ER destination (see 9 above) this time choose the ZipFolder file component. Click Settings. To show the invoice on the Screen, divert the file to the Archive: set Enabled and Save in job archive, and choose file Type = ZUGFeRD.
  1. To send the invoice per Email, add a new file destination line, click Settings, open the tab ZUGFeRD, and flip the Email slider. In the Email ID parameter, you may also select an Organisation administration > Setup > Organisation email template with an appropriate subject and a HTML body in your corporate design. Placeholders%ExchangedDocument% (invoice ID), %DuePayableAmount% (invoice amount) and %BuyerTradeParty% (customer ID) are supported out of the box i.e., the email subject and body of the email are dynamic. The selection Document type in this ER destination must remain Any or Electronic. ZUGFeRD ER destinations: Email
  2. The steps to configure the Heavy version end here. The Electronic Reporting engine will fill out the PDF form, populate an XML file and put both into a folder (i.e. a ZIP). This ZIP file is intercepted, unpacked, and the XML part is embedded into the PDF, adding some references and mandatory attributes. The PDF file is not fully PDF-A/3 compliant, but it can be read and parsed, the XML payload passes the validations (see the links below).
  3. Print the sales invoice with the option Use print management turned on. The resulting PDF document is rendered on the screen (the Light version offers an XML file to download) in a separate browser window or sent per e-mail to the email contact of the customer with the role Invoice. In the batch invoicing mode (de: “Autofaktura”), the Screen destination is obsolete.
  4. You may also re-print invoices out of the Invoice journal form (Sales ledger > Enquiries and reports > Invoices > …) with the button View.

An example of a ZUGFeRD invoice with the COMFORT profile may be found here: ZUGFeRD_COMFORT.pdf

Custom Mapping and the EXTENDED profile

The EXTENDED profile, compared to the ‘EN16932’ profile (also known as the ‘COMFORT’ profile), adds the following elements

  • Structured payment terms, such as cash discounts in %;
  • Serial numbers, batch numbers per line (not present on a Free text invoice a.k.a. “FTI”);
  • Delivery note numbers and dates per line (not present on a FTI);
  • Customer’s PO reference per line;
  • Ship to party (a deviating shipping address, see below);
  • Package quantity (per line only, not present on a FTI);
  • <ExemptionReasonCode> i.e., the reason for exemption from VAT obligation provided as a CEF VATEX code.

In the Root of the ZUGFeRD Sales invoice format mapping, a variable “Profile” is introduced. It acts as a profile selector. By default, it returns the number “3” for the COMFORT (=EN 16931) profile. The values “2”, “3”, “4” and “5” are reserved for the profiles BASIC, EN 16931, XRECHNUNG, and EXTENDED, respectively.

For example, to switch to the EXTENDED profile, derive your own version of the format, select the Profile node to the left, click Edit and let the formula return “5”.

Through a derived mapping, this variable may be even tied to a property of the customer (a CustTable field, for example) to act as a dynamic selector of the profile.

For the EXTENDED profile to function, the custom Invoice model mapping (ZUGFeRD) is necessary. The same custom mapping enables some features of the COMFORT and XRECHNUNG profiles, for example the country of origin or the HS code, or the city name. For the reasons of compatibility, these features – even though they belong to the COMFORT profile – are unlocked by the Profile > 3, too.

Below are additional steps to get the most of the EXTENDED profile:

 
  1. Deploy the Electronic configuration “Invoice model mapping (ZUGFeRD)” (Organisation administration > Electronic reporting > Configurations, button Exchange / Load from XML file).
  2. Select it in the ER tree, and make it Default for model mapping to resolve the ambiguity between the custom and the standard Invoice model mapping.
  3. To embed HS codes and the country of origin into the <DesignatedProductClassification> tag, make sure  the Commodity code and the Country/region are populated at Product information management > Products > Released products.
  1. For the batch and serial numbers to appear in the <IndividualTradeProductInstance> node, mark Show in sheet: Batch number and/or Serial number on the Invoice tab in the Form setup form (see the screenshot in the previous section).
  2. For the output of the commercial register (de: Handelsregister or HRB) number, a dedicated Registration type must be given the Czech (!) category “Spisova znacka” under Organization administration > Global address book > Registration types > Registration categories (this is how the standard free text invoice works 🙂
This registration record must be added to the primary address of the legal entity (see Organisation administration > Organisations > Legal entities, look for the Registration ID button, enter the Registration number and the Issuing agency there). The validity date of this registration cannot be changed, it becomes effective from the date of the entry onwards. Ultimately, it appears in a note of the REG type as intended by the maintainers of the ZUGFeRD standard:
 
   <ram:IncludedNote>
      <ram:Content>Landesgericht Eisenstadt 533252 w</ram:Content>
      <ram:SubjectCode>REG</ram:SubjectCode>
    </ram:IncludedNote>
  1. Before leaving the Organisation administration > Organisations > Legal entities form, check if the company Bank account is populated, and this bank account has an IBAN and a SWIFT code.
This concludes the EXTENDED setup. Check out the sample below, you buy what you see!

 Useful links

Extensibility

To implement a custom invoice design with a corporate logo, a certain colour palette or fonts, extend the ER configuration “ZUGFeRD Sales invoice” as any other ER configurable business document. Derive an own configuration, then extract, amend and replace the PDF template attached to the ER configuration version.
 
Please bear in mind that PDF forms do not contain dynamic, repeatable ranges or cells (refer to Design ER configurations to fill in PDF templates – Finance & Operations | Dynamics 365 | Microsoft Learn for more details). This is the reason why the number of invoice lines is limited by the PDF template; change the constants Paginator.#LinesMax, #LinesOnFirstPage and #LinesOnNextPages in accordance with the template to let Dynamics control the number of pages. 
 

The “output actions” are extendable: new output actions may be offered upon request at a discounted price. You may even implement your own /Class/ERFileOutputActionXXX_ZUGFeRD, for example:

				
					/// <summary>
/// Send the resulting PDF to a browser window interactively
/// </summary>
[ERFileOutputAttribute_ZUGFeRD(SRSPrintMediumType::Screen)]
class ERFileOutputActionScreen_ZUGFeRD extends ERFileOutputAction_ZUGFeRD
{
    /// <summary>
    /// The screen destination does not need to extract any contact info
    /// </summary>
    /// <returns>An empty visitor class</returns>
    public ERFileOutputActionXmlVisitor_ZUGFeRD makeVisitor()
    {
        return new ERFileOutputActionXmlVisitor_ZUGFeRD();
    }

    /// <summary>
    /// Display  the PDF file formed by ERFileDestinationPostProcessor_ZUGFeRD on the screen 
    /// </summary>
    /// <param name = "_outputPDF">Stream with a PDF file, with a CII XML attached</param>
    /// <returns>Success or failure to display</returns>
    public boolean sendFile(System.IO.MemoryStream _outputPDF)
    {
        Browser br = new Browser();
        
        str downloadUrl = File::SendFileToTempStore(_outputPDF,
                                                    ERConstants_ZUGFeRD::ZUGFeRD_Filename,
                                                    classstr(FileUploadTemporaryStorageStrategy),
                                                    true);
        if (downloadUrl != '')
        {
            br.navigate(downloadUrl, true, false);
        }
        else
        {
            return checkFailed("@ApplicationPlatform:DownloadFailed");
        }
        return true;
    }

}