Advertisement

Developer how-tos

IBAN explained: structure, check digits and test IBANs

An IBAN packs a country code, two check digits and a domestic account number into one string that banks across dozens of countries can read. This guide takes it apart, works through the mod-97 check by hand, gives tested validation code and explains what a valid IBAN does — and does not — prove.

By the Fakecreditcard teamPublished 9 min read

Advertisement

Key takeaways

  • An IBAN is a two-letter country code, two check digits and a country-specific BBAN, up to 34 characters in total.
  • Validation is mechanical: check the length for the country, move the first four characters to the end, turn letters into numbers and test that the result mod 97 equals 1.
  • A valid IBAN only proves the string is well formed. It says nothing about whether the account exists or who owns it.
  • Use published example IBANs or a generator for tests, and never send a real payment to a generated IBAN.
On this page
  1. What an IBAN is
  2. The structure of an IBAN
  3. IBAN lengths by country
  4. How the check digits work
  5. IBAN validation code
  6. What a valid IBAN does — and does not — prove
  7. IBAN, BIC and SWIFT codes
  8. Test IBANs for development
  9. Frequently asked questions

If your product moves money between bank accounts — payouts, refunds by transfer, direct debits, invoicing — you will collect IBANs. They look intimidating, but they follow a small set of public rules, and validating one takes a dozen lines of code. Knowing those rules also tells you where validation stops and where the bank’s own checks have to take over.

What an IBAN is

The International Bank Account Number is defined by the ISO 13616 standard, first published in 1997 and most recently revised in 2020. It wraps each country’s existing domestic account number in a common envelope, so a bank in one country can recognize, route and sanity-check an account number from another without knowing every national format by heart. SWIFT acts as the registrar under ISO 13616 and publishes the IBAN registry, which lists the structure and length for every participating country.

IBANs are used across Europe — including the 41 countries of the Single Euro Payments Area (SEPA), where they are the standard account identifier for euro transfers and direct debits — and in many countries of the Middle East, North Africa, the Caribbean and Latin America. Several large economies, including the United States, Canada and Australia, do not use them.

The structure of an IBAN

Every IBAN has the same three parts. Here is the textbook British example, GB82 WEST 1234 5698 7654 32:

PartExampleWhat it is
Country codeGBISO 3166-1 alpha-2 code of the country where the account is held
Check digits82Two digits computed with ISO 7064 MOD 97-10 over the whole IBAN
BBANWEST12345698765432The Basic Bank Account Number: the domestic bank, branch and account identifiers in the country’s own layout, up to 30 characters

Electronic and paper formats

In files, APIs and databases, an IBAN is written as one unbroken string of up to 34 uppercase letters and digits. On paper and on screens it is usually split into groups of four separated by spaces, as above, to make it easier to read aloud and copy. Your forms should accept both, strip the spaces, and store the electronic format.

Reading the BBAN

The BBAN is where countries differ. In the British example, WEST identifies the bank, 123456 is the sort code and 98765432 is the account number. A German BBAN is an eight-digit bank code followed by a ten-digit account number. Some countries embed their own national check digits inside the BBAN as well, which a strict validator can verify in addition to the IBAN check digits.

Advertisement

IBAN lengths by country

The length is fixed per country, so checking it is the cheapest validation you can run. These examples are taken from the IBAN registry’s published samples and all pass the check-digit test:

CountryLengthBBAN layoutExample IBAN
Norway (NO)15bank 4 digits · account 6 · national check 1NO9386011117947
Belgium (BE)16bank 3 digits · account 7 · national check 2BE68539007547034
Netherlands (NL)18bank 4 letters · account 10 digitsNL91ABNA0417164300
Switzerland (CH)21clearing number 5 digits · account 12 charactersCH9300762011623852957
Germany (DE)22bank code (BLZ) 8 digits · account 10DE89370400440532013000
United Kingdom (GB)22bank 4 letters · sort code 6 digits · account 8GB29NWBK60161331926819
United Arab Emirates (AE)23bank 3 digits · account 16AE070331234567890123456
Spain (ES)24bank 4 · branch 4 · national check 2 · account 10ES9121000418450200051332
Saudi Arabia (SA)24bank 2 digits · account 18 charactersSA0380000000608010167519
Turkey (TR)26bank 5 digits · reserved 1 · account 16 charactersTR330006100519786457841326
France (FR)27bank 5 · branch 5 · account 11 characters · RIB key 2FR1420041010050500013M02606
Italy (IT)27CIN letter · ABI 5 · CAB 5 · account 12 charactersIT60X0542811101000000123456
Poland (PL)28bank and branch 8 digits · account 16PL61109010140000071219812874
Brazil (BR)29bank 8 · branch 5 · account 10 · type 1 letter · owner 1BR1800360305000010009795493C1
Malta (MT)31bank 4 letters · branch 5 digits · account 18 charactersMT84MALT011000012345MTLCAST001S

