Foreign currency invoice
An invoice in GBP whose tax amount is additionally stated in EUR – including the exchange rate and its date. Plus a tax representative, a separate payee, an invoicing period, a prepayment and line-level allowances.
The basis is the official sample invoice
X07_01_Fremdwaehrung from the Factur-X / ZUGFeRD
documentation (FeRD sample package, ZUGFeRD 2.5.0, EXTENDED profile).
The code below produces exactly that document, field by field and in the
same order.
Some links on this page lead into the in-depth documentation in the customer area and require a sign-in.
This is the most demanding of the three sample documents: it brings together in one file what is otherwise spread across many pages. If you are building an EXTENDED document for the first time, the extended goods invoice is the better starting point; this page is about the special cases.
What this example covers
- Two currencies: invoice currency GBP (BT-5), accounting currency EUR (BT-6)
- The tax amount twice – once per currency (BT-110 and BT-111) – plus the exchange rate (BG-X-41)
- Seller tax representative (BG-11) and a separate payee (BG-10)
- Allowances at line level as
SpecifiedTradeAllowanceCharge - Invoicing period (BT-73/BT-74) and a prepayment (BT-113)
1. Invoice header and the two currencies
The decisive line is invoice.TaxCurrency. All amounts in the
document are stated in the invoice currency BT-5, here GBP; the accounting
currency BT-6 concerns only the additionally stated tax amount.
// BT-5 invoice currency is GBP – all amounts are stated in THIS currency.
FacturXInvoice invoice = FacturXInvoice.CreateInvoice(
invoiceNo: "47110815",
invoiceDate: new DateTime(2025, 12, 1),
currency: CurrencyCodes.GBP);
invoice.Type = InvoiceType.Invoice;
invoice.Name = "RECHNUNG"; // BT-X-2
invoice.BusinessProcess = "Beispielgeschäftsprozess"; // BT-23
// BT-6: accounting currency. As soon as it is set and differs from BT-5, EN 16931
// expects the tax amount to be stated in this currency as well.
invoice.TaxCurrency = CurrencyCodes.EUR;
' BT-5 invoice currency is GBP – all amounts are stated in THIS currency.
Dim invoice As FacturXInvoice = FacturXInvoice.CreateInvoice(
invoiceNo:="47110815",
invoiceDate:=New DateTime(2025, 12, 1),
currency:=CurrencyCodes.GBP)
invoice.Type = InvoiceType.Invoice
invoice.Name = "RECHNUNG" ' BT-X-2
invoice.BusinessProcess = "Beispielgeschäftsprozess" ' BT-23
' BT-6: accounting currency. As soon as it is set and differs from BT-5, EN 16931
' expects the tax amount to be stated in this currency as well.
invoice.TaxCurrency = CurrencyCodes.EUR
2. Free-text notes
The code TXD (tax information) tells the human reader why two
currencies appear in the document at all – a useful complement to the
structured fields further down.
Line breaks and indentation inside a note are significant in the XML. The tabs in the first call are not decoration – they are taken character for character from the reference file, and without them the cross-check reports a difference.
// The first note spans several lines. Line breaks and indentation are significant in
// the XML – these are exactly the tabs the reference file contains.
invoice.AddNote("Mitglieder der Geschäftsleitung\n\t\t\t\tH. Meier Geschäftsführer"
+ "\n\t\t\t\tT. Müller Prokurist\n\t\t\t\tHRB Braunschweig 12345",
subjectCode: SubjectCodes.REG);
invoice.AddNote("Vom 17. Dezember 2025 bis 6. Januar 2026 haben wir Betriebsferien.",
subjectCode: SubjectCodes.AAI);
// TXD = tax information. Tells the reader why two currencies appear at all.
invoice.AddNote("Aus konzern-internen Gründen wird der Steuerbetrag sowohl in der "
+ "Rechungswährung (EUR) als auch in der Buchwährung (GBP) ausgegeben.",
subjectCode: SubjectCodes.TXD);
invoice.AddNote("ZUGFeRD vers 2.5.0 (Extended)", subjectCode: SubjectCodes.ACB);
invoice.AddNote("Dies ist ein Beispiel zur empfohlenen Darstellung von Fremdwährungsrechnungen",
subjectCode: SubjectCodes.ACB);
' The first note spans several lines. Line breaks and indentation are significant in
' the XML – these are exactly the tabs the reference file contains.
invoice.AddNote("Mitglieder der Geschäftsleitung" & vbLf & vbTab & vbTab & vbTab & vbTab &
"H. Meier Geschäftsführer" & vbLf & vbTab & vbTab & vbTab & vbTab &
"T. Müller Prokurist" & vbLf & vbTab & vbTab & vbTab & vbTab &
"HRB Braunschweig 12345",
subjectCode:=SubjectCodes.REG)
invoice.AddNote("Vom 17. Dezember 2025 bis 6. Januar 2026 haben wir Betriebsferien.",
subjectCode:=SubjectCodes.AAI)
' TXD = tax information. Tells the reader why two currencies appear at all.
invoice.AddNote("Aus konzern-internen Gründen wird der Steuerbetrag sowohl in der " &
"Rechungswährung (EUR) als auch in der Buchwährung (GBP) ausgegeben.",
subjectCode:=SubjectCodes.TXD)
invoice.AddNote("ZUGFeRD vers 2.5.0 (Extended)", subjectCode:=SubjectCodes.ACB)
invoice.AddNote("Dies ist ein Beispiel zur empfohlenen Darstellung von Fremdwährungsrechnungen",
subjectCode:=SubjectCodes.ACB)
Note texts, product names and allowance reasons stay in German throughout this page: they are the payload of the official reference document, and translating them would break the comparison with it.
3. Seller and tax representative
The tax representative (BG-11) is a party in its own right with its own VAT ID – typical when a foreign supplier operates domestically through a fiscal representative. It is set like any other party, but its tax number goes through a dedicated method.
// Seller (BG-4) – without a contact person and without a GLN.
invoice.SetSeller(
name: "Rohstoff AG Salzgitter",
postcode: "38226",
city: "Salzgitter",
street: "Marktstr. 153",
country: CountryCodes.DE,
id: "12345676");
invoice.AddSellerTaxRegistration("DE123456788", TaxRegistrationSchemeID.VA);
// Seller tax representative (BG-11): a party of its own with its own VAT ID.
invoice.SellerTaxRepresentative = new Party()
{
Name = "Global Supplies Financial Services",
Postcode = "12345",
Street = "Friedrichstraße 165",
City = "Berlin",
Country = CountryCodes.DE
};
invoice.AddSellerTaxRepresentativeTaxRegistration("DE136695976", TaxRegistrationSchemeID.VA);
' Seller (BG-4) – without a contact person and without a GLN.
invoice.SetSeller(
name:="Rohstoff AG Salzgitter",
postcode:="38226",
city:="Salzgitter",
street:="Marktstr. 153",
country:=CountryCodes.DE,
id:="12345676")
invoice.AddSellerTaxRegistration("DE123456788", TaxRegistrationSchemeID.VA)
' Seller tax representative (BG-11): a party of its own with its own VAT ID.
invoice.SellerTaxRepresentative = New Party() With
{
.Name = "Global Supplies Financial Services",
.Postcode = "12345",
.Street = "Friedrichstraße 165",
.City = "Berlin",
.Country = CountryCodes.DE
}
invoice.AddSellerTaxRepresentativeTaxRegistration("DE136695976", TaxRegistrationSchemeID.VA)
4. Buyer
Two small things that are often searched for: street2 fills
ram:LineTwo, i.e. the second address line, and the buyer's
electronic address (BT-49) carries a Leitweg-ID here.
// Buyer (BG-7). street2 fills ram:LineTwo – the second address line ("Hof 3").
invoice.SetBuyer(
name: "Metallbau Leipzig GmbH & Co. KG",
postcode: "12345",
city: "Leipzig",
street: "Pappelallee 15",
street2: "Hof 3",
country: CountryCodes.DE,
id: "75969813");
// BT-49: electronic address of the buyer, scheme 0204 = Leitweg-ID.
invoice.SetBuyerElectronicAddress("04011000-1234512345-35",
ElectronicAddressSchemeIdentifiers.LeitwegId);
' Buyer (BG-7). street2 fills ram:LineTwo – the second address line ("Hof 3").
invoice.SetBuyer(
name:="Metallbau Leipzig GmbH & Co. KG",
postcode:="12345",
city:="Leipzig",
street:="Pappelallee 15",
street2:="Hof 3",
country:=CountryCodes.DE,
id:="75969813")
' BT-49: electronic address of the buyer, scheme 0204 = Leitweg-ID.
invoice.SetBuyerElectronicAddress("04011000-1234512345-35",
ElectronicAddressSchemeIdentifiers.LeitwegId)
5. Delivery and invoicing period
The ship-to party carries an electronic address as well. Unlike seller and
buyer, there is no Set… method for it: the
ElectronicAddress field hangs directly off the party and is written
in the EXTENDED profile only.
// Ship-to party (BG-13)
invoice.ShipTo = new Party()
{
ID = new GlobalID(null, "75969815"),
Name = "Metallbau Leipzig GmbH & Co. KG",
Postcode = "12347",
Street = "Eichenpromenade 37",
Street2 = "Tor 1",
City = "Metallstadt",
Country = CountryCodes.DE,
// BT-X-160: electronic address of the ship-to party, here a D-U-N-S number under
// scheme 0060. Every party carries this field – for seller and buyer it is BT-34
// and BT-49 respectively, for all others a BT-X field of its own that is written
// in the EXTENDED profile only.
ElectronicAddress = new ElectronicAddress()
{
Address = "999999999",
ElectronicAddressSchemeID = ElectronicAddressSchemeIdentifiers.DunsNumber
}
};
invoice.ActualDeliveryDate = new DateTime(2025, 11, 25); // BT-72
// BT-73 / BT-74: invoicing period for the whole document
invoice.SetBillingPeriod(new DateTime(2025, 11, 1), new DateTime(2025, 11, 30));
' Ship-to party (BG-13)
invoice.ShipTo = New Party() With
{
.ID = New GlobalID(Nothing, "75969815"),
.Name = "Metallbau Leipzig GmbH & Co. KG",
.Postcode = "12347",
.Street = "Eichenpromenade 37",
.Street2 = "Tor 1",
.City = "Metallstadt",
.Country = CountryCodes.DE,
' BT-X-160: electronic address of the ship-to party, here a D-U-N-S number under
' scheme 0060. Every party carries this field – for seller and buyer it is BT-34
' and BT-49 respectively, for all others a BT-X field of its own that is written
' in the EXTENDED profile only.
.ElectronicAddress = New ElectronicAddress() With
{
.Address = "999999999",
.ElectronicAddressSchemeID = ElectronicAddressSchemeIdentifiers.DunsNumber
}
}
invoice.ActualDeliveryDate = New DateTime(2025, 11, 25) ' BT-72
' BT-73 / BT-74: invoicing period for the whole document
invoice.SetBillingPeriod(New DateTime(2025, 11, 1), New DateTime(2025, 11, 30))
6. Payee and bank account
Payment goes not to the seller but to its financial services provider (BG-10).
The bank account is set separately through
AddCreditorFinancialAccount.
// Payee (BG-10): payment does not go to the seller but to its financial services
// provider. Scheme 0060 = D-U-N-S number.
invoice.Payee = new Party()
{
GlobalID = new GlobalID(GlobalIDSchemeIdentifiers.DUNS, "432156789"),
Name = "Global Supplies Financial Services",
Postcode = "12345",
Street = "Friedrichstraße 165",
City = "Berlin",
Country = CountryCodes.DE
};
// No information text and no BIC – the reference emits neither.
invoice.SetPaymentMeans(PaymentMeansTypeCodes.SEPACreditTransfer);
invoice.AddCreditorFinancialAccount(
iban: "DE77 3707 0060 0321 9870 00",
bic: null,
name: "Global Supplies Financial Services");
' Payee (BG-10): payment does not go to the seller but to its financial services
' provider. Scheme 0060 = D-U-N-S number.
invoice.Payee = New Party() With
{
.GlobalID = New GlobalID(GlobalIDSchemeIdentifiers.DUNS, "432156789"),
.Name = "Global Supplies Financial Services",
.Postcode = "12345",
.Street = "Friedrichstraße 165",
.City = "Berlin",
.Country = CountryCodes.DE
}
' No information text and no BIC – the reference emits neither.
invoice.SetPaymentMeans(PaymentMeansTypeCodes.SEPACreditTransfer)
invoice.AddCreditorFinancialAccount(
iban:="DE77 3707 0060 0321 9870 00",
bic:=Nothing,
name:="Global Supplies Financial Services")
7. Line item with allowances
A single line, but with the distinction that gets confused most often in practice: there are two different kinds of allowance at line level.
| Method | XML element | Effect |
|---|---|---|
AddTradeAllowance |
ram:AppliedTradeAllowanceCharge(inside the gross price) |
Amount per unit. Lowers the net price. This is what the goods invoice does. |
AddSpecifiedTradeAllowance |
ram:SpecifiedTradeAllowanceCharge(in the line settlement) |
Amount for the entire line. Lowers the line total, the price stays unchanged. That is the route used here. |
Concretely: the unit price stays at GBP 100, while the two allowances bring the line total down from 1,000 to GBP 850.
// 10 steel coils at GBP 100 = GBP 1,000, less two allowances (100 + 50) → GBP 850.
TradeLineItem coil = invoice.AddTradeLineItem(
lineID: "1",
name: "Stahlcoil",
netUnitPrice: 100m,
grossUnitPrice: 100m,
unitCode: QuantityCodes.H87,
unitQuantity: 1m,
billedQuantity: 10m,
lineTotalAmount: 850m, // after deducting the two allowances below
taxType: TaxTypes.VAT,
categoryCode: TaxCategoryCodes.S,
taxPercent: 19m,
sellerAssignedID: "CO-123/V2A",
buyerAssignedID: "Toolbox 0815");
coil.GrossQuantity = 1m; // ram:BasisQuantity in the gross price
coil.OriginTradeCountry = CountryCodes.DE; // BT-159 country of origin
// Line note without a subject code, again with the indentation from the reference.
coil.AddNote("Materialzertifikat X-234 gem ISO XYZ.\n\t\t\t\t\t\tWare bleibt bis zur "
+ "vollständigen Bezahlung unser Eigentum.\n\t\t\t\t\t");
// Order reference including the order line, but without a date
coil.SetBuyerOrderReferencedDocument("ORDER84359", orderReferencedDate: null,
orderReferencedLineId: "1");
// Allowance 1: percentage based, 10 % of 1,000. Reason code 64 = special agreement.
coil.AddSpecifiedTradeAllowance(
currency: CurrencyCodes.GBP,
basisAmount: 1000m,
actualAmount: 100m,
chargePercentage: 10m,
reason: "Lagerware",
reasonCode: AllowanceReasonCodes.SpecialAgreement);
// Allowance 2: a fixed amount. Reason code 70 = incoterm discount.
coil.AddSpecifiedTradeAllowance(
currency: CurrencyCodes.GBP,
basisAmount: 1000m,
actualAmount: 50m,
reason: "Direktbelieferung",
reasonCode: AllowanceReasonCodes.IncotermDiscount);
' 10 steel coils at GBP 100 = GBP 1,000, less two allowances (100 + 50) → GBP 850.
Dim coil As TradeLineItem = invoice.AddTradeLineItem(
lineID:="1",
name:="Stahlcoil",
netUnitPrice:=100D,
grossUnitPrice:=100D,
unitCode:=QuantityCodes.H87,
unitQuantity:=1D,
billedQuantity:=10D,
lineTotalAmount:=850D, ' after deducting the two allowances below
taxType:=TaxTypes.VAT,
categoryCode:=TaxCategoryCodes.S,
taxPercent:=19D,
sellerAssignedID:="CO-123/V2A",
buyerAssignedID:="Toolbox 0815")
coil.GrossQuantity = 1D ' ram:BasisQuantity in the gross price
coil.OriginTradeCountry = CountryCodes.DE ' BT-159 country of origin
' Line note without a subject code, again with the indentation from the reference.
coil.AddNote("Materialzertifikat X-234 gem ISO XYZ." & vbLf &
vbTab & vbTab & vbTab & vbTab & vbTab & vbTab &
"Ware bleibt bis zur vollständigen Bezahlung unser Eigentum." & vbLf &
vbTab & vbTab & vbTab & vbTab & vbTab)
' Order reference including the order line, but without a date
coil.SetBuyerOrderReferencedDocument("ORDER84359", orderReferencedDate:=Nothing,
orderReferencedLineId:="1")
' Allowance 1: percentage based, 10 % of 1,000. Reason code 64 = special agreement.
coil.AddSpecifiedTradeAllowance(
currency:=CurrencyCodes.GBP,
basisAmount:=1000D,
actualAmount:=100D,
chargePercentage:=10D,
reason:="Lagerware",
reasonCode:=AllowanceReasonCodes.SpecialAgreement)
' Allowance 2: a fixed amount. Reason code 70 = incoterm discount.
coil.AddSpecifiedTradeAllowance(
currency:=CurrencyCodes.GBP,
basisAmount:=1000D,
actualAmount:=50D,
reason:="Direktbelieferung",
reasonCode:=AllowanceReasonCodes.IncotermDiscount)
8. Document-level charges and allowances
A charge for single-use packaging and a percentage loyalty discount. In the XML
both share the same element ram:SpecifiedTradeAllowanceCharge and
are distinguished only by ram:ChargeIndicator. The writer emits
them in the order they were added, which is why the charge comes first in the
code.
// The charge comes first – the writer emits charges and allowances in the order they
// were added, and the reference lists the charge first.
invoice.AddTradeCharge(
basisAmount: null, // the reference emits no basis amount here
currency: CurrencyCodes.GBP,
actualAmount: 30m,
reason: "Einwegverpackung",
taxTypeCode: TaxTypes.VAT,
taxCategoryCode: TaxCategoryCodes.S,
taxPercent: 19m,
reasonCode: ChargeReasonCodes.Miscellaneous); // ABK
invoice.AddTradeAllowance(
basisAmount: 850m,
currency: CurrencyCodes.GBP,
actualAmount: 21.25m,
chargePercentage: 2.5m,
reason: "Stammkundenrabatt",
taxTypeCode: TaxTypes.VAT,
taxCategoryCode: TaxCategoryCodes.S,
taxPercent: 19m,
reasonCode: AllowanceReasonCodes.FixedLongTerm); // 102
' The charge comes first – the writer emits charges and allowances in the order they
' were added, and the reference lists the charge first.
invoice.AddTradeCharge(
basisAmount:=Nothing, ' the reference emits no basis amount here
currency:=CurrencyCodes.GBP,
actualAmount:=30D,
reason:="Einwegverpackung",
taxTypeCode:=TaxTypes.VAT,
taxCategoryCode:=TaxCategoryCodes.S,
taxPercent:=19D,
reasonCode:=ChargeReasonCodes.Miscellaneous) ' ABK
invoice.AddTradeAllowance(
basisAmount:=850D,
currency:=CurrencyCodes.GBP,
actualAmount:=21.25D,
chargePercentage:=2.5D,
reason:="Stammkundenrabatt",
taxTypeCode:=TaxTypes.VAT,
taxCategoryCode:=TaxCategoryCodes.S,
taxPercent:=19D,
reasonCode:=AllowanceReasonCodes.FixedLongTerm) ' 102
9. VAT in the invoice currency
At first entirely ordinary, in GBP: 850.00 + 30.00 − 21.25 = 858.75, of which 19 % = 163.1625 → GBP 163.16.
// BT-110: tax amount in the invoice currency (GBP).
invoice.AddApplicableTradeTax(
basisAmount: 858.75m,
percent: 19m,
taxAmount: 163.16m,
typeCode: TaxTypes.VAT,
categoryCode: TaxCategoryCodes.S,
allowanceChargeBasisAmount: 8.75m, // +30.00 − 21.25
lineTotalBasisAmount: 850m);
' BT-110: tax amount in the invoice currency (GBP).
invoice.AddApplicableTradeTax(
basisAmount:=858.75D,
percent:=19D,
taxAmount:=163.16D,
typeCode:=TaxTypes.VAT,
categoryCode:=TaxCategoryCodes.S,
allowanceChargeBasisAmount:=8.75D, ' +30.00 − 21.25
lineTotalBasisAmount:=850D)
10. Tax amount in the accounting currency and the exchange rate
For the VAT return, the tax amount in a foreign currency is not enough: Art. 230 of the EU VAT Directive (2006/112/EC) requires the amount in the seller's national currency as well. Three related pieces of information exist for that:
| Code | Field | Meaning |
|---|---|---|
| BT-6 | TaxCurrency |
The accounting currency itself, here EUR. |
| BT-111 | TaxTotalAmountInAccountingCurrency |
The same tax amount, converted into BT-6: EUR 183.14. |
| BG-X-41 | TaxCurrencyExchange (group) | The rate the conversion was made with. |
| BT-X-258 | SourceCurrency |
Invoice currency, i.e. BT-5 (GBP). FactoorSharp derives it automatically. |
| BT-X-259 | TargetCurrency |
Accounting currency, i.e. BT-6 (EUR). |
| BT-X-260 | ConversionRate |
The rate itself, here 1.12244. |
| BT-X-261 | ConversionRateTimestamp |
Rate date, optional. Here the delivery date, 25 November 2025. |
Without BG-X-41 the document would carry only the result, not the way there – and for an accounting department that wants to recompute the amount or check it against the daily rate, that is exactly the missing piece.
Why one method for three business terms? Because EN 16931 business rule BR-53 requires that if BT-6 is present, BT-111 must be supplied too. And the rate in BG-X-41 is the justification for the value in BT-111. Separate setters would have allowed a tax amount in the accounting currency to be set without ever stating which rate produced it – or conversely, a rate to be recorded that matches no reported amount.
// One call writes BT-111, BT-6 and the whole BG-X-41 group:
// 163.16 GBP × 1.12244 = 183.14 EUR
// The source currency is derived automatically from invoice.Currency (BT-5).
invoice.SetTaxCurrencyExchange(
taxTotalInAccountingCurrency: 183.14m,
accountingCurrency: CurrencyCodes.EUR,
conversionRate: 1.12244m,
conversionRateTimestamp: new DateTime(2025, 11, 25));
' One call writes BT-111, BT-6 and the whole BG-X-41 group:
' 163.16 GBP × 1.12244 = 183.14 EUR
' The source currency is derived automatically from invoice.Currency (BT-5).
invoice.SetTaxCurrencyExchange(
taxTotalInAccountingCurrency:=183.14D,
accountingCurrency:=CurrencyCodes.EUR,
conversionRate:=1.12244D,
conversionRateTimestamp:=New DateTime(2025, 11, 25))
The former method SetTaxTotalInAccountingCurrency set only
BT-111 and BT-6, without a rate. It was removed in version 20.0;
use SetTaxCurrencyExchange instead.
About the rate itself: BT-X-260 is defined in the schema as a plain
xs:decimal with no digit limit, and the FeRD reference writes five
decimal places. The writer therefore rounds adaptively – to two places
where that is lossless, otherwise to up to five – and reproduces 1.12244
exactly. The rate date, like every date field in this library, is written in
UN/CEFACT format 102 (CCYYMMDD).
BG-X-41 exists in the EXTENDED profile only and is modelled on the CII side
exclusively. UBL does have a structurally comparable element in
cac:TaxExchangeRate, but that lies outside the EN 16931
CIUS and is therefore not served by FactoorSharp – see
UBL vs. CII.
11. Payment terms
Two stages, deliberately as plain free text with a date here. How an early payment discount is made machine-readable instead is shown in the goods invoice.
// Two stages as plain free text plus a date – without PaymentTermsType.Skonto, so
// without a machine-readable early payment discount block.
invoice.AddTradePaymentTerms("Zahlbar ohne Abschlag bis ", new DateTime(2025, 12, 31));
invoice.AddTradePaymentTerms("Zahlbar mit 2% Skonto bis", new DateTime(2025, 12, 14));
' Two stages as plain free text plus a date – without PaymentTermsType.Skonto, so
' without a machine-readable early payment discount block.
invoice.AddTradePaymentTerms("Zahlbar ohne Abschlag bis ", New DateTime(2025, 12, 31))
invoice.AddTradePaymentTerms("Zahlbar mit 2% Skonto bis", New DateTime(2025, 12, 14))
12. Document totals
All totals are in GBP. New compared to the other examples is the prepayment (BT-113), which is deducted from the grand total:
| BT code | Parameter | Calculation (GBP) |
|---|---|---|
| BT-106 | lineTotalAmount |
850.00 (line total after the two allowances) |
| BT-108 | chargeTotalAmount |
30.00 (single-use packaging) |
| BT-107 | allowanceTotalAmount |
21.25 (loyalty discount) |
| BT-109 | taxBasisAmount |
850.00 + 30.00 − 21.25 = 858.75 |
| BT-110 | taxTotalAmount |
858.75 × 19 % = 163.16 |
| BT-112 | grandTotalAmount |
858.75 + 163.16 = 1,021.91 |
| BT-113 | totalPrepaidAmount |
500.00. How individual instalments are itemised is covered under advance payments. |
| BT-115 | duePayableAmount |
1,021.91 − 500.00 = 521.91 |
// All values in GBP, the invoice currency – including the tax amount.
invoice.SetTotals(
lineTotalAmount: 850m, // BT-106
chargeTotalAmount: 30m, // BT-108
allowanceTotalAmount: 21.25m, // BT-107
taxBasisAmount: 858.75m, // BT-109
taxTotalAmount: 163.16m, // BT-110
grandTotalAmount: 1021.91m, // BT-112
totalPrepaidAmount: 500m, // BT-113 prepayment
duePayableAmount: 521.91m); // BT-115
' All values in GBP, the invoice currency – including the tax amount.
invoice.SetTotals(
lineTotalAmount:=850D, ' BT-106
chargeTotalAmount:=30D, ' BT-108
allowanceTotalAmount:=21.25D, ' BT-107
taxBasisAmount:=858.75D, ' BT-109
taxTotalAmount:=163.16D, ' BT-110
grandTotalAmount:=1021.91D, ' BT-112
totalPrepaidAmount:=500D, ' BT-113 prepayment
duePayableAmount:=521.91D) ' BT-115
13. Saving and checking
invoice.Save("X07_01_Fremdwaehrung.xml",
ZUGFeRDVersion.Version25,
Profile.Extended,
ZUGFeRDFormats.CII);
invoice.Save("X07_01_Fremdwaehrung.xml",
ZUGFeRDVersion.Version25,
Profile.Extended,
ZUGFeRDFormats.CII)
The result has to have the same tree structure as
X07_01_Fremdwaehrung.xml from the FeRD sample package. Whether the
document also complies with the rule set is something you check either
in the browser
or straight
from your code.
One finding is to be expected there and does not come from the rebuild: the
FeRD reference carries 04011000-1234512345-35 as its
Leitweg-ID, and that value's check digit is wrong. It is taken character for
character from the template, so the finding hits the template just as much.
If you use this invoice as a document of your own, put a valid Leitweg-ID in
that place.
A human-readable rendition is produced by the visualizer; how it becomes a PDF/A-3 with embedded XML is covered under working with PDF files.