API reference › @evolu/common › Type › Iban
const Iban: brand(
"Iban",
String,
(value: string) => {
if (!/^[A-Z]{2}(?!00|01|99)\d{2}[A-Z0-9]{11,30}$/u.test(value)) {
return err<IbanError>({ type: "Iban", value });
}
// ISO 7064 MOD 97-10 reads the first four characters last and each letter
// as two digits (A = 10). Reducing after every character keeps the
// remainder a small integer, so no BigInt is needed.
let remainder = 0;
for (let index = 4; index < value.length + 4; index++) {
const code = value.charCodeAt(index % value.length);
remainder =
(code >= 65
? remainder * 100 + code - 55
: remainder * 10 + code - 48) % 97;
}
return remainder === 1 ? ok() : err<IbanError>({ type: "Iban", value });
},
formatIbanError,
);
Defined in: packages/common/src/Type.ts:9740
International Bank Account Number in the electronic format of ISO 13616.
Iban accepts two uppercase ASCII letters, two check digits from 02 to 98, and 11 to 30 uppercase ASCII letters and digits, 15 to 34 characters in total, and verifies the ISO 7064 MOD 97-10 checksum. Check digits 00, 01, and 99 are rejected even though they can pass the checksum, because they spell the same account as 97, 98, and 02, so every account has exactly one Iban.
Iban does not normalize. Remove the spaces that split the paper format into groups of four characters and uppercase the text before validating it.
Iban does not check the country code or the account length of each country. Countries join the SWIFT IBAN registry regularly, and a registry built into Iban would reject data synced from a client with a newer one.
Example
import { assertEqual, assertErr, assertOk, Iban } from "@evolu/common";
const value = "GB82WEST12345698765432";
assertOk(Iban.fromUnknown(value), value);
assertErr(Iban.fromUnknown("GB82WEST12345698765433"));
const paper = "gb82 west 1234 5698 7654 32";
const invalid = Iban.fromUnknown(paper);
assertErr(invalid);
assertEqual(invalid.error, { type: "Iban", value: paper });
assertOk(Iban.fromUnknown(paper.replaceAll(" ", "").toUpperCase()), value);