Note how the layouts mix digits and letters. The Netherlands and the UK start the BBAN with a four-letter bank code, Italy begins with a check letter, and France allows letters inside the account number. A validator that expects digits only after the check digits will reject valid IBANs from those countries.

How the check digits work

The two check digits make the whole IBAN, read as one big number in a particular way, leave a remainder of exactly 1 when divided by 97. A single mistyped character or a swap of two neighboring characters almost always breaks that property, so the check catches the typing mistakes people actually make.

Validating an IBAN step by step

  1. Normalize. Remove spaces and convert to uppercase: GB82WEST12345698765432.
  2. Check the length for the country: GB IBANs have 22 characters.
  3. Move the first four characters to the end: WEST12345698765432GB82.
  4. Replace each letter with two digits, where A = 10, B = 11 … Z = 35. W becomes 32, E 14, S 28, T 29, G 16 and B 11, giving 3214282912345698765432161182.
  5. Divide by 97. The remainder is 1, so the IBAN is valid. Any other remainder means it is not.

Doing it without big integers

That number has 28 digits, more than a 64-bit integer can hold. Languages with arbitrary-precision integers (Python, Java’s BigInteger, JavaScript’s BigInt) can compute it directly. Elsewhere, process the digits in pieces: take the first nine digits, reduce them mod 97, write the two-digit remainder in front of the next seven digits, and repeat.

StepNumbermod 97
132142829170
270234569829
329765432124
424611821

The last remainder is 1, the same result as the direct calculation.

Calculating check digits for a new IBAN

To build an IBAN from a country code and a BBAN, put 00 in place of the check digits and run the same steps. For the German BBAN 370400440532013000: rearranged with zeros, the string is 370400440532013000DE00, which becomes 370400440532013000131400. That leaves a remainder of 9, and the check digits are 98 − 9 = 89 (padded to two digits when needed). The finished IBAN is DE89370400440532013000.

IBAN validation code

Both snippets accept the paper format with spaces, check the general shape, then run the mod-97 test. In production, also compare the length against a per-country table such as the one above.

Python

Python
import re


def to_digits(s: str) -> str:
    return ''.join(str(int(c, 36)) for c in s)  # '0'-'9' stay, 'A' -> '10' ... 'Z' -> '35'


def iban_valid(iban: str) -> bool:
    s = re.sub(r'\s+', '', iban).upper()
    if not re.fullmatch(r'[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}', s):
        return False
    return int(to_digits(s[4:] + s[:4])) % 97 == 1


def iban_check_digits(country: str, bban: str) -> str:
    return f'{98 - int(to_digits(bban + country + "00")) % 97:02d}'


print(iban_valid('GB82 WEST 1234 5698 7654 32'))     # True
print(iban_check_digits('DE', '370400440532013000'))  # 89

JavaScript

JavaScript
function mod97(digits) {
  let rem = 0;
  for (let i = 0; i < digits.length; i += 7) {
    rem = Number(String(rem) + digits.slice(i, i + 7)) % 97;  // piecewise: no BigInt needed
  }
  return rem;
}

function toDigits(s) {
  return s.replace(/[A-Z]/g, (c) => String(c.charCodeAt(0) - 55));
}

function ibanValid(input) {
  const s = String(input).replace(/\s+/g, '').toUpperCase();
  if (!/^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/.test(s)) return false;
  return mod97(toDigits(s.slice(4) + s.slice(0, 4))) === 1;
}

function ibanCheckDigits(country, bban) {
  return String(98 - mod97(toDigits(bban + country + '00'))).padStart(2, '0');
}

console.log(ibanValid('GB82 WEST 1234 5698 7654 32'));  // true
console.log(ibanCheckDigits('DE', '370400440532013000'));  // '89'

