Skip to content

Commit

Permalink
Added support for Swedbank account with 5 digit clearing number star…
Browse files Browse the repository at this point in the history
…ting with 8

  - 5 digit celearing + nolla + account number 9 digits
  - used from some banks
  • Loading branch information
edgarbjorntvedt committed Feb 11, 2024
1 parent 40e0a6e commit 3b59dc1
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 21 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
Validation of IBAN and BBAN numbers and other country specific bank account formats. Extendable with custom validations

# Rules
## Swedish Bban rules is implemented based on this document:
https://www.bankgirot.se/globalassets/dokument/anvandarmanualer/bankernaskontonummeruppbyggnad_anvandarmanual_sv.pdf
EG25001000540
EG250010005400000100026173878
## Swedish Bban rules
Implementation is based on this document:
* https://www.bankgirot.se/globalassets/dokument/anvandarmanualer/bankernaskontonummeruppbyggnad_anvandarmanual_sv.pdf

And ading supporting for 5 digit clearing number as well:
* https://www.swedbank.se/privat/betala-och-overfora/konton/clearingnummer/5-siffriga-clearingnummer-som-borjar-pa-siffran-8.html
15 changes: 10 additions & 5 deletions src/validators/SwedishBbanValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ interface Account{
}

function extractClearingNumber(_clearing: string | null, bban: string) {
return _clearing ? parseInt(_clearing) : parseInt(bban.substr(0, 4))
return _clearing ? parseInt(_clearing) : parseInt(bban.slice(0, 4))
}

function extractAccountNumberOnly(_clearing: string | null, bban: string) {
return _clearing ? bban : bban.substr(4)
return _clearing ? bban : bban.slice(4)
}

function getType(clearingNumber:number):string {
Expand Down Expand Up @@ -64,11 +64,14 @@ function parseClearingAndAccountNumber(_clearing:string|null, bban:string):Accou
export class SwedishBbanValidation implements IStrictValidation {
_config: types.BankAccountValidationConfig
private _syntaxTester: RegExp
private _syntaxTesterSwedbank: RegExp

constructor(config: Partial<types.BankAccountValidationConfig>) {
this._config = defaultsDeep({}, config, defaultConfig)
/* syntax: optional clearing (4 digit) + account number (7, 9 or 10 digit)*/
this._syntaxTester = /^(\d{4}(:?\d{7}|\d{9}|\d{10})|(:?\d{7}|\d{9}|\d{10}))$/
/* syntax: 5 digit clearing starting with 8 + nolla + account number 9 digit */
this._syntaxTesterSwedbank = /^8\d{4}0\d{9}$/
}

canValidate(input: ValidationInput): Boolean {
Expand All @@ -94,7 +97,7 @@ export class SwedishBbanValidation implements IStrictValidation {

const account = parseClearingAndAccountNumber(input.clearingNumber || null, input.accountNumber)

const validSyntax = this._syntaxTester.test(account.bban)
const validSyntax = this._syntaxTester.test(account.bban) || this._syntaxTesterSwedbank.test(account.bban)

if (!validSyntax){
return {
Expand All @@ -104,11 +107,13 @@ export class SwedishBbanValidation implements IStrictValidation {
}

if (
account.type === '1.1' && account.length === 7 && sweMod11(account.bban.substr(1)) ||
account.type === '1.1' && account.length === 7 && sweMod11(account.bban.slice(1)) ||
account.type === '1.2' && account.length === 7 && sweMod11(account.bban) ||
account.type === '2.1' && account.length === 10 && sweMod10(account.accountNumber) ||
account.type === '2.2' && account.length === 9 && sweMod11(account.accountNumber) ||
account.type === '2.3' && account.length === 10 && sweMod10(account.accountNumber)
account.type === '2.3' && account.length === 10 && sweMod10(account.accountNumber) ||
// supporting 5 digit clearing number - Swedbank
account.type === '2.3' && account.length === 11 && sweMod10(account.accountNumber.slice(-10))
){
return {
valid: true,
Expand Down
60 changes: 48 additions & 12 deletions test/SE/testBbanValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,6 @@ describe('SwedishBbanValidation', ()=> {
reason: null
})
})
it('should validate a valid type 2.3 Swedish BBAN account (Swedbank)', ()=>{
chai.expect(validation.validate({accountNumber: '83881122211004'})).to.deep.equal({
'valid': true,
reason: null
})
})

it('should invalidate an invalid Swedish BBAN account', ()=>{
chai.expect(validation.validate({accountNumber: '54401122004'})).to.deep.equal({
Expand Down Expand Up @@ -135,12 +129,6 @@ describe('SwedishBbanValidation', ()=> {
reason: null
})
})
it('should validate a valid type 2.3 Swedish BBAN account (Swedbank)', ()=>{
chai.expect(validation.validate({clearingNumber:'8388', accountNumber: '1122211004'})).to.deep.equal({
'valid': true,
reason: null
})
})

xit('should invalidate an invalid Swedish BBAN account', ()=>{
chai.expect(validation.validate({clearingNumber:'5440', accountNumber: '1122004'})).to.deep.equal({
Expand Down Expand Up @@ -171,6 +159,54 @@ describe('SwedishBbanValidation', ()=> {
})
})

describe('4 char clearing number type 2.3 (that starts with 8) Swedish Swedbank BBAN account ', ()=> {
// CCCC0KKKKKKKKK
// (4 siffror i clearingnumret, en extra nolla, 9 siffror i kontonumret - totalt 14 siffror).
it('should validate a valid type 2.3 Swedish BBAN account (Swedbank)', ()=>{ // TODO: here
chai.expect(validation.validate({accountNumber: '83880122211006'})).to.deep.equal({
'valid': true,
reason: null
})
})
it('should validate account number with starting 0', ()=>{
chai.expect(validation.validate({clearingNumber:'8388', accountNumber: '0122211006'})).to.deep.equal({
'valid': true,
reason: null
})
})

it('should validate account number without starting 0', ()=>{
chai.expect(validation.validate({clearingNumber:'8388', accountNumber: '122211006'})).to.deep.equal({
'valid': true,
reason: null
})
})
})

describe('5 char clearing number type 2.3 (that starts with 8) Swedish Swedbank BBAN account ', ()=> {
// CCCCC0KKKKKKKKK
// (5 siffror i clearingnumret, en extra nolla, 9 siffror i kontonumret - totalt 15 siffror).
it('should validate a valid type 2.3 Swedish BBAN account (Swedbank)', ()=>{
chai.expect(validation.validate({accountNumber: '838890122211006'})).to.deep.equal({
'valid': true,
reason: null
})
})
it('should validate account number with starting 0', ()=>{
chai.expect(validation.validate({clearingNumber:'83889', accountNumber: '0122211006'})).to.deep.equal({
'valid': true,
reason: null
})
})

it('should validate account number without starting 0', ()=>{
chai.expect(validation.validate({clearingNumber:'83889', accountNumber: '122211006'})).to.deep.equal({
'valid': true,
reason: null
})
})
})

describe('when determining suitability', ()=> {
it('should accept a Swedish country', ()=>{
chai.expect(validation.canValidate({accountNumber: 'invalid', countryCode: 'SE', type: 'bban'})).to.equal(true)
Expand Down

0 comments on commit 3b59dc1

Please sign in to comment.