Back to Compliance Hub
Critical

BR-DE-18

Skonto (Early-Payment Discount) Badly Formatted in BT-20

What This Error Means

EN 16931 has no structured field for an early-payment discount (Skonto). XRechnung therefore defines a machine-readable line format inside the payment terms (BT-20): #SKONTO#TAGE=n#PROZENT=n.nn# with an optional #BASISBETRAG=n.nn# segment. BR-DE-18 checks every line that starts with '#' in the first cac:PaymentTerms/cbc:Note (CII: the first ram:SpecifiedTradePaymentTerms/ram:Description). Each such line must match the format exactly, and a line break must follow the last Skonto line. Ordinary text lines are ignored. The rule is fatal.

Why this happens

The Schematron normalises each line that starts with '#' and matches it against the regular expression (^|\r?\n)#(SKONTO)#TAGE=([0-9]+#PROZENT=[0-9]+\.[0-9]{2})(#BASISBETRAG=-?[0-9]+\.[0-9]{2})?#$. A second condition requires the text after the last #...# segment to begin with a line break. The typical mistakes are: a percentage without two decimals (PROZENT=2) or with a comma (PROZENT=2,00); lower-case keywords (#skonto#); a space inside the line; a missing closing '#'; the percent sign (PROZENT=2.00%); and, very often, no line break after the last Skonto line because the note ends directly with '#'. Invoicing software that writes Skonto as prose ('2 % Skonto bei Zahlung innerhalb von 14 Tagen') does not trigger BR-DE-18, but the receiving system cannot process that discount automatically.

How to Fix It

Write each Skonto tier on its own line as #SKONTO#TAGE=14#PROZENT=2.00# and end it with a line break. Use capital letters, whole days, a dot as decimal separator and exactly two decimals for the percentage. Add #BASISBETRAG=1500.00 before the closing # only if the discount is not calculated on the amount due (BT-115).

Step-by-step

1) Put all payment terms into the first cac:PaymentTerms/cbc:Note; a second PaymentTerms element is not checked and is easily overlooked by the recipient. 2) Keep free text on its own lines that do not start with '#'. 3) Write each tier as #SKONTO#TAGE=<days>#PROZENT=<percent with two decimals>#, for example #SKONTO#TAGE=14#PROZENT=2.00#. 4) Add #BASISBETRAG=<amount>.00 before the final '#' only if the discount base differs from BT-115, for example when some lines are not eligible. 5) End every Skonto line, including the last one, with a line break. In XML a literal line break inside the element is enough; &#10; also works. 6) In CII, use the same syntax in ram:SpecifiedTradePaymentTerms/ram:Description. 7) Validate again.

XML Example
<cac:PaymentTerms>
  <cbc:Note>Zahlbar innerhalb von 30 Tagen netto.
#SKONTO#TAGE=10#PROZENT=3.00#
#SKONTO#TAGE=20#PROZENT=1.50#BASISBETRAG=1500.00#
</cbc:Note>
</cac:PaymentTerms>

Fix Automatically

Upload your invoice to our Smart Repair engine. It checks the file against the full KoSIT rule set, including BR-DE-18, and corrects supported fields with a GoBD audit trail.

Open Smart Repair

Frequently asked questions

My Skonto line looks right. Why does BR-DE-18 still fire?

Most often the line break after the last '#' is missing, or the percentage has no two decimals (2 instead of 2.00). A comma as decimal separator or a stray space causes the same error.

Can I offer two Skonto tiers?

Yes. Write one line per tier, for example 3.00 % within 10 days and 1.50 % within 20 days, each ending with '#' and a line break.

Is Skonto as plain text allowed?

Plain text lines are not checked by BR-DE-18, so the file stays valid. Public buyers usually process discounts only from the structured #SKONTO# format, though, so use it if you want the discount to be applied reliably.

Related Errors

Other commonly encountered validation errors