BR-DE-18Skonto Zeilen in […] müssen diesem regulärem Ausdruck entsprechen: […].

Official rule text

Die Informationen zur Gewährung von Skonto müssen wie folgt im Element "Payment terms" (BT-20) übermittelt werden: Anzugeben ist im ersten Segment "SKONTO", im zweiten "TAGE=n", im dritten "PROZENT=n". Prozentzahlen sind ohne Vorzeichen sowie mit Punkt getrennt von zwei Nachkommastellen anzugeben. Liegt dem zu berechnenden Betrag nicht BT-115, "fälliger Betrag" zugrunde, sondern nur ein Teil des fälligen Betrags der Rechnung, ist der Grundwert zur Berechnung von Skonto als viertes Segment "BASISBETRAG=n" gemäß dem semantischen Datentypen Amount anzugeben. Jeder Eintrag beginnt mit einer #, die Segmente sind mit einer # getrennt und eine Zeile schließt mit einer # ab. Am Ende einer vollständigen Skontoangabe muss ein XML-konformer Zeilenumbruch folgen. Alle Angaben zur Gewährung von Skonto müssen in Großbuchstaben gemacht werden. Zusätzliches Whitespace (Leerzeichen, Tabulatoren oder Zeilenumbrüche) ist nicht zulässig. Andere Zeichen oder Texte als in den oberen Vorgaben genannt sind nicht zulässig.

KoSIT words this rule differently in the two files. Above is the UBL wording; here is the other:

Wording in CII

Skonto Zeilen in […] muessen diesem regulärem Ausdruck entsprechen: […]. Die Informationen zur Gewährung von Skonto müssen wie folgt im Element "Payment terms" (BT-20) übermittelt werden: Anzugeben ist im ersten Segment "SKONTO", im zweiten "TAGE=n", im dritten "PROZENT=n". Prozentzahlen sind ohne Vorzeichen sowie mit Punkt getrennt von zwei Nachkommastellen anzugeben. Liegt dem zu berechnenden Betrag nicht BT-115, "fälliger Betrag" zugrunde, sondern nur ein Teil des fälligen Betrags der Rechnung, ist der Grundwert zur Berechnung von Skonto als viertes Segment "BASISBETRAG=n" gemäß dem semantischen Datentypen Amount anzugeben. Jeder Eintrag beginnt mit einer #, die Segmente sind mit einer # getrennt und eine Zeile schließt mit einer # ab. Am Ende einer vollständigen Skontoangabe muss ein XML-konformer Zeilenumbruch folgen. Alle Angaben zur Gewährung von Skonto müssen in Großbuchstaben gemacht werden. Zusätzliches Whitespace (Leerzeichen, Tabulatoren oder Zeilenumbrüche) ist nicht zulässig. Andere Zeichen oder Texte als in den oberen Vorgaben genannt sind nicht zulässig.

Cash-discount (Skonto) information in the payment terms (BT-20) must follow a fixed machine-readable format: #SKONTO#TAGE=n#PROZENT=n.nn#, one entry per line, all in capitals, the percentage with a dot and exactly two decimals.

Severity
Error
Applies to
CII, UBL
Rule set
v2026-08-31
Checked on

Written and checked against the official KoSIT rule set by Dmytro Yalanskyi, NormAPI.

Why does BR-DE-18 happen?

The rule only inspects lines beginning with #. Free text such as "2% discount if paid within 14 days" is ignored and passes — though it is also unusable to the recipient's software. The error comes from the half-correct attempt: PROZENT=2 instead of PROZENT=2.00, one space too many, or the missing trailing line break. The official text above leaves two gaps, because the rule set fills them in as it validates: the name of the element, and the expression itself. It is (^|\r?\n)#(SKONTO)#TAGE=([0-9]+#PROZENT=[0-9]+\.[0-9]{2})(#BASISBETRAG=-?[0-9]+\.[0-9]{2})?#$ and it says three things the prose does not: TAGE takes whole numbers only, PROZENT takes no sign, and BASISBETRAG explicitly allows a minus.

What the validator checks

The expression the official KoSIT rule set evaluates — not paraphrased, but read from the Schematron file it ships. UBL and CII address different document trees, so the same rule reads differently in each.

UBL
every $line in cac:PaymentTerms/cbc:Note[1]/tokenize(. , '(\r?\n)')[starts-with( normalize-space(.) , '#')] satisfies matches ( normalize-space ($line), $XR-SKONTO-REGEX) and matches( cac:PaymentTerms/cbc:Note[1]/tokenize(. , '#.+#')[last()], '^\s*\n' )

Variables in it

$XR-SKONTO-REGEX
'(^|\r?\n)#(SKONTO)#TAGE=([0-9]+#PROZENT=[0-9]+\.[0-9]{2})(#BASISBETRAG=-?[0-9]+\.[0-9]{2})?#$'
CII
every $line in rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradePaymentTerms/ram:Description[1]/tokenize(. , '(\r?\n)')[starts-with( normalize-space(.) , '#')] satisfies matches ( normalize-space ($line), $XR-SKONTO-REGEX ) and matches( rsm:SupplyChainTradeTransaction/ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradePaymentTerms/ram:Description[1]/tokenize(. , '#.+#')[last()], '^\s*\n' )

Variables in it

$XR-SKONTO-REGEX
'(^|\r?\n)#(SKONTO)#TAGE=([0-9]+#PROZENT=[0-9]+\.[0-9]{2})(#BASISBETRAG=-?[0-9]+\.[0-9]{2})?#$'

Source: rule set v2026-08-31

How do you fix BR-DE-18?

Write the entry exactly as #SKONTO#TAGE=14#PROZENT=2.00# and terminate it with a line break. Percentages always with a dot and exactly two decimals. If the discount applies to a partial amount only, append #BASISBETRAG=n.nn# as a fourth segment. No extra whitespace, no other text on the same line.

In the XML

A UBL fragment. The CII path is named above — same change, different element names.

Fails
<cac:PaymentTerms>
  <cbc:Note>2 % Skonto bei Zahlung innerhalb von 14 Tagen</cbc:Note>
</cac:PaymentTerms>
Fixed
<cac:PaymentTerms>
  <cbc:Note>#SKONTO#TAGE=14#PROZENT=2.00#
Zahlbar innerhalb von 30 Tagen netto</cbc:Note>
</cac:PaymentTerms>

Download an example invoice that triggers BR-DE-18 ↓

Related rules

NormAPI provides technical validation, not tax or legal advice.