XRechnung · UBL · rule diff

XRechnung 2.3.0: UBL validation rule changes

22 rules changed between 2.2.0 and 2.3.0 — added, removed, or rewritten. This is computed from the two rule sets directly, not from a changelog.

About this comparison

Revalidate compares the archived 2.2.0 and 2.3.0 rule sets at the assertion and variable level. The diff identifies changed rules; replaying your invoices shows which changes affect your documents.

Browse archived rule sets and checksums. Report published by Revalidate on .

What changed

BR-DE-18Dependency changed

A regex dependency now requires lines to start with "#SKONTO"

Why this matters

The rule's test expression is byte-identical between the two releases; the changed dependency is the variable "$XR-SKONTO-REGEX". That variable's regex previously was "#(SKONTO)#TAGE=([0-9]+#PROZENT=[0-9]+\.[0-9]{2})(#BASISBETRAG=-?[0-9]+\.[0-9]{2})?#$"; it now prepends "(^|\r?\n)" before the "#(SKONTO)". The previous pattern could match a "#SKONTO" segment anywhere in a line up to the line end, while the added alternation restricts it to the start of the string or immediately after a line break. Since the test normalizes each tokenized line before matching, no line break is present for those values, so the practical effect is to require the normalized line to begin with "#SKONTO".

fatalcountry

Original rule text: [BR-DE-18] Skonto Zeilen in müssen 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.

Explanation and fix

What this rule requires

The XRechnung rule BR-DE-18 requires that discount terms ("Skonto") in the first cac:PaymentTerms/cbc:Note element (BT-20 "Payment terms") are written as lines beginning with # in exactly the form #SKONTO#TAGE=n#PROZENT=n[#BASISBETRAG=n]#, with TAGE as digits, PROZENT as unsigned decimal with a dot and two decimal places, and an optional signed BASISBETRAG amount with two decimal places. A line fails if it starts with # but does not match that pattern after normalize-space(), or if the final line does not end with a newline. As this is a fatal rule, such a document fails validation.

How to fix

In cac:PaymentTerms/cbc:Note (BT-20), set each Skonto entry to a single line matching the required uppercase format, for example #SKONTO#TAGE=14#PROZENT=2.00# or #SKONTO#TAGE=14#PROZENT=2.00#BASISBETRAG=100.00#, and ensure the note ends with an XML line break (\n or \r\n) after the last #. Check that segments are separated by #, there is no whitespace inside a segment, PROZENT has exactly two decimal places, BASISBETRAG has two decimal places if present, and only the literal uppercase segment names are used.

Guidance on this rule. The original text above is authoritative.

BR-DE-18 rule details

Changed variable $XR-SKONTO-REGEX

Before · 2.2.0

'#(SKONTO)#TAGE=([0-9]+#PROZENT=[0-9]+\.[0-9]{2})(#BASISBETRAG=-?[0-9]+\.[0-9]{2})?#$'

After · 2.3.0

'(^|\r?\n)#(SKONTO)#TAGE=([0-9]+#PROZENT=[0-9]+\.[0-9]{2})(#BASISBETRAG=-?[0-9]+\.[0-9]{2})?#$'
BR-DEX-04Dependency changed

ICD code list adds "0231" through "0238"

The rule's test expression is byte-identical between the two releases. The changed dependency is "$ISO-6523-ICD-CODES": its code list previously ended at "0230" and now ends at "0238", adding "0231" through "0238". The expression references "$ISO-6523-ICD-EXT-CODES", not "$ISO-6523-ICD-CODES", so the evidence does not show how the added codes reach the rule.

fatalcountry

Original rule text: [BR-DEX-04] Any scheme identifier in MUST be coded using one of the ISO 6523 ICD list.

Explanation and fix

What this rule requires

The rule requires that a party identification element (cac:PartyIdentification/cbc:ID in UBL or ram:GlobalID in CII) with a schemeID attribute and an XRechnung extension context uses a scheme identifier from the ISO 6523 ICD code list supplied by the rule. In UBL, SEPA is also allowed if the element is inside an AccountingSupplierParty or PayeeParty; in CII only the ISO 6523 ICD codes are accepted. The document fails when the schemeID is not one of those allowed codes or contains internal spaces.

How to fix

Set the schemeID attribute to a code from the rule's ISO-6523-ICD-EXT-CODES list (e.g., 0002, 0060, or 0088) with no internal spaces. In UBL, if the party is the accounting supplier or payee, SEPA is also accepted; in CII only an ISO 6523 ICD code is allowed. If the scheme identifier is not needed for this party identification, remove the schemeID attribute.

Guidance on this rule. The original text above is authoritative.

BR-DEX-04 rule details

Changed variable $ISO-6523-ICD-CODES

Before · 2.2.0

' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 '

After · 2.3.0

' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238'
BR-DEX-06Dependency changed

ISO 6523 code list adds "0231" through "0238"

The test expression is byte-identical in both releases, so the change is in a value it depends on. The variable "$ISO-6523-ICD-CODES" previously ended at "0230" and now continues with "0231", "0232", "0233", "0234", "0235", "0236", "0237", and "0238", adding eight entries. The test expression still references "$ISO-6523-ICD-EXT-CODES".

fatalcountry

Original rule text: [BR-DEX-06] Any scheme identifier in MUST be coded using one of the ISO 6523 ICD list.

Explanation and fix

What this rule requires

This rule applies to item standard identification identifiers that carry a schemeID and occur in a document using the XRechnung extension. It requires the schemeID attribute, after trimming surrounding whitespace, to contain no internal spaces and to be exactly one of the codes listed in the rule's $ISO-6523-ICD-EXT-CODES (for example 0002, 0088, XR01). It fails if the attribute is empty or whitespace-only, contains spaces inside the value, or is not one of those codes.

How to fix

On the relevant element (cac:StandardItemIdentification/cbc:ID in UBL, ram:SpecifiedTradeProduct/ram:GlobalID in CII), set the schemeID attribute to a single valid ISO 6523 ICD code from the allowed list, without any spaces inside the code. For example, use 0002 or XR01 as appropriate. Ensure only one code is provided; if you currently have multiple codes separated by spaces, keep only the applicable one. If the code you used is not in the list, look up the correct ISO 6523 ICD code for the item identification scheme.

Guidance on this rule. The original text above is authoritative.

