Skip to content

Commit

Permalink
Merge pull request #255 from gocardless/iban-validation-sweden-3300
Browse files Browse the repository at this point in the history
Fix validation for Swedish IBANs in clearing code 3300
  • Loading branch information
jcollins-gc authored Feb 14, 2025
2 parents 6e1201d + ee4a0bf commit 38e2405
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ Gemfile.lock
.bundle
*.gem
.DS_Store
.idea
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.23.0 - February 14, 2025

- Fix validation for SE IBANs for clearing code 3300 where the account number starts with a 0

## 1.22.0 - January 22, 2025

- Remove support for Ruby < 3.1, add support for Ruby >= 3.4
Expand Down
7 changes: 5 additions & 2 deletions data/raw/swedish_bank_lookup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# - As of 30/10/2020: https://www.bankgirot.se/globalassets/dokument/anvandarmanualer/bankernaskontonummeruppbyggnad_anvandarmanual_sv.pdf
# - Swedish Bankers' Association clearing numbers: https://www.swedishbankers.se/media/4245/1906_clearingnummer-institut.pdf
# - https://transferwise.com/gb/iban/sweden
# - Bankgirot: https://www.bankgirot.se/globalassets/dokument/anvandarmanualer/bankernaskontonummeruppbyggnad_anvandarmanual_sv.pdf
# - Svensk betalinfrastruktur: https://www.bankinfrastruktur.se/framtidens-betalningsinfrastruktur/iban-och-svenskt-nationellt-kontonummer
#
# Fields:
# - Range: The range of clearing codes for this bank. Used to
Expand Down Expand Up @@ -79,10 +81,11 @@
:bank: Nordea Personkonto
# NOTE: We're routing Nordea Personkonto to the main Nordea bank code, but
# it may belong at one of the other Nordea codes we're not currently using.
# Account numbers for this clearing number are the same as personal ID numbers.
:bank_code: 300
:clearing_code_length: 4
:serial_number_length: 10
:zerofill_serial_number: false
:zerofill_serial_number: true
:include_clearing_code: false
:validation_scheme: '2.1'
- :range: [3301, 3399]
Expand Down Expand Up @@ -117,7 +120,7 @@
:clearing_code_length: 4
:serial_number_length: 10
:zerofill_serial_number: false
:include_clearing_code: fase
:include_clearing_code: false
:validation_scheme: '2.1'
- :range: [3783, 3999]
:bank: Nordea
Expand Down
2 changes: 1 addition & 1 deletion lib/ibandit/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Ibandit
VERSION = "1.22.0"
VERSION = "1.23.0"
end
84 changes: 84 additions & 0 deletions spec/ibandit/iban_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,90 @@
its(:to_s) { is_expected.to eq("SE5412000000012810105723") }
end

context "when the IBAN was created from a Swedish IBAN" do
context "where the clearing code is part of the account number" do
let(:arg) { "SE4730000000031231234567" }

its(:country_code) { is_expected.to eq("SE") }
its(:bank_code) { is_expected.to be_nil }
its(:branch_code) { is_expected.to be_nil }
its(:account_number) { is_expected.to be_nil }
its(:swift_bank_code) { is_expected.to eq("300") }
its(:swift_branch_code) { is_expected.to be_nil }
its(:swift_account_number) { is_expected.to eq("00000031231234567") }
its(:iban) { is_expected.to eq("SE4730000000031231234567") }
its(:pseudo_iban) { is_expected.to be_nil }
its(:to_s) { is_expected.to eq("SE4730000000031231234567") }
its(:valid?) { is_expected.to eq(true) }
end

context "where the clearing code is not part of the account number" do
let(:arg) { "SE7160000000000123456789" }

its(:country_code) { is_expected.to eq("SE") }
its(:bank_code) { is_expected.to be_nil }
its(:branch_code) { is_expected.to be_nil }
its(:account_number) { is_expected.to be_nil }
its(:swift_bank_code) { is_expected.to eq("600") }
its(:swift_branch_code) { is_expected.to be_nil }
its(:swift_account_number) { is_expected.to eq("00000000123456789") }
its(:iban) { is_expected.to eq("SE7160000000000123456789") }
its(:pseudo_iban) { is_expected.to be_nil }
its(:to_s) { is_expected.to eq("SE7160000000000123456789") }
its(:valid?) { is_expected.to eq(true) }
end

context "where the clearing code is 3300, and therefore the account number is the national ID" do
context "where the person was born in the 1990s" do
let(:arg) { "SE2130000000009308127392" }

its(:country_code) { is_expected.to eq("SE") }
its(:bank_code) { is_expected.to be_nil }
its(:branch_code) { is_expected.to be_nil }
its(:account_number) { is_expected.to be_nil }
its(:swift_bank_code) { is_expected.to eq("300") }
its(:swift_branch_code) { is_expected.to be_nil }
its(:swift_account_number) { is_expected.to eq("00000009308127392") }
its(:iban) { is_expected.to eq("SE2130000000009308127392") }
its(:pseudo_iban) { is_expected.to be_nil }
its(:to_s) { is_expected.to eq("SE2130000000009308127392") }
its(:valid?) { is_expected.to eq(true) }
end

context "where the person was born in the 2000s" do
let(:arg) { "SE9430000000000607274287" }

its(:country_code) { is_expected.to eq("SE") }
its(:bank_code) { is_expected.to be_nil }
its(:branch_code) { is_expected.to be_nil }
its(:account_number) { is_expected.to be_nil }
its(:swift_bank_code) { is_expected.to eq("300") }
its(:swift_branch_code) { is_expected.to be_nil }
its(:swift_account_number) { is_expected.to eq("00000000607274287") }
its(:iban) { is_expected.to eq("SE9430000000000607274287") }
its(:pseudo_iban) { is_expected.to be_nil }
its(:to_s) { is_expected.to eq("SE9430000000000607274287") }
its(:valid?) { is_expected.to eq(true) }
end

context "where the person was born in the year 2000" do
let(:arg) { "SE3830000000000007134937" }

its(:country_code) { is_expected.to eq("SE") }
its(:bank_code) { is_expected.to be_nil }
its(:branch_code) { is_expected.to be_nil }
its(:account_number) { is_expected.to be_nil }
its(:swift_bank_code) { is_expected.to eq("300") }
its(:swift_branch_code) { is_expected.to be_nil }
its(:swift_account_number) { is_expected.to eq("00000000007134937") }
its(:iban) { is_expected.to eq("SE3830000000000007134937") }
its(:pseudo_iban) { is_expected.to be_nil }
its(:to_s) { is_expected.to eq("SE3830000000000007134937") }
its(:valid?) { is_expected.to eq(true) }
end
end
end

context "when the IBAN was created with local details for Australia" do
let(:arg) do
{
Expand Down

0 comments on commit 38e2405

Please sign in to comment.