Mustang was originally implemented in Java but from April 2022-2025 there was also a version in .net. It was open source and AGPL-licensed and has been completely merged into Ghostscript.net in 2025.
It will not support ZUGFeRD version 1 and no validation, and for the time being it does not yet support Order-X, Allowances/Charges, Embedded files, corrected invoices, credit notes or references e.g. to shippings, contracts or other documents.
But it does support XRechnung, ZUGFeRD 2 and Factur-X and arbitrary PDF input, so you can even use it if you don’t even have a PDF/A-document.
The conversion from PDF into PDF/A-3 can also be used separately.
Mustang+.net can be used quite similar to Mustang+Java:
using Ghostscript.NET.PDFA3Converter.ZUGFeRD;
using System.IO;
using java.math;
Invoice i = (new Invoice()).setDueDate(DateTime.Now).setIssueDate(DateTime.Now).setDeliveryDate(DateTime.Now).setSender((new TradeParty("Test company","teststr","55232","teststadt","DE")).addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test","+49123456789","test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890","COBADEFXXX"))).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setReferenceNumber("991-01484-64").setNumber("123").
addItem(new Item(new Product("Testprodukt", "", "H87", new BigDecimal(19)), new BigDecimal("1.0"), new BigDecimal("1.0")));
ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
zf2p.generateXML(i);
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
string outfilename="xrechnung.xml";
File.WriteAllBytes(outfilename, zf2p.getXML());
Just replace Date by System.DateTime, and the ZUGFeRDExporterFromPDFA1 requires a String constructor argument, the path to your Ghostscript native .dll file.
With the above invoice object of course you can also write a Factur-X/ZUGFeRD PDF file using
ZUGFeRDExporter ex=new ZUGFeRDExporter("gsdll64.dll").load("blanko.pdf");
ex.setTransaction(i);
ex.export("factur-x.pdf");
For a test you can use our MustangBlanko PDF-A/1 file but in Mustang.net the source can also be a plain pdf file.
To confirm the XML amounts match your amounts, you can e.g. use
TransactionCalculator tc=new TransactionCalculator(i);
...tc.getGrandTotal()...
For arbitrary precision, “java.math”‘s BigDecimal, i.e. the OpenJDK.BigMathNET package is used. In the .csproj the following itemgroup entries make sense:
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="itext7" Version="7.2.1" />
<PackageReference Include="OpenJDK.BigMathNET" Version="1.0.2.1" />
<PackageReference Include="Ghostscript.NET" Version="1.3.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.4" />
</ItemGroup>
For community support – and as recipient for potential PRs – please refer to Ghostscript.NET.