BR-DEX-06 rule details

Changed variable $ISO-6523-ICD-CODES

Before · 2.2.0

' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 '

After · 2.3.0

' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238'
BR-DEX-07Dependency changed

Allowed CEF EAS scheme codes gain "0177" and "0235"

The test expression is byte-identical in both releases. The $CEF-EAS-CODES list now includes "0177" after "0170" and "0235" after "0230"; all other entries are unchanged. This widens the set of CEF EAS scheme identifiers the rule accepts for an Endpoint Identifier. The two additional codes were not accepted before and are accepted now.

fatalcountry

Original rule text: [BR-DEX-07] Any scheme identifier for an Endpoint Identifier in MUST belong to the CEF EAS code list.

Explanation and fix

What this rule requires

For an endpoint identifier (cbc:EndpointID or ram:URIID) that has a schemeID and the invoice declares itself as an XRechnung extension, the schemeID must be exactly one of the codes from the CEF EAS code list accepted by the rule, with no spaces inside the value. The test fails if the schemeID is empty or whitespace-only, contains an internal space, or is not in the allowed code list.

How to fix

Set the schemeID attribute to a valid CEF EAS code from the rule's list, such as "0088" or "0208". Ensure the value is not empty and does not contain spaces. If the current scheme identifier is not in the list, map it to the appropriate CEF EAS code.

Guidance on this rule. The original text above is authoritative.

BR-DEX-07 rule details

Changed variable $CEF-EAS-CODES

Before · 2.2.0

' 0002 0007 0009 0037 0060 0088 0096 0097 0106 0130 0135 0142 0147 0151 0170 0183 0184 0188 0190 0191 0192 0193 0194 0195 0196 0198 0199 0200 0201 0202 0203 0204 0205 0208 0209 0210 0211 0212 0213 0215 0216 0217 0218 0219 0220 0221 0225 0230 9901 9910 9913 9914 9915 9918 9919 9920 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9957 9959 AN AQ AS AU EM '

After · 2.3.0

' 0002 0007 0009 0037 0060 0088 0096 0097 0106 0130 0135 0142 0147 0151 0170 0177 0183 0184 0188 0190 0191 0192 0193 0194 0195 0196 0198 0199 0200 0201 0202 0203 0204 0205 0208 0209 0210 0211 0212 0213 0215 0216 0217 0218 0219 0220 0221 0225 0230 0235 9901 9910 9913 9914 9915 9918 9919 9920 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9957 9959 AN AQ AS AU EM '
BR-DEX-05Dependency changed

Allowed ISO 6523 ICD codes expanded by eight entries

The test expression is byte-identical between published "2.2.0" and "2.3.0"; the only change is to the variable $ISO-6523-ICD-CODES. In published "2.2.0", that variable's allowed-code list ended at "0230". In "2.3.0" it appends eight additional codes: "0231", "0232", "0233", "0234", "0235", "0236", "0237", and "0238". The rule continues to accept a scheme identifier only if it appears in that list and contains no spaces.

fatalcountry

Original rule text: [BR-DEX-05] Any scheme identifier in MUST be coded using one of the ISO 6523 ICD list.

Explanation and fix

What this rule requires

The rule applies when the document is identified as an XRechnung extension (the $isExtension condition is true). For such documents, the @schemeID attribute on cac:PartyLegalEntity/cbc:CompanyID (UBL) or on ram:ID outside ram:SpecifiedTaxRegistration (CII) must be a code from the ISO 6523 ICD list, and it must not contain any whitespace. If the value is empty, contains a space, or is not exactly one of the listed codes, the document fails validation. This is a fatal rule, so the invoice is rejected.

How to fix

Set @schemeID to one of the allowed ISO 6523 ICD codes from the rule's list, for example XR01 or 0002, and ensure there are no spaces. If the current value is not in the list or contains whitespace, replace it with the correct code for your identification scheme.

Guidance on this rule. The original text above is authoritative.

BR-DEX-05 rule details

Changed variable $ISO-6523-ICD-CODES

Before · 2.2.0

' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 '

After · 2.3.0

' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238'
BR-DE-28Dependency changed

Only "$XR-EMAIL-REGEX" changed, replacing the old long allowed-character pattern with a much shorter one.

Why this matters

The test expression is byte-identical and still matches the e-mail field against "$XR-EMAIL-REGEX". The variable changed from the value "^[a-zA-Z0-9!#\$%&"*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#\$%&"*+/=?^_`{|}~-]+)*@([a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$" to the value "^[^@\s]+@([^@.\s]+\.)+[^@.\s]+$". The old value limited the local part to letters, digits, and a listed set of symbols, with dots only as separators, and limited the domain part to letters, digits, and hyphens, also with dots only as separators. The new value allows the local part to contain any characters except "@" and whitespace, including dots in any position, and defines the domain part as a dot-separated list of at least two labels, each made of characters other than "@", ".", and whitespace.

warningcountry

Original rule text: [BR-DE-28] In BT-43 soll genau ein @-Zeichen enthalten sein, welches nicht von einem Leerzeichen, einem Punkt, aber mindestens zwei Zeichen auf beiden Seiten flankiert werden soll. Ein Punkt sollte nicht am Anfang oder am Ende stehen.

Explanation and fix

What this rule requires

This is a warning, so the document is not rejected, but the rule recommends that the supplier contact email in BT-43 (cbc:ElectronicMail in UBL, ram:URIID in CII) have a plausible email shape. The test accepts values with no whitespace, exactly one @, at least one non-whitespace character before @, and after @ a domain that contains at least one dot with at least one non-dot/non-space character before each dot and no dot immediately after @ or at the end. A value fails if it is empty or only whitespace, has no @ or more than one @, contains spaces, or lacks a dotted domain after @ with non-empty labels.

How to fix

Set the email address in BT-43 to a value that contains exactly one @, no spaces, at least one character before @, and a domain after @ like example.com with at least one dot and non-empty labels. Check for hidden whitespace or extra @ characters. If the email looks correct, verify that you are editing the correct cbc:ElectronicMail or ram:URIID element in the supplier contact.

Guidance on this rule. The original text above is authoritative.

BR-DE-28 rule details

Changed variable $XR-EMAIL-REGEX

Before · 2.2.0

