bank_account_tools 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/data/iban.yml ADDED
@@ -0,0 +1,550 @@
1
+ # http://en.wikipedia.org/wiki/International_Bank_Account_Number#IBAN_formats_by_country
2
+ # http://www.swift.com/dsp/resources/documents/IBAN_Registry.pdf
3
+ # https://bank.codes/iban/structure/
4
+
5
+ al: # Albania
6
+ length: 28
7
+ regexp: >
8
+ (?<bank_identifier> \d{8})
9
+ (?<account_number> [A-Z0-9]{16})
10
+
11
+ ad: # Andorra
12
+ length: 24
13
+ regexp: >
14
+ (?<bank_identifier> \d{4})
15
+ (?<branch_identifier> \d{4})
16
+ (?<account_number> [A-Z0-9]{12})
17
+
18
+ at: # Austria
19
+ length: 20
20
+ regexp: >
21
+ (?<bank_identifier> \d{5})
22
+ (?<account_number> \d{11})
23
+
24
+ az: # Azerbaijan
25
+ length: 28
26
+ regexp: >
27
+ (?<bank_identifier> [A-Z0-9]{4})
28
+ (?<account_number> \d{20})
29
+
30
+ bh: # Bahrain
31
+ length: 22
32
+ regexp: >
33
+ (?<bank_identifier> [A-Z]{4})
34
+ (?<account_number> [A-Z0-9]{14})
35
+
36
+ be: # Belgium
37
+ length: 16
38
+ regexp: >
39
+ (?<bank_identifier> \d{3})
40
+ (?<account_number> \d{7})
41
+ (?<national_check_digits> \d{2})
42
+
43
+ ba: # Bosnia and Herzegovina
44
+ length: 20
45
+ regexp: >
46
+ (?<bank_identifier> \d{3})
47
+ (?<branch_identifier> \d{3})
48
+ (?<account_number> \d{8})
49
+ (?<national_check_digits> \d{2})
50
+
51
+ br: # Brazil
52
+ length: 29
53
+ regexp: >
54
+ (?<bank_identifier> \d{8})
55
+ (?<branch_identifier> \d{5})
56
+ (?<account_number> \d{10})
57
+ (?<account_type> [A-Z])
58
+ (?<account_owner> [A-Z0-9])
59
+
60
+ bg: # Bulgaria
61
+ length: 22
62
+ regexp: >
63
+ (?<bank_identifier> [A-Z]{4})
64
+ (?<branch_identifier> \d{4})
65
+ (?<account_type> \d{2})
66
+ (?<account_number> [A-Z0-9]{8})
67
+
68
+ cr: # Costa Rica
69
+ length: 21
70
+ regexp: >
71
+ (?<bank_identifier> \d{3})
72
+ (?<account_number> \d{14})
73
+
74
+ hr: # Croatia
75
+ length: 21
76
+ regexp: >
77
+ (?<bank_identifier> \d{7})
78
+ (?<account_number> \d{10})
79
+
80
+ cy: # Cyprus
81
+ length: 28
82
+ regexp: >
83
+ (?<bank_identifier> \d{3})
84
+ (?<branch_identifier> \d{5})
85
+ (?<account_number> [A-Z0-9]{16})
86
+
87
+ cz: # Czech Republic
88
+ length: 24
89
+ regexp: >
90
+ (?<bank_identifier> \d{4})
91
+ (?<account_number> \d{6}\d{10})
92
+
93
+ de: # Germany
94
+ length: 22
95
+ regexp: >
96
+ (?<bank_identifier> \d{8})
97
+ (?<account_number> \d{10})
98
+
99
+ dk: # Denmark
100
+ length: 18
101
+ regexp: >
102
+ (?<bank_identifier> \d{4})
103
+ (?<account_number> \d{9})
104
+ (?<national_check_digits> \d{1})
105
+
106
+ gl: # Greenland (same as Denmark)
107
+ length: 18
108
+ regexp: >
109
+ (?<bank_identifier> \d{4})
110
+ (?<account_number> \d{9})
111
+ (?<national_check_digits> \d{1})
112
+
113
+ fo: # Faroe Islands (same as Denmark)
114
+ length: 18
115
+ regexp: >
116
+ (?<bank_identifier> \d{4})
117
+ (?<account_number> \d{9})
118
+ (?<national_check_digits> \d{1})
119
+
120
+ do: # Dominican Republic
121
+ length: 28
122
+ regexp: >
123
+ (?<bank_identifier> [A-Z]{4})
124
+ (?<account_number> \d{20})
125
+
126
+ ee: # Estonia
127
+ length: 20
128
+ regexp: >
129
+ (?<bank_identifier> \d{2})
130
+ (?<branch_identifier> \d{2})
131
+ (?<account_number> \d{11})
132
+ (?<national_check_digits> \d{1})
133
+
134
+ fi: # Finland
135
+ length: 18
136
+ regexp: >
137
+ (?<bank_identifier> \d{6})
138
+ (?<account_number> \d{7})
139
+ (?<national_check_digits> \d{1})
140
+
141
+ fr: # France
142
+ length: 27
143
+ regexp: >
144
+ (?<bank_identifier> \d{5})
145
+ (?<branch_identifier> \d{5})
146
+ (?<account_number> [A-Z0-9]{11})
147
+ (?<national_check_digits> \d{2})
148
+
149
+ ge: # Georgia
150
+ length: 22
151
+ regexp: >
152
+ (?<bank_identifier> [A-Z]{2})
153
+ (?<account_number> \d{16})
154
+
155
+ gi: # Gibraltar
156
+ length: 23
157
+ regexp: >
158
+ (?<bank_identifier> [A-Z]{4})
159
+ (?<account_number> [A-Z0-9]{15})
160
+
161
+ gr: # Greece
162
+ length: 27
163
+ regexp: >
164
+ (?<bank_identifier> \d{4})
165
+ (?<branch_identifier> \d{3})
166
+ (?<account_number> [A-Z0-9]{16})
167
+
168
+ gt: # Guatemala
169
+ length: 28
170
+ regexp: >
171
+ (?<bank_identifier> [A-Z0-9]{4})
172
+ (?<account_number> [A-Z0-9]{20})
173
+
174
+ hu: # Hungary
175
+ length: 28
176
+ regexp: >
177
+ (?<bank_identifier> \d{3})
178
+ (?<branch_identifier> \d{4})
179
+ (?<account_number> \d{1}\d{15})
180
+ (?<national_check_digits> \d{1})
181
+
182
+ is: # Iceland
183
+ length: 26
184
+ regexp: >
185
+ (?<bank_identifier> \d{4})
186
+ (?<branch_identifier> \d{2})
187
+ (?<account_number> \d{6}\d{10})
188
+
189
+ ie: # Ireland
190
+ length: 22
191
+ regexp: >
192
+ (?<bank_identifier> [A-Z0-9]{4})
193
+ (?<branch_identifier> \d{6})
194
+ (?<account_number> \d{8})
195
+
196
+ il: # Israel
197
+ length: 23
198
+ regexp: >
199
+ (?<bank_identifier> \d{3})
200
+ (?<branch_identifier> \d{3})
201
+ (?<account_number> \d{13})
202
+
203
+ it: # Italy
204
+ length: 27
205
+ regexp: >
206
+ (?<national_check_digits> [A-Z])
207
+ (?<bank_identifier> \d{5})
208
+ (?<branch_identifier> \d{5})
209
+ (?<account_number> [A-Z0-9]{12})
210
+
211
+ kz: # Kazakhstan
212
+ length: 20
213
+ regexp: >
214
+ (?<bank_identifier> \d{3})
215
+ (?<account_number> [A-Z0-9]{13})
216
+
217
+ xk: # Republic of Kosovo
218
+ length: 20
219
+ regexp: >
220
+ (?<bank_identifier> \d{4})
221
+ (?<account_number> \d{12})
222
+
223
+ kw: # Kuwait
224
+ length: 30
225
+ regexp: >
226
+ (?<bank_identifier> [A-Z]{4})
227
+ (?<account_number> [A-Z0-9]{22})
228
+
229
+ lv: # Latvia
230
+ length: 21
231
+ regexp: >
232
+ (?<bank_identifier> [A-Z]{4})
233
+ (?<account_number> [A-Z0-9]{13})
234
+
235
+ lb: # Lebanon
236
+ length: 28
237
+ regexp: >
238
+ (?<bank_identifier> \d{4})
239
+ (?<account_number> [A-Z0-9]{20})
240
+
241
+ li: # Liechtenstein
242
+ length: 21
243
+ regexp: >
244
+ (?<bank_identifier> \d{5})
245
+ (?<account_number> [A-Z0-9]{12})
246
+
247
+ lt: # Lithuania
248
+ length: 20
249
+ regexp: >
250
+ (?<bank_identifier> \d{5})
251
+ (?<account_number> \d{11})
252
+
253
+ lu: # Luxembourg
254
+ length: 20
255
+ regexp: >
256
+ (?<bank_identifier> \d{3})
257
+ (?<account_number> [A-Z0-9]{13})
258
+
259
+ mk: # Macedonia
260
+ length: 19
261
+ regexp: >
262
+ (?<branch_identifier> \d{3})
263
+ (?<account_number> [A-Z0-9]{10})
264
+ (?<national_check_digits> \d{2})
265
+
266
+ mt: # Malta
267
+ length: 31
268
+ regexp: >
269
+ (?<bank_identifier> [A-Z]{4})
270
+ (?<branch_identifier> \d{5})
271
+ (?<account_number> [A-Z0-9]{18})
272
+
273
+ mr: # Mauritania
274
+ length: 27
275
+ regexp: >
276
+ (?<bank_identifier> \d{5})
277
+ (?<branch_identifier> \d{5})
278
+ (?<account_number> \d{11})
279
+ (?<national_check_digits> \d{2})
280
+
281
+ mu: # Mauritius
282
+ length: 30
283
+ regexp: >
284
+ (?<bank_identifier> [A-Z]{4}\d{2})
285
+ (?<branch_identifier> \d{2})
286
+ (?<account_number> \d{12}\d{3}[A-Z]{3})
287
+
288
+ mc: # Monaco
289
+ length: 27
290
+ regexp: >
291
+ (?<bank_identifier> \d{5})
292
+ (?<branch_identifier> \d{5})
293
+ (?<account_number> [A-Z0-9]{11})
294
+ (?<national_check_digits> \d{2})
295
+
296
+ md: # Moldova
297
+ length: 24
298
+ regexp: >
299
+ (?<bank_identifier> [A-Z0-9]{2})
300
+ (?<account_number> \d{18})
301
+
302
+ me: # Montenegro
303
+ length: 22
304
+ regexp: >
305
+ (?<bank_identifier> \d{3})
306
+ (?<account_number> (\d{13})(\d{2}))
307
+
308
+ nl: # Netherlands
309
+ length: 18
310
+ regexp: >
311
+ (?<bank_identifier> [A-Z]{4})
312
+ (?<account_number> \d{10})
313
+
314
+ 'no': # Norway
315
+ length: 15
316
+ regexp: >
317
+ (?<bank_identifier> \d{4})
318
+ (?<account_number> (\d{6})(\d{1}))
319
+
320
+ pk: # Pakistan
321
+ length: 24
322
+ regexp: >
323
+ (?<bank_identifier> [A-Z0-9]{4})
324
+ (?<account_number> \d{16})
325
+
326
+ ps: # Palestine
327
+ length: 29
328
+ regexp: >
329
+ (?<bank_identifier> [A-Z0-9]{4})
330
+ (?<account_number> \d{21})
331
+
332
+ pl: # Poland
333
+ length: 28
334
+ regexp: >
335
+ (?<bank_identifier> \d{8})
336
+ (?<account_number> \d{16})
337
+
338
+ pt: # Portugal
339
+ length: 25
340
+ regexp: >
341
+ (?<bank_identifier> \d{4})
342
+ (?<branch_identifier> \d{4})
343
+ (?<account_number> \d{11})
344
+ (?<national_check_digits> \d{2})
345
+
346
+ ro: # Romania
347
+ length: 24
348
+ regexp: >
349
+ (?<bank_identifier> [A-Z]{4})
350
+ (?<account_number> [A-Z0-9]{16})
351
+
352
+ sm: # San Marino
353
+ length: 27
354
+ regexp: >
355
+ (?<national_check_digits> [A-Z])
356
+ (?<bank_identifier> \d{5})
357
+ (?<branch_identifier> \d{5})
358
+ (?<account_number> [A-Z0-9]{12})
359
+
360
+ sa: # Saudi Arabia
361
+ length: 24
362
+ regexp: >
363
+ (?<bank_identifier> \d{2})
364
+ (?<account_number> [A-Z0-9]{18})
365
+
366
+ rs: # Serbia
367
+ length: 22
368
+ regexp: >
369
+ (?<bank_identifier> \d{3})
370
+ (?<account_number> \d{13})
371
+ (?<national_check_digits> \d{2})
372
+
373
+ sk: # Slovak Republic
374
+ length: 24
375
+ regexp: >
376
+ (?<bank_identifier> \d{4})
377
+ (?<branch_identifier> \d{6})
378
+ (?<account_number> \d{10})
379
+
380
+ si: # Slovenia
381
+ length: 19
382
+ regexp: >
383
+ (?<bank_identifier> \d{5})
384
+ (?<account_number> \d{8})
385
+ (?<national_check_digits> \d{2})
386
+
387
+ es: # Spain
388
+ length: 24
389
+ regexp: >
390
+ (?<bank_identifier> \d{4})
391
+ (?<branch_identifier> \d{4})
392
+ (?<national_check_digits> \d{1}\d{1})
393
+ (?<account_number> \d{10})
394
+
395
+ se: # Sweden
396
+ length: 24
397
+ regexp: >
398
+ (?<bank_identifier> \d{3})
399
+ (?<account_number> \d{16}\d{1})
400
+
401
+ ch: # Switzerland
402
+ length: 21
403
+ regexp: >
404
+ (?<bank_identifier> \d{5})
405
+ (?<account_number> [A-Z0-9]{12})
406
+
407
+ tn: # Tunisia
408
+ length: 24
409
+ regexp: >
410
+ (?<bank_identifier> \d{2})
411
+ (?<branch_identifier> \d{3})
412
+ (?<account_number> \d{13}\d{2})
413
+
414
+ tr: # Turkey
415
+ length: 26
416
+ regexp: >
417
+ (?<bank_identifier> \d{5})([A-Z0-9])
418
+ (?<account_number> [A-Z0-9]{16})
419
+
420
+ ae: # United Arab Emirates
421
+ length: 23
422
+ regexp: >
423
+ (?<bank_identifier> \d{3})
424
+ (?<account_number> \d{16})
425
+
426
+ gb: # United Kingdom
427
+ length: 22
428
+ regexp: >
429
+ (?<bank_identifier> [A-Z]{4})
430
+ (?<branch_identifier> \d{6})
431
+ (?<account_number> \d{8})
432
+
433
+ vg: # Virgin Islands, British
434
+ length: 24
435
+ regexp: >
436
+ (?<bank_identifier> [A-Z0-9]{4})
437
+ (?<account_number> \d{16})
438
+
439
+ # In addition to the above list, Nordea has catalogued IBANs for countries listed below.[32]
440
+
441
+ ua: # Ukraine
442
+ length: 29
443
+ regexp: >
444
+ (?<bank_identifier> [0-9]{6})
445
+ (?<account_number> \d{19})
446
+
447
+
448
+ ao: # Angola
449
+ length: 25
450
+ regexp: '\d{21}'
451
+
452
+ bj: # Benin
453
+ length: 28
454
+ regexp: '[A-Z]\d{23}'
455
+
456
+ bf: # Burkina Faso
457
+ length: 27
458
+ regexp: '\d{23}'
459
+
460
+ bi: # Burundi
461
+ length: 16
462
+ regexp: '\d{12}'
463
+
464
+ cm: # Cameroon
465
+ length: 27
466
+ regexp: '\d{23}'
467
+
468
+ cv: # Cape Verde
469
+ length: 25
470
+ regexp: '\d{21}'
471
+
472
+ ir: # Iran
473
+ length: 26
474
+ regexp: '\d{22}'
475
+
476
+ ci: # Ivory Coast
477
+ length: 28
478
+ regexp: '[A-Z]\d{23}'
479
+
480
+ mg: # Madagascar
481
+ length: 27
482
+ regexp: '\d{23}'
483
+
484
+ ml: # Mali
485
+ length: 28
486
+ regexp: '[A-Z]\d{23}'
487
+
488
+ mz: # Mozambique
489
+ length: 25
490
+ regexp: '\d{21}'
491
+
492
+ sn: # Senegal
493
+ length: 28
494
+ regexp: '[A-Z]\d{23}'
495
+
496
+ cg: # Republic Congo
497
+ length: 27
498
+ regexp: '\d{23}'
499
+
500
+ dz: # Algeria
501
+ length: 24
502
+ regexp: '\d{20}'
503
+
504
+ eg: # Egypt
505
+ length: 27
506
+ regexp: '\d{23}'
507
+
508
+ ga: # Gabon
509
+ length: 27
510
+ regexp: '\d{23}'
511
+
512
+ jo: # Jordan https://bank.codes/iban/structure/jordan/
513
+ length: 30
514
+ regexp: >
515
+ (?<bank_identifier> [A-Z]{4})
516
+ (?<branch_identifier> \d{4})
517
+ (?<account_number> [A-Z0-9]{18})
518
+
519
+ qa: # Qatar https://bank.codes/iban/structure/qatar/
520
+ length: 29
521
+ regexp: >
522
+ (?<bank_identifier> [A-Z]{4})
523
+ (?<account_number> [A-Z0-9]{21})
524
+
525
+ tl: # Timor Leste https://bank.codes/iban/structure/timor-leste/
526
+ length: 23
527
+ regexp: >
528
+ (?<bank_identifier> \d{3})
529
+ (?<account_number> \d{16})
530
+
531
+ sc: #Seychelles https://bank.codes/iban/structure/seychelles/
532
+ length: 31
533
+ regexp: >
534
+ (?<bank_identifier> [A-Z]{4})
535
+ (?<branch_identifier> \d{4})
536
+ (?<account_number> \d{16})
537
+ (?<currency> [A-Z]{3})
538
+
539
+ st: #Sao Tome and Principe https://bank.codes/iban/structure/sao-tome-and-principe/
540
+ length: 25
541
+ regexp: >
542
+ (?<bank_identifier> \d{4})
543
+ (?<branch_identifier> \d{4})
544
+ (?<account_number> \d{13})
545
+
546
+ lc: #Saint Lucia https://bank.codes/iban/structure/saint-lucia/
547
+ length: 32
548
+ regexp: >
549
+ (?<bank_identifier> [A-Z]{4})
550
+ (?<account_number> \d{24})
@@ -0,0 +1,44 @@
1
+ require 'bank_account_tools'
2
+
3
+ module BankAccountTools
4
+ class BBAN # Basic Bank Account Number
5
+ def initialize(country_code, code)
6
+ @country_code, @code = country_code, code
7
+ end
8
+
9
+ def to_s
10
+ @code
11
+ end
12
+
13
+ def valid?
14
+ valid_length? && !data.nil?
15
+ end
16
+
17
+ # the bban is the iban minus the first 4 characters (country_code, check_digits)
18
+ def valid_length?
19
+ specification && specification['length'] - 4 == @code.length
20
+ end
21
+
22
+ [:account_number, :bank_identifier, :branch_identifier].each do |m|
23
+ define_method(m) { data && data[m] }
24
+ end
25
+
26
+ def country_applies_iban?
27
+ !!specification
28
+ end
29
+
30
+ private
31
+
32
+ def data
33
+ @code.match(/^#{specification['regexp']}$/x) if specification
34
+ end
35
+
36
+ def specification
37
+ @specification ||= self.class.specifications[@country_code.downcase]
38
+ end
39
+
40
+ def self.specifications
41
+ @@specs ||= BankAccountTools.load_specifications(:iban)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,67 @@
1
+ require 'bank_account_tools/validators/bic_validator' if defined? ActiveModel
2
+
3
+ module BankAccountTools
4
+ class BIC
5
+ REGEX = /^([A-Z]{4})([A-Z]{2})([A-Z0-9]{2})([A-Z0-9]{3})?$/.freeze
6
+
7
+ def self.valid?(code)
8
+ new(code).valid?
9
+ end
10
+
11
+ def initialize(code)
12
+ @code = code.to_s.gsub(/\s+/, '').upcase
13
+ end
14
+
15
+ def bank_code
16
+ @code[0..3]
17
+ end
18
+
19
+ def country_code
20
+ @code[4..5]
21
+ end
22
+
23
+ def location_code
24
+ @code[6..7]
25
+ end
26
+
27
+ def branch_code
28
+ @code[8..10]
29
+ end
30
+
31
+ def to_s(formatted=false)
32
+ formatted ? to_formatted_str : @code
33
+ end
34
+
35
+ def to_formatted_str
36
+ "#{bank_code} #{country_code} #{location_code} #{branch_code}".strip
37
+ end
38
+
39
+ def test?
40
+ location_code[1] == '0'
41
+ end
42
+
43
+ def passive?
44
+ location_code[1] == '1'
45
+ end
46
+
47
+ def reverse_billing?
48
+ location_code[1] == '2'
49
+ end
50
+
51
+ def valid?
52
+ valid_format? && valid_location_code? && valid_branch_code?
53
+ end
54
+
55
+ def valid_format?
56
+ !!@code[REGEX]
57
+ end
58
+
59
+ def valid_location_code?
60
+ !location_code.start_with?('0', '1') && !location_code.end_with?('O')
61
+ end
62
+
63
+ def valid_branch_code?
64
+ branch_code.empty? || branch_code == 'XXX' || !branch_code.start_with?('X')
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,33 @@
1
+ require 'bank_account_tools/iban'
2
+ require 'bank_account_tools/bic'
3
+
4
+ module BankAccountTools
5
+ class Contact
6
+ attr_reader :iban, :bic
7
+
8
+ def initialize(iban, bic)
9
+ self.iban = iban
10
+ self.bic = bic
11
+ end
12
+
13
+ def iban=(value)
14
+ @iban = IBAN.new(value)
15
+ end
16
+
17
+ def bic=(value)
18
+ @bic = BIC.new(value)
19
+ end
20
+
21
+ def valid?
22
+ iban.valid? && bic.valid?
23
+ end
24
+
25
+ def to_h
26
+ { iban: iban.to_s, bic: bic.to_s }
27
+ end
28
+
29
+ def to_a
30
+ to_h.values
31
+ end
32
+ end
33
+ end