ibantools icon indicating copy to clipboard operation
ibantools copied to clipboard

German IBAN is considered valid, while it's not

Open s-gurevich opened this issue 3 years ago • 4 comments

Describe the bug As stated in https://github.com/Simplify/ibantools/issues/36 the account number validation is not yet implemented for every country. But you continue to add support for different countries. We would greatly appreciate it if you could support the evaluation of German IBANs.

To Reproduce DE08664518620010204868 isValidIBAN and validateIBAN state that it is "valid"

Expected behavior isValidIBAN and validateIBAN recognize it as "invalid"

Additional context Related to https://github.com/Simplify/ibantools/issues/36

s-gurevich avatar Mar 04 '22 12:03 s-gurevich

Hi @s-gurevich I'll be happy to add support for account number validation for Germany, but my understanding is that every bank in Germany has their own way to validate account number. I could not find any details or documentation related to that so I decides to skip Germany for now. Same thing about Austria and few other countries. If you have any details, please let me know.

Simplify avatar Mar 10 '22 13:03 Simplify

To validate the german bank codes it is necessary to check inside a file on the official german central bank website. Any solution to validating german ibans therefore must have access to the current "Bankleitzahlendateien" file, which gets updated multiple times per year as far as I can see. Since the file in question is ~1 MB in size, it would need to be processed first into a different format, probably json, to bundle it with the library.

Screenshot from 2022-03-22 07-43-15

Maybe support for the different country bank codes could be added like it is done in locale aware libraries, such as the i18n integration in vee-validate to keep the bundle size down if validation for certain countries is not needed.

AntonioDell avatar Mar 22 '22 06:03 AntonioDell

The problem is not the file size of the Bankleitzahlen file itself. It would be possible to shrink it down to a more reasonable size. The problem is the the checksum for the bank account number (Prüfziffernberechnungsmethode).

If you take a look at the aforementioned IBAN DE08664518620010204868 which contains the BLZ 66451862 and bank account number 0010204868. In the Bankleitzahlen file you would find 66451862 as a valid BLZ for "Sparkasse Hanauerland"

In the screenshot above you see the 9th column ("Prüfziffer- berechnung-") which contains a two char code referring to a certain checksum calculation method. You can find all the definitions at Bundesbank's website. There are currently over 100 different methods (mostly some kind of different modulo with different weights) and in theory this list can be changed or extended quarterly with the quarterly updates of the Bankleitzahlen file.

My elaborate guess would be that just the implementation for all of those methods would require more lines of code than ibantools currently has in total for all the other functionality.

baumerdev avatar Aug 24 '22 11:08 baumerdev

I will add support for custom validation function in the future, so it will be possible to make separate package as add-on for this kind of problems. I can't see myself writing package for validating different German banks account numbers in the next 6 months.

Simplify avatar Sep 11 '22 15:09 Simplify

Hi @Simplify I found the time to start a project and code all the implementations and tests for the roundabout 120 check digit methods, currently in use in German bank accounts.

https://github.com/baumerdev/ibantools-germany

This library converts the raw data of Deutsche Bundesbank into a smaller JSON file only containing the data needed (mapping the BLZ [=bank sort code] to the relevant check digit method ID).

If you call something like the example of @s-gurevich

import { isValidIBAN } from "ibantools-germany";
isValidIBAN("DE08664518620010204868");

You will receive false since the account number check digit is wrong (the last digit of the account number has to be 6 and not 8 ... and of course the IBAN check digit would obviously change too).

The library contains a function isValidBBAN which has the same signature as bban_validation_func so you can use it as a drop-in replacement:

import { isValidIBAN, countrySpecs } from "ibantools";
import { isValidBBAN } from "ibantools-germany";

console.log(isValidIBAN("DE08664518620010204868")); // true; even if incorrect
console.log(isValidIBAN("DE62664518620010204866")); // true

// We can simply overwrite/set the method for validating German BBAN in ibantools
countrySpecs.DE.bban_validation_func = isValidBBAN;

console.log(isValidIBAN("DE08664518620010204868")); // false; now fixed
console.log(isValidIBAN("DE62664518620010204866")); // true

(I'm not really sure that countrySpecs is an object that should be exported though … since it raises some security concerns if it can this easily be modified)

Of course it would be nicer to have a helper function in ibantools like this:

function setCountryBBANValidation(country: string, func: (bban: string) => boolean): boolean {
  if (typeof countrySpecs[country] === "undefined") {
    return false;
  }
  countrySpecs[country].bban_validation_func = func;
  return true;
}

baumerdev avatar Oct 22 '22 19:10 baumerdev

@baumerdev thanks a lot. If you can and have time, please make PR with that function that will allow custom validation function + tests. Feel free to add link your package in README too. I'll merge it and make new release as soon as I can. Do not hide countrySpecs yet, as some banks/companies use it to add some country codes that don't exist, to use it internally. I'll probably stop exporting that in next mayor release and maybe add functionality to insert new country specification.

Simplify avatar Oct 24 '22 13:10 Simplify

@Simplify I just created a PR for the added function and complete tests. I also added my library + example for the new function to the README file ... please have a look if it's okay that way or feel free to change it to whatever suits you best.

baumerdev avatar Oct 26 '22 17:10 baumerdev

This would be a great addition, we also need this functionality.

Question: Do we have a similar issue for BIC/SWIFT checks with German numbers? Maybe that's a dumb question, but I wanted to make sure, the same can't come up for those as well

icebearlabs avatar Nov 09 '22 15:11 icebearlabs

@icebearlabs If you install the packages npm install --save ibantools-germany@latest and inject it into ibantools via

import { isValidBBAN } from "ibantools-germany";
countrySpecs.DE.bban_validation_func = isValidBBAN;

(see my example from my previous answer) you are good to go. The open PR mainly contains a convenience function which does the same as overwriting countrySpecs.DE.bban_validation_func = isValidBBAN; manually.

If you want to validate German BIC as well you can use https://github.com/baumerdev/bankdata-germany npm install --save bankdata-germany@latest which provides a function for validation

import { isValidBIC } from "bankdata-germany"
isValidBIC("MARKDEFF"); // true

This isn't based on an algorithm but checks agains a dataset included in the package, containing the current bank data (for that reason it has a larger file size and I would only use it server side). Since there currently is no hook for that in ibantools you have to extends it somehow like that:

import { isValidBIC as isValidBICde } from "bankdata-germany"

function isValidBIC(bic: string) {
  const result = ibantools.validateBIC(bic):
  if (result.valid === false || bic.toUpperCase().slice(4,6) !== "DE") {
    return result.valid;
  }
  return isValidBICde(bic)
}

baumerdev avatar Nov 09 '22 17:11 baumerdev

@baumerdev Thanks a lot, PR is merged. I'll make new release today.

Simplify avatar Nov 09 '22 20:11 Simplify