BR-KSA-16Payment means code is not one ZATCA accepts
Mutabiq checks Saudi ZATCA Phase 2 e-invoice XML before you submit it: pre-validation against published ZATCA requirements, not an approval by the authority. This page explains one rule, BR-KSA-16.
Five checks a month on the Free plan. The file is checked in memory and is never stored.
The message ZATCA prints
[BR-KSA-16]-Payment means code (BT-81) in an invoice exist, then it must contain one of the values from subset of UNTDID 4461 code list
What Mutabiq reports
One entry for each way this rule can be reported.
Reported as
What kind of value was found — empty, not_15_digits and the like — never the value itself.
Payment means code is not one ZATCA accepts
Reported ascode_not_permitteda code ZATCA does not accept
What is wrong
The document is a standard tax invoice and its cbc:PaymentMeansCode holds a value that ZATCA's check does not find in its list. Read the next part before changing anything, because the check is looser than the message and the check is what decides. The message lists five codes - 10, 30, 42, 48 and 1 - but the check behind it searches for your value as a piece of text inside the string ' 10 30 42 48 1 ', without putting delimiters around your value first. So it accepts values the message does not list: 8 is found inside 48 and passes, and so do 0, 2, 3, 4 and even an empty cbc:PaymentMeansCode, because a text search finds the empty string inside any string. This note therefore fires only on a value that appears nowhere in that string at all, such as 57, ZZ or CASH. The consequence for you is the other direction: a silent result here is not confirmation that your code is one of the five, and Mutabiq mirrors the check rather than promising a stricter one. There is a second limit worth knowing: if the document carries more than one cbc:PaymentMeansCode, ZATCA's expression hands a set of elements to a function that takes a single string, which is an error at the platform rather than a verdict, so no answer can be relied on for such a document; Mutabiq reads the first code as the conservative choice. This applies to standard tax invoices and their credit and debit notes only - the invoice transaction code KSA-2 beginning 01 - and the published message says as much: on a simplified invoice the payment means code is optional. Note also that ZATCA's Data Dictionary marks BT-81 optional on every document type while this assertion makes it mandatory on the three standard ones. The assertion is what the platform runs and what decides the outcome.
What to check in your ERP
The value comes from your payment method or payment terms table, and the usual causes are an internal code written straight through (CASH, BANK, CC, or a numeric key from your own table), a UNTDID 4461 code that is valid in that list but not on ZATCA's short subset (for example 20 for a cheque or 31 for a debit transfer), and a code padded or prefixed by a formatting step. Map your payment methods explicitly onto the five ZATCA lists - 10 cash, 30 credit transfer, 42 payment to bank account, 48 bank card, 1 instrument not defined - rather than passing your own values through, and check that only one cac:PaymentMeans block carries a code.
Standard invoice carries no payment means block
Reported aspayment_means_missingthe payment means block is missing
What is wrong
The document is a standard tax invoice and carries no cac:PaymentMeans element anywhere in it. Only rule packs before 2.0.0 report this: SDK 3.0.8's BR-KSA-16 asked three things in order - that a cac:PaymentMeans exists, that a cbc:PaymentMeansCode exists inside one, and that the code is found in the list ' 10 30 42 48 1 ' - and the first of the three failed here. In SDK 3.4.8, which rule pack 2.0.0 reads, BR-KSA-16 checks only the payment means codes a document carries, each against a subset of the UNTDID 4461 code list, as a warning (KSA:1835-1836); a document with no payment means gives it nothing to check, so a report produced under 2.0.0 never carries this note.
What to check in your ERP
Nothing needs changing for rule pack 2.0.0 on this account: BR-KSA-16 no longer asks for a payment means block. Where your export does write one, its code must be on the UNTDID 4461 subset the checker carries; the five codes the earlier list allowed - 10 for cash, 30 for credit transfer, 42 for payment to a bank account, 48 for a bank card and 1 where the instrument is not defined - are all on it.
Payment means block carries no payment means code
Reported ascode_element_missingthe code element is missing
What is wrong
The document is a standard tax invoice and carries at least one cac:PaymentMeans, but none of them holds a cbc:PaymentMeansCode. Only rule packs before 2.0.0 report this: SDK 3.0.8's BR-KSA-16 required a cbc:PaymentMeansCode inside a cac:PaymentMeans on a standard tax invoice, and here that element is absent - an empty one would have satisfied it. In SDK 3.4.8, which rule pack 2.0.0 reads, BR-KSA-16 checks only the payment means codes a document carries, each against a subset of the UNTDID 4461 code list, as a warning (KSA:1835-1836); a block with no code gives it nothing to check, so a report produced under 2.0.0 never carries this note.
What to check in your ERP
Nothing needs changing for rule pack 2.0.0 on this account: BR-KSA-16 no longer asks for the code. If you do write one, it must be on the UNTDID 4461 subset the checker carries, and write the element only when it has a value, because an empty code element is flagged.
The clause that runs
Quoted from the validation-rule stylesheet ZATCA publishes, at the file and line named below. The executed guard is what the check runs; the reported test is what it prints when it fails, and the two are not always the same.
As shipped in ZATCA SDK 3.4.8: the copy quoted here is, byte for byte, the file that release ships. The date in the file name is the name ZATCA gives the file; the rules in it are those of SDK 3.4.8.
A worked example
A synthetic document from the measured test corpus that trips this rule, shown where it differs from one that passed. Mutabiq's report names the class of the value, never the value itself.