pain.001 Validator

Why Valid pain.001 Files Still Get Rejected

XSD-valid pain.001 files get rejected by banks every day. Learn the hidden validation layers banks apply on top of the schema — and how to catch them before submission.

What XSD validation actually checks

The ISO 20022 XML Schema (XSD) validates the structure of your pain.001 file: element names, data types, ordering, and cardinality. A file that passes XSD is well-formed — every tag is in the right place and every field has the right format.

But XSD knows nothing about your business logic. It cannot verify that the sum of all transactions matches the declared control sum. It cannot check whether your IBAN is valid. It cannot enforce that a specific bank only accepts certain field combinations.

XSD-valid file — will still be rejected by the bank

<GrpHdr>
  <MsgId>MSG-001</MsgId>
  <CreDtTm>2024-01-15T10:00:00</CreDtTm>
  <NbOfTxs>2</NbOfTxs>
  <CtrlSum>1000.00</CtrlSum>  <!-- Declared sum -->
</GrpHdr>
<PmtInf>
  <CdtTrfTxInf>
    <InstdAmt Ccy="CHF">600.00</InstdAmt>
  </CdtTrfTxInf>
  <CdtTrfTxInf>
    <InstdAmt Ccy="CHF">600.00</InstdAmt>  <!-- Actual sum: 1200.00 -->
  </CdtTrfTxInf>
</PmtInf>

Bank overlays and compliance profiles

Banks and payment networks define overlays on top of the base ISO 20022 schema. These overlays restrict or extend the standard in ways specific to each institution or payment rail.

The Swiss Payment Standards CH.03 profile (pain.001.001.09.ch.03.xsd) adds mandatory fields, restricts character sets, and enforces rules about QR-bill references. The UBS overlay adds further restrictions on top of CH.03. SEPA Credit Transfer defines its own subset of pain.001 elements.

A file that is valid per the base ISO XSD may be completely invalid for a specific bank's profile — and the bank will reject it without explanation other than a terse error code.

The business rule layer

Even after XSD and profile checks pass, banks run business rule validation. These are semantic checks the schema cannot express:

Business rules that XSD cannot validate

CtrlSum = sum of all InstdAmt values across all CdtTrfTxInf
NbOfTxs = count of all CdtTrfTxInf elements
IBAN checksum = MOD97 algorithm on the account number
BIC format = 8 or 11 characters, valid institution code
EqvtAmt = forbidden in most CH.03 profiles

A real rejection example

A payment file passes XSD validation. The developer assumes it is ready to submit. The bank returns: 'RJCT / AM09 / ControlSum does not match.' The file contained 3 transactions of CHF 33.33 each. The declared CtrlSum was CHF 100.00. The actual sum: 3 × 33.33 = 99.99. The floating-point accumulation produced a rounding mismatch that XSD cannot detect.

Floating-point arithmetic in payment files causes CtrlSum mismatches more often than any other single error. Always accumulate amounts as integers (cents) and convert to decimal at the end.

Catch these before submission

Pre-validation means running all three layers — XSD, business rules, and bank profile — against your file before it reaches the bank. This catches the majority of rejections in development, not in production.

Why Valid pain.001 Files Still Get Rejected — Ifriqa