bank_account_tools 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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