'^[a-zA-Z0-9!#\$%&"*+/=?^_`{|}~-]+(\.[a-zA-Z0-9!#\$%&"*+/=?^_`{|}~-]+)*@([a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$'

After · 2.3.0

'^[^@\s]+@([^@.\s]+\.)+[^@.\s]+$'
BR-DEX-08Dependency changed

The rule's allowed ISO 6523 ICD codes now include 0231 through 0238.

The test expression is byte-identical in both releases. The variable listed as changed, $ISO-6523-ICD-CODES, previously ended with "0230"; it now continues through "0238", adding eight codes from "0231" to "0238". The test expression itself references $ISO-6523-ICD-EXT-CODES, which the evidence does not show changing separately.

fatalcountry

Original rule text: [BR-DEX-08] Any scheme identifier for a Delivery location identifier in MUST be coded using one of the ISO 6523 ICD list.

Explanation and fix

What this rule requires

The rule checks the schemeID attribute of the delivery location identifier (UBL: cac:DeliveryLocation/cbc:ID; CII: ram:ApplicableHeaderTradeDelivery/ram:ShipToTradeParty/ram:GlobalID) when the document is declared as an XRechnung extension. The value must not contain internal spaces and must be one of the codes in the rule's ISO 6523 ICD extension list (for example, 0002, 0088, or XR01). The document fails when this attribute contains an internal space or is not one of those listed codes.

How to fix

Change the schemeID value to a code from the ISO 6523 ICD list, such as 0002, 0088, or XR01. Ensure the value has no spaces; if spaces come from data entry, correct the field or mapping to output only the code. Check the source system's configuration for delivery location identifier schemes and align it with the allowed ISO 6523 ICD codes.

Guidance on this rule. The original text above is authoritative.

BR-DEX-08 rule details

Changed variable $ISO-6523-ICD-CODES

Before · 2.2.0

' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 '

After · 2.3.0

' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238'
BR-DE-17Test expression rewritten

Surrounding whitespace no longer affects invoice or credit note type code comparison.

The test now applies "normalize-space()" to the invoice type code and the credit note type code before comparing them against "$supportedInvAndCNTypeCodes". Previously it compared the raw values. The function strips leading and trailing whitespace and collapses any internal runs to a single space, so surrounding whitespace no longer affects the comparison. The permitted codes in the rule message are unchanged.

warningcountry

Original rule text: [BR-DE-17] Mit dem Element "Invoice type code" (BT-3) sollen ausschließlich folgende Codes aus der Codeliste UNTDID 1001 übermittelt werden: 326 (Partial invoice), 380 (Commercial invoice), 384 (Corrected invoice), 389 (Self-billed invoice) und 381 (Credit note),875 (Partial construction invoice), 876 (Partial final construction invoice), 877 (Final construction invoice).

Explanation and fix

What this rule requires

This warning checks the document type code (BT-3). In a UBL invoice or credit note, at least one of cbc:InvoiceTypeCode or cbc:CreditNoteTypeCode must contain one of the codes 326, 380, 384, 389, 381, 875, 876 or 877 (UNTDID 1001). In a CII invoice, rsm:ExchangedDocument/ram:TypeCode must contain one of those same codes. Because the severity is warning, the validator reports it but does not reject the document; it recommends using an allowed code.

How to fix

Set the document type code to one of the allowed values: 326, 380, 384, 389, 381, 875, 876 or 877. In UBL, put it in cbc:InvoiceTypeCode (on an invoice) or cbc:CreditNoteTypeCode (on a credit note); if both are present, at least one must have an allowed value. In CII, put it in rsm:ExchangedDocument/ram:TypeCode. Do not use any other code, and do not leave the relevant element empty or only whitespace.

Guidance on this rule. The original text above is authoritative.

BR-DE-17 rule details

Before · 2.2.0

cbc:InvoiceTypeCode = $supportedInvAndCNTypeCodes or cbc:CreditNoteTypeCode = $supportedInvAndCNTypeCodes

After · 2.3.0

normalize-space(cbc:InvoiceTypeCode) = $supportedInvAndCNTypeCodes or normalize-space(cbc:CreditNoteTypeCode) = $supportedInvAndCNTypeCodes
BR-DE-26Test expression rewritten

The rule now normalizes whitespace in invoice and credit note codes before comparing them to "384"

The test no longer compares the raw values of the invoice type code and credit note type code directly to the number "384"; it now applies normalize-space to each value and compares the result to the string "384". The comparison is therefore exact and ignores leading or trailing whitespace in those element values. The surrounding condition and the requirement for a billing reference are otherwise unchanged.

warningcountry

Original rule text: [BR-DE-26] Wenn im Element "Invoice type code" (BT-3) der Code 384 (Corrected invoice) übergeben wird, soll PRECEDING INVOICE REFERENCE BG-3 mind. einmal vorhanden sein.

Explanation and fix

What this rule requires

The rule applies to invoices and credit notes. If the invoice type code (BT-3) or credit note type code is set to 384 (corrected invoice), the rule expects at least one preceding invoice reference element (cac:BillingReference/cac:InvoiceDocumentReference) to be present. Because this is a warning, the validator reports it but the document is not rejected; the rule is advisory and recommends that corrected invoices carry a reference to the preceding invoice.

How to fix

If the document uses type code 384, add at least one cac:BillingReference/cac:InvoiceDocumentReference element to the invoice. The test only checks that this element exists, so ensure the element is present and populated with the appropriate preceding invoice reference details.

Guidance on this rule. The original text above is authoritative.

BR-DE-26 rule details

Before · 2.2.0

((not(cbc:InvoiceTypeCode = 384 or cbc:CreditNoteTypeCode = 384) or (cac:BillingReference/cac:InvoiceDocumentReference)))

After · 2.3.0

((not(normalize-space(cbc:InvoiceTypeCode) = '384' or normalize-space(cbc:CreditNoteTypeCode) = '384') or (cac:BillingReference/cac:InvoiceDocumentReference)))
BR-CL-25Test expression rewritten

Allowed endpoint scheme identifiers gain "0177" and "0235"

The test checks that the endpoint scheme identifier has no spaces and is one of the codes in a fixed list embedded in the test. Between published 2.2.0 and 2.3.0, that list was changed to add "0177" and "0235". No other codes in the list were added or removed.

fatalbusiness

Original rule text: [BR-CL-25]-Endpoint identifier scheme identifier MUST belong to the CEF EAS code list

