Developer debugging guide
Why a checksum-valid IBAN can still be rejected.
MOD-97 answers one narrow question. A bank form, validation library or payment-provider sandbox can apply several additional contracts. Debug the exact layer that failed instead of treating every rejection as “invalid IBAN.”
Short answer: the value may have a correct structure and checksum but fail a national BBAN rule, miss the validator's bank registry, use an unsupported country, or differ from the provider's documented sandbox fixture.
Debug in this order
1. Normalize the inputRemove spaces, uppercase letters and preserve leading zeroes. Do not parse the BBAN as a number.
2. Check country structureVerify the country is supported and the exact length and character positions match its IBAN format.
3. Run MOD-97Move the first four characters, convert letters to numbers and confirm the remainder is 1.
4. Identify local rulesSome validators additionally evaluate a national account or BBAN checksum. Record whether this layer ran.
5. Pin registry evidenceA bank code or BIC may be absent, stale or outside the validator's dataset. Save the source and snapshot version.
6. Read the sandbox contractA provider can require its own published fixtures. A random checksum-valid value is not automatically a valid sandbox credential.
Keep the validation layers separate
| Layer | What a pass means | What it does not prove |
| Format | Country, length and character positions match the implemented rule. | Correct checksum, assigned bank or usable account. |
| MOD-97 | The international IBAN checksum is internally consistent. | National checksum, current bank registry match or account existence. |
| National checksum | The local BBAN rule passed when the validator supports it. | That every other library implements the same optional check. |
| Registry match | The identifier matches a bank record in one dated dataset. | Current reachability, ownership or universal provider support. |
| Provider fixture | The value is documented for one sandbox and expected scenario. | Suitability for another provider or a live payment. |
Make the failure reproducible
Record the normalized input, validator and version, exact failed layer, expected result and registry or provider source. The free starter kit carries those fields explicitly and runs without an API key.
python3 verify.py
node --test verify.test.js
Start with the ten static cases, then add the smallest case that reproduces your integration failure. Avoid storing a real customer's full IBAN in a public issue or fixture.
Need a bank-specific case?
First inspect current bank/BIC coverage. If a matching target exists, generate a synthetic case and keep the target, source version, expected checks and seed with the test artifact. If your provider requires fixed sandbox credentials, use the provider's documented fixture instead.
IBANgen provides synthetic QA data and validation evidence. It does not verify account ownership, balances, reachability or payment execution.