<!-- md-source: a3f25df37616 FactoorSharpWeb/wwwroot/de/Service/ForeignCurrencyInvoice.md -->

# Foreign currency invoice

> Markdown version of <https://www.factoorsharp.de/en/Service/ForeignCurrencyInvoice> for AI agents.
> Languages: [Deutsch](https://www.factoorsharp.de/de/Service/ForeignCurrencyInvoice.md) ·
> [English](https://www.factoorsharp.de/en/Service/ForeignCurrencyInvoice.md) ·
> [Français](https://www.factoorsharp.de/fr/Service/ForeignCurrencyInvoice.md)

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).

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)

Note texts, product names and allowance reasons stay in German throughout: they are the
payload of the official reference document.

## 1. Invoice header and the two currencies

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.

```csharp
// BT-5 the 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;
```

## 2. Free-text notes

The code `TXD` (tax information) tells the human reader why two currencies appear.

Line breaks and indentation inside a note are **significant** in the XML. The tabs in the
first call are taken character for character from the reference file; without them the
cross-check reports a difference.

```csharp
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.
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);
```

## 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.

```csharp
// 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);

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);
```

## 4. Buyer

`street2` fills `ram:LineTwo`, i.e. the second address line. The buyer's electronic
address (BT-49) carries a Leitweg-ID here.

```csharp
invoice.SetBuyer(
    name: "Metallbau Leipzig GmbH & Co. KG",
    postcode: "12345",
    city: "Leipzig",
    street: "Pappelallee 15",
    street2: "Hof 3",
    country: CountryCodes.DE,
    id: "75969813");

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.

```csharp
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.
    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));
```

## 6. Payee and bank account

```csharp
// 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");
```

## 7. Line item with allowances

Two different kinds of allowance at line level, the distinction most often confused in
practice:

| 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.

```csharp
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);
```

## 8. Document-level charges and allowances

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.

```csharp
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
```

## 9. VAT in the invoice currency

850.00 + 30.00 − 21.25 = 858.75, of which 19 % = 163.1625 → **GBP 163.16**.

```csharp
// 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);
```

## 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.

**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.

```csharp
// 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));
```

The former method `SetTaxTotalInAccountingCurrency` set only BT-111 and BT-6, without a
rate. It was removed in version 20.0; use `SetTaxCurrencyExchange` instead.

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 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 not served by FactoorSharp.

## 11. Payment terms

Two stages, deliberately as plain free text with a date here.

```csharp
// 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 |
| BT-115 | `duePayableAmount` | 1,021.91 − 500.00 = **521.91** |

```csharp
// 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
```

## 13. Saving and checking

```csharp
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.

One validation finding is to be expected 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.

The validator, the visualizer and the detailed documentation for them live in the
customer area at <https://www.factoorsharp.de/support/>.

## Related pages

- [Extended goods invoice](https://www.factoorsharp.de/en/Service/GoodsInvoice.md): six line items, two tax rates, discounts and an early payment discount in EXTENDED.
- [Correction invoice](https://www.factoorsharp.de/en/Service/CorrectionInvoice.md): type 384 with negative amounts, set apart from the credit note.
- [Getting started](https://www.factoorsharp.de/en/Home/GettingStarted.md): installation, license key and your first invoice.
- [Factur-X reference](https://www.factoorsharp.de/en/Service/Documentation): XML elements and BT/BG codes to look up.