Explanation and fix

What this rule requires

The rule requires that the endpoint identifier's schemeID attribute (cbc:EndpointID/@schemeID in UBL, ram:URIID/@schemeID in CII) is a value from the CEF EAS code list, and that the value contains no spaces (after surrounding whitespace is removed). The test checks both conditions: it fails if the normalized schemeID contains any space or if it is not one of the listed codes. Because severity is fatal, an invoice with a schemeID that does not satisfy this is rejected.

How to fix

Set the endpoint identifier scheme identifier to a valid CEF EAS code. In UBL, change cbc:EndpointID/@schemeID to one of the allowed codes, e.g. 0088, 9930, or EM. In CII, set ram:URIID/@schemeID similarly. Ensure the value has no spaces within it and matches exactly one code from the list. If you believe the current value is already a scheme identifier, verify it is listed in the rule; only codes in the list are accepted.

Guidance on this rule. The original text above is authoritative.

BR-CL-25 rule details

Before · 2.2.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0007 0009 0037 0060 0088 0096 0097 0106 0130 0135 0142 0147 0151 0170 0183 0184 0188 0190 0191 0192 0193 0194 0195 0196 0198 0199 0200 0201 0202 0203 0204 0205 0208 0209 0210 0211 0212 0213 0215 0216 0217 0218 0219 0220 0221 0225 0230 9901 9910 9913 9914 9915 9918 9919 9920 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9957 9959 AN AQ AS AU EM ', concat(' ', normalize-space(@schemeID), ' '))))

After · 2.3.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0007 0009 0037 0060 0088 0096 0097 0106 0130 0135 0142 0147 0151 0170 0177 0183 0184 0188 0190 0191 0192 0193 0194 0195 0196 0198 0199 0200 0201 0202 0203 0204 0205 0208 0209 0210 0211 0212 0213 0215 0216 0217 0218 0219 0220 0221 0225 0230 0235 9901 9910 9913 9914 9915 9918 9919 9920 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9957 9959 AN AQ AS AU EM ', concat(' ', normalize-space(@schemeID), ' '))))
BR-DEX-02Test expression rewritten

Second count equality now requires child lines to have children before comparing sums

The first part of the rule, which uses the variable $invoiceline, is unchanged. The second part compares two counts. Before the change, the first count selected child lines whose net amount equalled the sum of their own child lines, without separately requiring that they had any child lines; the second count required at least one child line. The updated expression adds the requirement of at least one child line to the first count before checking the amount equality. Both counts now target the same population of child lines that have at least one child line.

warningcountry

Original rule text: [BR-DEX-02] Der Wert von "Invoice line net amount" (BT-131) einer "INVOICE LINE" (BG-25) oder einer "SUB INVOICE LINE" (BG-DEX-01) soll der Summe der "Invoice line net amount" (BT-131) der direkt darunterliegenden "SUB INVOICE LINE" (BG-DEX-01) entsprechen.

Explanation and fix

What this rule requires

This warning checks that a line's net amount equals the sum of its direct sub-lines' net amounts. For every cac:InvoiceLine that has at least one cac:SubInvoiceLine, its cbc:LineExtensionAmount must equal the sum of the child cac:SubInvoiceLine/cbc:LineExtensionAmount values. The same check applies to any cac:SubInvoiceLine that itself contains a cac:SubInvoiceLine. This is advisory, so the document is not rejected, but the validator reports the mismatched amounts.

How to fix

Update the cbc:LineExtensionAmount of each cac:InvoiceLine that has cac:SubInvoiceLine children to equal the sum of the direct child cac:SubInvoiceLine/cbc:LineExtensionAmount values. Do the same for any cac:SubInvoiceLine that has its own cac:SubInvoiceLine children. Alternatively, adjust the sub-line amounts so the sums match the parent amounts.

Guidance on this rule. The original text above is authoritative.

BR-DEX-02 rule details

Before · 2.2.0