The {11,30} in the shape check reflects the shortest BBAN in use (Norway’s 11 characters) and the standard’s 30-character maximum. Our IBAN checker runs the full per-country length and format check and shows each step for any IBAN you paste in.

What a valid IBAN does — and does not — prove

Passing the checks tells you the string is well formed for its country and was very probably typed correctly. That is valuable: it stops most failed transfers caused by typos before they cost a returned-payment fee. It does not tell you:

  • That the account exists. Anyone can compute valid check digits for any BBAN, which is exactly what an IBAN generator does.
  • Who owns it. The IBAN carries no name. Name-matching services such as Confirmation of Payee in the UK and Verification of Payee in the EU compare the payee name with the account holder before a transfer is sent.
  • That it can receive the payment. The account may be closed, blocked, or of a type that does not accept the currency or payment scheme you use.

Treat IBAN validation like the Luhn check for card numbers: a fast, local guard against typos, with the bank having the final word.

IBAN, BIC and SWIFT codes

People often confuse these identifiers, and forms that ask for the wrong one cause failed payments.

IdentifierStandardIdentifiesExample
IBANISO 13616One bank accountGB82WEST12345698765432
BIC (“SWIFT code”)ISO 9362A bank or branch, 8 or 11 charactersDEUTDEFF
BBAN / domestic numberNationalThe account inside its own countryWEST 123456 98765432

For euro transfers within SEPA, the IBAN is normally all you need; asking customers for a BIC there adds friction for no benefit. For international transfers outside SEPA, banks typically ask for both the IBAN (where the destination country uses one) and the receiving bank’s BIC.

Test IBANs for development

Real IBANs are personal data. Copying customers’ account details into a development database, a bug report or a test fixture creates the same kind of exposure that PCI DSS forbids for card numbers. For testing, use one of these instead:

  • Registry examples such as those in the table above. They are published as samples for exactly this purpose and are widely recognized as test values.
  • Generated IBANs. Our IBAN generator builds IBANs with the correct length, layout and check digits for many countries, so you can test per-country formatting and bulk imports.
  • Payment provider test values. If you use a provider for SEPA Direct Debit or payouts, its sandbox documents specific IBANs that simulate success, failure and returns. Use those for end-to-end tests.

Never send money to a generated IBAN

A generated IBAN is random within a valid structure. In a live system a transfer to it either fails or, by chance, reaches a real person’s account. Keep generated IBANs in test environments only.

A short test plan

  • Valid examples from several countries, with and without spaces and in lowercase.
  • The same IBANs with one character changed and with two neighboring characters swapped (must fail).
  • A valid IBAN with one character removed or added (must fail on length).
  • IBANs with letters in the BBAN (Netherlands, UK, France, Italy) to make sure your validator does not assume digits.
  • An unknown or non-IBAN country code, such as US (must fail with a clear message).

Frequently asked questions

How many characters does an IBAN have?

It depends on the country, from 15 in Norway to more than 30 in a few countries, with 34 as the maximum the standard allows. Germany and the UK use 22, France and Italy 27.

What are the two digits after the country code?

They are check digits calculated with the ISO 7064 MOD 97-10 method over the whole IBAN. They let software detect typing mistakes before a payment is sent.

Does a valid IBAN mean the account exists?

No. A validator only confirms the length, the format and the check digits. Only the receiving bank knows whether the account is open and who holds it; name-checking services such as Confirmation of Payee in the UK and Verification of Payee in the EU address that separately.

What is the difference between an IBAN and a BIC or SWIFT code?

The IBAN identifies an individual account. The BIC (ISO 9362, often called a SWIFT code) identifies the bank. Within the SEPA area, the IBAN alone is normally enough for euro transfers.

Can I use a generated IBAN to receive money?

No. A generated IBAN has valid structure and check digits, but no bank opened the account. A transfer to it fails or, by chance, reaches someone else’s account, so use generated IBANs only as test data.

Does the United States use IBANs?

No. The US, Canada and Australia, among others, do not use IBANs. Payments to those countries use domestic routing and account numbers together with the bank’s BIC.

Sources

  1. Wikipedia — International Bank Account Number (structure, validation, country lengths)
  2. European Central Bank — Single Euro Payments Area (SEPA)

Tools used in this guide

Related guides

Written for developers, QA teams and merchants. Generated card numbers are test data: they are not real cards and cannot pay for anything.

Advertisement