(every $invoiceline in /ubl:Invoice/cac:InvoiceLine[ exists (./cac:SubInvoiceLine) ] satisfies $invoiceline/xs:decimal(cbc:LineExtensionAmount) = sum($invoiceline/cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount))) and (count( //cac:SubInvoiceLine [xs:decimal(cbc:LineExtensionAmount) = sum(child::cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount))]) = count(//cac:SubInvoiceLine [count(cac:SubInvoiceLine) > 0]))

After · 2.3.0

(every $invoiceline in /ubl:Invoice/cac:InvoiceLine[ exists (./cac:SubInvoiceLine) ] satisfies $invoiceline/xs:decimal(cbc:LineExtensionAmount) = sum($invoiceline/cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount))) and (count( //cac:SubInvoiceLine [count(cac:SubInvoiceLine) > 0 and xs:decimal(cbc:LineExtensionAmount) = sum(cac:SubInvoiceLine/xs:decimal(cbc:LineExtensionAmount))]) = count(//cac:SubInvoiceLine [count(cac:SubInvoiceLine) > 0]))
BR-DE-20Test expression rewritten

Whitespace around the payment means code no longer bypasses the IBAN check

The first disjunct of the test now normalizes whitespace in the payment means code before comparing it with "59"; previously the comparison used the code as written. This means a code of "59" with leading or trailing whitespace no longer makes the negative condition true, so validation no longer skips the IBAN pattern and checksum checks. The IBAN pattern and checksum remainder conditions are unchanged.

warningcountry

Original rule text: [BR-DE-20] "Debited account identifier" (BT-91) soll eine korrekte IBAN enthalten, wenn in "Payment means type code" (BT-81) mit dem Code 59 SEPA als Zahlungsmittel gefordert wird.

Explanation and fix

What this rule requires

The rule applies when the payment means type code (BT-81) is 59, indicating SEPA. In that case, the debited account identifier (BT-91) must be a valid IBAN. The test is satisfied if the code is not 59; if it is 59, the account identifier is checked for IBAN validity. This is a warning, so the document is not rejected, but the validator recommends a correct IBAN.

How to fix

If PaymentMeansCode / TypeCode is 59, ensure the account identifier in cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID (UBL) or ram:PayerPartyDebtorFinancialAccount/ram:IBANID (CII) is a valid IBAN. If the code is 59 and the IBAN is correct, check that it is formatted as the rule's IBAN check accepts.

Guidance on this rule. The original text above is authoritative.

BR-DE-20 rule details

Before · 2.2.0

not(cbc:PaymentMeansCode = '59') or matches(normalize-space(replace(cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')), '^[A-Z]{2}[0-9]{2}[a-zA-Z0-9]{0,30}$') and xs:decimal(string-join(for $cp in string-to-codepoints(concat(substring(normalize-space(replace(cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),5),upper-case(substring(normalize-space(replace(cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),1,2)),substring(normalize-space(replace(cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),3,2))) return (if($cp > 64) then string($cp - 55) else string($cp - 48)),'')) mod 97 = 1

After · 2.3.0

not(normalize-space(cbc:PaymentMeansCode) = '59') or matches(normalize-space(replace(cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')), '^[A-Z]{2}[0-9]{2}[a-zA-Z0-9]{0,30}$') and xs:decimal(string-join(for $cp in string-to-codepoints(concat(substring(normalize-space(replace(cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),5),upper-case(substring(normalize-space(replace(cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),1,2)),substring(normalize-space(replace(cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),3,2))) return (if($cp > 64) then string($cp - 55) else string($cp - 48)),'')) mod 97 = 1
BR-CL-22Test expression rewritten

Three VATEX codes added to allowed list

The list of permitted values inside the contains expression gained "VATEX-EU-144", "VATEX-EU-146-1E", and "VATEX-EU-159" after "VATEX-EU-143-1L" and before "VATEX-EU-309". No entries were removed from the list. The surrounding expression is otherwise unchanged: it still rejects values containing spaces and still matches a single token against the same space-padded list.

fatalbusiness

Original rule text: [BR-CL-22]-Tax exemption reason code identifier scheme identifier MUST belong to the CEF VATEX code list

Explanation and fix

What this rule requires

The rule requires the cbc:TaxExemptionReasonCode element (in CII: ram:ExemptionReasonCode) to contain a value that appears in the CEF VATEX code list. The test first checks that the normalized value contains no space, then checks that the uppercase form of the value is present in the list provided by the rule. A document fails if the value contains a space or is not in that list.

How to fix

Set the cbc:TaxExemptionReasonCode (or ram:ExemptionReasonCode) value to one of the codes listed in the rule's CEF VATEX code list, for example VATEX-EU-79-C or VATEX-FR-FRANCHISE. Ensure the value has no spaces; case is ignored by the test, but using the exact uppercase form is safest. If the current value is not in the list, replace it with the correct VAT exemption reason code.

Guidance on this rule. The original text above is authoritative.

BR-CL-22 rule details

Before · 2.2.0

((not(contains(normalize-space(.), ' ')) and contains(' VATEX-EU-79-C VATEX-EU-132 VATEX-EU-132-1A VATEX-EU-132-1B VATEX-EU-132-1C VATEX-EU-132-1D VATEX-EU-132-1E VATEX-EU-132-1F VATEX-EU-132-1G VATEX-EU-132-1H VATEX-EU-132-1I VATEX-EU-132-1J VATEX-EU-132-1K VATEX-EU-132-1L VATEX-EU-132-1M VATEX-EU-132-1N VATEX-EU-132-1O VATEX-EU-132-1P VATEX-EU-132-1Q VATEX-EU-143 VATEX-EU-143-1A VATEX-EU-143-1B VATEX-EU-143-1C VATEX-EU-143-1D VATEX-EU-143-1E VATEX-EU-143-1F VATEX-EU-143-1FA VATEX-EU-143-1G VATEX-EU-143-1H VATEX-EU-143-1I VATEX-EU-143-1J VATEX-EU-143-1K VATEX-EU-143-1L VATEX-EU-309 VATEX-EU-148 VATEX-EU-148-A VATEX-EU-148-B VATEX-EU-148-C VATEX-EU-148-D VATEX-EU-148-E VATEX-EU-148-F VATEX-EU-148-G VATEX-EU-151 VATEX-EU-151-1A VATEX-EU-151-1AA VATEX-EU-151-1B VATEX-EU-151-1C VATEX-EU-151-1D VATEX-EU-151-1E VATEX-EU-G VATEX-EU-O VATEX-EU-IC VATEX-EU-AE VATEX-EU-D VATEX-EU-F VATEX-EU-I VATEX-EU-J VATEX-FR-FRANCHISE VATEX-FR-CNWVAT ', concat(' ', normalize-space(upper-case(.)), ' '))))

After · 2.3.0

((not(contains(normalize-space(.), ' ')) and contains(' VATEX-EU-79-C VATEX-EU-132 VATEX-EU-132-1A VATEX-EU-132-1B VATEX-EU-132-1C VATEX-EU-132-1D VATEX-EU-132-1E VATEX-EU-132-1F VATEX-EU-132-1G VATEX-EU-132-1H VATEX-EU-132-1I VATEX-EU-132-1J VATEX-EU-132-1K VATEX-EU-132-1L VATEX-EU-132-1M VATEX-EU-132-1N VATEX-EU-132-1O VATEX-EU-132-1P VATEX-EU-132-1Q VATEX-EU-143 VATEX-EU-143-1A VATEX-EU-143-1B VATEX-EU-143-1C VATEX-EU-143-1D VATEX-EU-143-1E VATEX-EU-143-1F VATEX-EU-143-1FA VATEX-EU-143-1G VATEX-EU-143-1H VATEX-EU-143-1I VATEX-EU-143-1J VATEX-EU-143-1K VATEX-EU-143-1L VATEX-EU-144 VATEX-EU-146-1E VATEX-EU-159 VATEX-EU-309 VATEX-EU-148 VATEX-EU-148-A VATEX-EU-148-B VATEX-EU-148-C VATEX-EU-148-D VATEX-EU-148-E VATEX-EU-148-F VATEX-EU-148-G VATEX-EU-151 VATEX-EU-151-1A VATEX-EU-151-1AA VATEX-EU-151-1B VATEX-EU-151-1C VATEX-EU-151-1D VATEX-EU-151-1E VATEX-EU-G VATEX-EU-O VATEX-EU-IC VATEX-EU-AE VATEX-EU-D VATEX-EU-F VATEX-EU-I VATEX-EU-J VATEX-FR-FRANCHISE VATEX-FR-CNWVAT ', concat(' ', normalize-space(upper-case(.)), ' '))))
BR-CL-05Test expression rewritten

Currency code list drops "VEF" and adds "VES", "VED", and "ZWG".

The rule checks the value against a space-delimited list of accepted ISO 4217 alpha-3 currency codes. In the previous version the list contained "VEF"; in this version it does not. The list now also contains "VES", "VED", and "ZWG", which were absent before.

fatalbusiness

Original rule text: [BR-CL-05]-Tax currency code MUST be coded using ISO code list 4217 alpha-3

Explanation and fix

What this rule requires

The rule requires cbc:TaxCurrencyCode (UBL) or ram:TaxCurrencyCode (CII) to hold an ISO 4217 alpha-3 currency code from the list accepted by BR-CL-05. It passes only when the normalized value is exactly one of the 178 listed codes, for example EUR, USD, or GBP. A document fails if the element is empty, contains only whitespace, has an internal space, or uses a code not on that list.

How to fix

Put a valid ISO 4217 alpha-3 currency code in the tax currency field, such as EUR, USD, or GBP. Ensure the value has no internal spaces (surrounding whitespace is ignored by the rule) and is not empty or only whitespace. Check that the code is present in the BR-CL-05 list; if the current code is something else, replace it with the correct three-letter ISO 4217 code.

Guidance on this rule. The original text above is authoritative.

BR-CL-05 rule details

Before · 2.2.0

((not(contains(normalize-space(.), ' ')) and contains(' AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND BOB BOV BRL BSD BTN BWP BYN BZD CAD CDF CHE CHF CHW CLF CLP CNY COP COU CRC CUC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HRK HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRO MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLE SOS SRD SSP STD SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD USN UYI UYU UZS VEF VND VUV WST XAF XAG XAU XBA XBB XBC XBD XCD XDR XOF XPD XPF XPT XSU XTS XUA XXX YER ZAR ZMW ZWL ', concat(' ', normalize-space(.), ' '))))

After · 2.3.0

((not(contains(normalize-space(.), ' ')) and contains(' AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND BOB BOV BRL BSD BTN BWP BYN BZD CAD CDF CHE CHF CHW CLF CLP CNY COP COU CRC CUC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRO MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLE SOS SRD SSP STD SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD USN UYI UYU UZS VES VED VND VUV WST XAF XAG XAU XBA XBB XBC XBD XCD XDR XOF XPD XPF XPT XSU XTS XUA XXX YER ZAR ZMW ZWG ZWL ', concat(' ', normalize-space(.), ' '))))
BR-CL-10Test expression rewritten

Allowed scheme identifier list now includes "0231" through "0238"

The rule's allowed-code list has been extended with eight further scheme identifiers. The list previously ended at "0230"; it now continues with "0231", "0232", "0233", "0234", "0235", "0236", "0237", and "0238". The requirement that the scheme identifier contain no spaces, and the separate "SEPA" exception for supplier and payee parties, are unchanged.

fatalbusiness

Original rule text: [BR-CL-10]-Any identifier identification scheme identifier MUST be coded using one of the ISO 6523 ICD list.

Explanation and fix

What this rule requires

The rule requires the @schemeID attribute on the identifier in cac:PartyIdentification/cbc:ID (UBL) or ram:GlobalID (CII, excluding elements under ram:SpecifiedTradeProduct or ram:ShipToTradeParty) to be a code from the ISO 6523 ICD list. For UBL only, the value SEPA is also accepted if the element is within an cac:AccountingSupplierParty or cac:PayeeParty. If the attribute is present but empty or whitespace-only, contains a space, or is not one of the allowed values, the document fails validation.

How to fix

Set @schemeID to a valid ISO 6523 ICD code, for example 0002, 0003, 0088, or any other code from the rule's accepted list. In UBL, if the scheme must be SEPA, use exactly SEPA and ensure the identifier is inside an cac:AccountingSupplierParty or cac:PayeeParty. Check the current value for typos, extra spaces, or a code outside the allowed list.

Guidance on this rule. The original text above is authoritative.

BR-CL-10 rule details

Before · 2.2.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 ', concat(' ', normalize-space(@schemeID), ' ')))) or ((not(contains(normalize-space(@schemeID), ' ')) and contains(' SEPA ', concat(' ', normalize-space(@schemeID), ' '))) and ((ancestor::cac:AccountingSupplierParty) or (ancestor::cac:PayeeParty)))

After · 2.3.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238 ', concat(' ', normalize-space(@schemeID), ' ')))) or ((not(contains(normalize-space(@schemeID), ' ')) and contains(' SEPA ', concat(' ', normalize-space(@schemeID), ' '))) and ((ancestor::cac:AccountingSupplierParty) or (ancestor::cac:PayeeParty)))
BR-CL-11Test expression rewritten

Eight scheme identifiers, "0231" through "0238", are added to the ISO 6523 ICD list

The rule checks that the identification scheme identifier on a registration identifier is coded using one of the ISO 6523 ICD list. In the published 2.2.0 test, the embedded list of valid codes ended at "0230". In published 2.3.0, eight more codes were added: "0231", "0232", "0233", "0234", "0235", "0236", "0237", and "0238". The rest of the expression is unchanged.

fatalbusiness

Original rule text: [BR-CL-11]-Any registration identifier identification scheme identifier MUST be coded using one of the ISO 6523 ICD list.

Explanation and fix

What this rule requires

The rule requires that the @schemeID of cac:PartyLegalEntity/cbc:CompanyID (UBL) or ram:ID outside ram:SpecifiedTaxRegistration (CII) is coded using one of the ISO 6523 ICD identifiers. The test checks that the normalized value contains no spaces and matches one of the four-digit codes listed in the rule. A document fails when the @schemeID is missing, blank, contains spaces, or has a code not present in that list.

How to fix

Set the @schemeID attribute to a valid four-digit code from the ISO 6523 ICD list accepted by the rule, such as 0002 or 0003, without spaces. Check the exact code used against the codes listed in the rule.

Guidance on this rule. The original text above is authoritative.

BR-CL-11 rule details

Before · 2.2.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 ', concat(' ', normalize-space(@schemeID), ' '))))

After · 2.3.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238 ', concat(' ', normalize-space(@schemeID), ' '))))
BR-CL-04Test expression rewritten

Currency code list adds "VES", "VED" and "ZWG", drops "HRK" and "VEF"

The rule's expression still begins by checking that the normalized value contains no space, and then checks membership in a space-delimited list of ISO 4217 alpha-3 codes. That list changed between versions: it now includes "VES", "VED", and "ZWG", and it no longer includes "HRK" or "VEF". Nothing else in the expression changed.

fatalbusiness

Original rule text: [BR-CL-04]-Invoice currency code MUST be coded using ISO code list 4217 alpha-3

Explanation and fix

What this rule requires

The rule requires the invoice currency code to be a valid ISO 4217 alpha-3 currency code. It checks that the code contains no spaces and appears in the rule's list of accepted currency codes. A document fails if cbc:DocumentCurrencyCode (UBL) or ram:InvoiceCurrencyCode (CII) is empty, contains whitespace, or is not one of the listed codes.

How to fix

Set the currency code element to a three-letter ISO 4217 code from the list allowed by the rule, for example EUR, USD, or GBP. In UBL use cbc:DocumentCurrencyCode; in CII use ram:InvoiceCurrencyCode. Ensure the value contains no spaces.

Guidance on this rule. The original text above is authoritative.

BR-CL-04 rule details

Before · 2.2.0

((not(contains(normalize-space(.), ' ')) and contains(' AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND BOB BOV BRL BSD BTN BWP BYN BZD CAD CDF CHE CHF CHW CLF CLP CNY COP COU CRC CUC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HRK HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRO MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLE SOS SRD SSP STD SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD USN UYI UYU UZS VEF VND VUV WST XAF XAG XAU XBA XBB XBC XBD XCD XDR XOF XPD XPF XPT XSU XTS XUA XXX YER ZAR ZMW ZWL ', concat(' ', normalize-space(.), ' '))))

After · 2.3.0

((not(contains(normalize-space(.), ' ')) and contains(' AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND BOB BOV BRL BSD BTN BWP BYN BZD CAD CDF CHE CHF CHW CLF CLP CNY COP COU CRC CUC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRO MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLE SOS SRD SSP STD SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD USN UYI UYU UZS VES VED VND VUV WST XAF XAG XAU XBA XBB XBC XBD XCD XDR XOF XPD XPF XPT XSU XTS XUA XXX YER ZAR ZMW ZWG ZWL ', concat(' ', normalize-space(.), ' '))))
BR-CL-26Test expression rewritten

Delivery location scheme ISO 6523 code list extended with "0231" through "0238".

The test checks a delivery location scheme identifier against a whitespace-separated list of ISO 6523 ICD codes. The published 2.3.0 version adds "0231", "0232", "0233", "0234", "0235", "0236", "0237", and "0238" to that list, which previously ended at "0230". No other part of the expression changes.

fatalbusiness

Original rule text: [BR-CL-26]-Delivery location identifier scheme identifier MUST belong to the ISO 6523 ICD code list

Explanation and fix

What this rule requires

The rule requires that the schemeID attribute on the delivery location identifier (cac:DeliveryLocation/cbc:ID[@schemeID]) be one of the ISO 6523 ICD codes listed in the rule, with no spaces inside the value. The test rejects any value whose normalized form contains a space or is not in the embedded list. Since this is a fatal rule, an invoice with any other schemeID fails validation.

How to fix

Set the schemeID attribute to a code from the ISO 6523 ICD list, for example 0088, and ensure it has no internal spaces or whitespace. If you are unsure which code applies, check the identifier scheme used for the delivery location.

Guidance on this rule. The original text above is authoritative.

BR-CL-26 rule details

Before · 2.2.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 ', concat(' ', normalize-space(@schemeID), ' '))))

After · 2.3.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238 ', concat(' ', normalize-space(@schemeID), ' '))))
BR-CL-21Test expression rewritten

The rule now permits eight more ISO 6523 ICD codes, "0231" through "0238"

The test expression was widened: the list of permitted scheme identifiers from the ISO 6523 ICD code list previously ended at "0230", and it now also includes "0231", "0232", "0233", "0234", "0235", "0236", "0237", and "0238". The rule therefore accepts eight additional scheme identifiers. The other part of the condition — that the scheme identifier contains no whitespace — is unchanged.

fatalbusiness

Original rule text: [BR-CL-21]-Item standard identifier scheme identifier MUST belong to the ISO 6523 ICD code list

Explanation and fix

What this rule requires

The rule requires that the scheme identifier in the item standard identifier (cac:StandardItemIdentification/cbc:ID[@schemeID] in UBL, or ram:SpecifiedTradeProduct/ram:GlobalID[@schemeID] in CII) be exactly one code from the ISO 6523 ICD code list. The test checks that the value does not contain a space and matches one of the listed codes such as 0088, 0160, or 0248. Because the severity is fatal, a value that contains a space or is not among the listed codes causes the document to fail validation.

How to fix

Set the @schemeID attribute to a valid ISO 6523 ICD code from the rule's list, with no spaces inside the value. For example, use 0088 if that is the correct scheme for the item identifier. If the current value is not in the list, look up the correct ISO 6523 ICD code for the identifier scheme in use.

Guidance on this rule. The original text above is authoritative.

BR-CL-21 rule details

Before · 2.2.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 ', concat(' ', normalize-space(@schemeID), ' '))))

After · 2.3.0

((not(contains(normalize-space(@schemeID), ' ')) and contains(' 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 0234 0235 0236 0237 0238 ', concat(' ', normalize-space(@schemeID), ' '))))
BR-CL-03Test expression rewritten

Allowed currency code list drops "VEF" and adds "VES", "VED", "ZWG"

The rule still checks the currency identifier against a fixed list of ISO 4217 alpha-3 codes and still rejects identifiers whose normalized value contains a space. The list itself changed: "VEF" is no longer accepted, while "VES", "VED", and "ZWG" are now accepted. No other test condition changed.

fatalbusiness

Original rule text: [BR-CL-03]-currencyID MUST be coded using ISO code list 4217 alpha-3

Explanation and fix

What this rule requires

The rule requires that the @currencyID attribute on amount elements (UBL) or on ram:TaxTotalAmount (CII) contains an ISO 4217 alpha-3 currency code from the list accepted by the rule, and that the code contains no spaces. Because the severity is fatal, an invoice that does not satisfy this condition is rejected with message [BR-CL-03]-currencyID MUST be coded using ISO code list 4217 alpha-3.

How to fix

Set the currencyID attribute to a valid three-letter ISO 4217 alpha-3 code that appears in the rule's list, for example EUR or USD. Ensure the value is not empty and contains no spaces. In UBL this applies to amount elements such as cbc:TaxAmount; in CII it applies to ram:TaxTotalAmount[@currencyID]. If the current value is not a valid code, correct it in the source system.

Guidance on this rule. The original text above is authoritative.

BR-CL-03 rule details

Before · 2.2.0

((not(contains(normalize-space(@currencyID), ' ')) and contains(' AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND BOB BOV BRL BSD BTN BWP BYN BZD CAD CDF CHE CHF CHW CLF CLP CNY COP COU CRC CUC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HRK HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRO MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLE SOS SRD SSP STD SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD USN UYI UYU UZS VEF VND VUV WST XAF XAG XAU XBA XBB XBC XBD XCD XDR XOF XPD XPF XPT XSU XTS XUA XXX YER ZAR ZMW ZWL ', concat(' ', normalize-space(@currencyID), ' '))))

After · 2.3.0

((not(contains(normalize-space(@currencyID), ' ')) and contains(' AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND BOB BOV BRL BSD BTN BWP BYN BZD CAD CDF CHE CHF CHW CLF CLP CNY COP COU CRC CUC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRO MUR MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB RWF SAR SBD SCR SDG SEK SGD SHP SLE SOS SRD SSP STD SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD TZS UAH UGX USD USN UYI UYU UZS VES VED VND VUV WST XAF XAG XAU XBA XBB XBC XBD XCD XDR XOF XPD XPF XPT XSU XTS XUA XXX YER ZAR ZMW ZWG ZWL ', concat(' ', normalize-space(@currencyID), ' '))))
BR-DE-19Test expression rewritten

Payment means type code "58" with surrounding whitespace now triggers IBAN checks.

The first condition of the rule changed. Previously the payment means type code was compared to the exact value "58"; now leading and trailing whitespace is removed from that code before the comparison. A payment means type code with such whitespace around "58" is therefore treated as equal to "58" and goes on to the IBAN pattern and modulo checks. The IBAN pattern and modulo checks themselves are unchanged.

warningcountry

Original rule text: [BR-DE-19] "Payment account identifier" (BT-84) soll eine korrekte IBAN enthalten, wenn in "Payment means type code" (BT-81) mit dem Code 58 SEPA als Zahlungsmittel gefordert wird.

Explanation and fix

What this rule requires

The rule checks payment means where the payment means code is '30' or '58'. It only requires an IBAN when the code is '58' (SEPA). In that case, the payment account identifier (BT-84) must pass the IBAN validation function xr:checkIBAN. Since the severity is warning, the validator reports this but does not reject the document.

How to fix

For UBL: in cac:PaymentMeans with cbc:PaymentMeansCode = 58, provide a syntactically valid IBAN in cac:PayeeFinancialAccount/cbc:ID. For CII: in ram:SpecifiedTradeSettlementPaymentMeans with ram:TypeCode = 58, provide a valid IBAN in ram:PayeePartyCreditorFinancialAccount/ram:IBANID. If the code is 30, no change is needed for this rule. Check the value against the IBAN checksum that xr:checkIBAN applies.

Guidance on this rule. The original text above is authoritative.

BR-DE-19 rule details

Before · 2.2.0

not(cbc:PaymentMeansCode = '58') or matches(normalize-space(replace(cac:PayeeFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')), '^[A-Z]{2}[0-9]{2}[a-zA-Z0-9]{0,30}$') and xs:integer(string-join(for $cp in string-to-codepoints(concat(substring(normalize-space(replace(cac:PayeeFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),5),upper-case(substring(normalize-space(replace(cac:PayeeFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),1,2)),substring(normalize-space(replace(cac:PayeeFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),3,2))) return (if($cp > 64) then string($cp - 55) else string($cp - 48)),'')) mod 97 = 1

After · 2.3.0

not(normalize-space(cbc:PaymentMeansCode) = '58') or matches(normalize-space(replace(cac:PayeeFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')), '^[A-Z]{2}[0-9]{2}[a-zA-Z0-9]{0,30}$') and xs:integer(string-join(for $cp in string-to-codepoints(concat(substring(normalize-space(replace(cac:PayeeFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),5),upper-case(substring(normalize-space(replace(cac:PayeeFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),1,2)),substring(normalize-space(replace(cac:PayeeFinancialAccount/cbc:ID, '([ \n\r\t\s])', '')),3,2))) return (if($cp > 64) then string($cp - 55) else string($cp - 48)),'')) mod 97 = 1
BR-TMP-2New rule

New rule requires "External document location" to be an absolute URL with a valid scheme.

The rule is new in the 2.3.0 release. It tests the "External document location" value against the regular expression in the variable $XR-URL-REGEX. The check requires the value to be an absolute URL with a valid scheme. No equivalent check existed in 2.2.0.

warningbusiness

Original rule text: [BR-TMP-2] BT-124 "External document location" muss eine absolute URL mit gültigem Schema enthalten.

Explanation and fix

What this rule requires

The rule requires that the external document location (BT-124) contains an absolute URL with a valid scheme. In UBL, the element cbc:URI inside cac:AdditionalDocumentReference/cac:Attachment/cac:ExternalReference must match the pattern ^([a-zA-Z])([a-zA-Z0-9+.-])+:.*: it must start with a letter, followed by one or more characters from letters, digits, +, ., -, then a colon, then any characters. In CII, for the ram:AdditionalReferencedDocument with ram:TypeCode = '916', ram:URIID must either be absent or, if present, match the same pattern. This is a fatal rule, so a present but non-matching value causes the document to fail validation.

How to fix

In UBL, set cbc:URI to a value that matches the pattern, such as https://example.com/doc.pdf. In CII, if ram:URIID is present, set it to a matching absolute URL; if no external document location URI is needed, you may omit ram:URIID.

Guidance on this rule. The original text above is authoritative.

BR-TMP-2 rule details

Added · 2.3.0

matches(cbc:URI, $XR-URL-REGEX)

Which of these catch you depends on your invoices.

The rule diff is the same for everyone — what breaks is not. Upload a corpus once and every subsequent release gets replayed against your own invoices, so you see what breaks for you.