creditcard-identifier 2.0.0 → 2.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2971d1554919d8eaf0fd916f87d9003cee3aae39d07e0b6f6de388d19eff31f1
4
- data.tar.gz: c51129f59758f48b10b24f1e7f7f2d6ee336b62aa8e91fceed7ead69d1005fcb
3
+ metadata.gz: 1ae87b47647670786be04ec29dbb4257da90c3264e1fdb5cb57df74cd6dc8c2b
4
+ data.tar.gz: 6d209a5a775ea4e95f9dce3daa5b9a190fa79904e72aae23532438e42b0c3a6c
5
5
  SHA512:
6
- metadata.gz: 0b831eb2196ceab513b4b2e77907abd454d14cfb13052dc0e14eea01ad964bfff247f13fdfb382bb0f9bb210c0409721853f02e414a6c05cf6dea8c87c030df0
7
- data.tar.gz: 10f73f531f751c2f48f347daed4b1d2f726cd19495ae579d4a80b6d40e5b4ea6a2f8b694f17f80d6d46bb8327a1530a936743e86382b5453d92de98ab3559e6e
6
+ metadata.gz: 613ec2e5e2e481e1fabb607c8f27b520ed0ab1d8fb8aa55cdf45c7069e1654afc22599a4bcf1db125db888daa8352277db00ecb92bb6765f8b9499b25cca013e
7
+ data.tar.gz: 8a60d7b35b49a581f47a514ca12f04436206d132d2dd9c315f1a6f204d7c345556e4a077d621b8a0e00c8476a7de7b4448e6f3c65267770f72e30cbe3339fe45
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Renato Augusto Viço Elias
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,6 +1,21 @@
1
1
  # Credit Card Identifier - Ruby Library
2
2
 
3
- Ruby library for credit card BIN validation using bin-cc data.
3
+ Ruby library for credit card BIN validation and identification.
4
+
5
+ ## Supported Card Brands
6
+
7
+ - American Express (amex)
8
+ - Aura
9
+ - BaneseCard
10
+ - Diners Club
11
+ - Discover
12
+ - Elo
13
+ - Hipercard
14
+ - JCB
15
+ - Maestro
16
+ - Mastercard
17
+ - UnionPay
18
+ - Visa
4
19
 
5
20
  ## Installation
6
21
 
@@ -31,7 +46,7 @@ require 'creditcard_identifier'
31
46
 
32
47
  # Identify card brand
33
48
  brand = CreditcardIdentifier.find_brand('4012001037141112')
34
- puts brand # 'visa'
49
+ puts brand[:name] # 'visa'
35
50
 
36
51
  # Check if card is supported
37
52
  supported = CreditcardIdentifier.supported?('4012001037141112')
@@ -47,7 +62,12 @@ validator = CreditcardIdentifier::Validator.new
47
62
 
48
63
  # Identify brand
49
64
  brand = validator.find_brand('4012001037141112')
50
- puts brand # 'visa'
65
+ puts brand[:name] # 'visa'
66
+
67
+ # Get detailed brand info
68
+ detailed = validator.find_brand('4012001037141112', detailed: true)
69
+ puts detailed[:scheme] # 'visa'
70
+ puts detailed[:matched_pattern] # { bin: '^4', length: [13, 16, 19], ... }
51
71
 
52
72
  # Check if supported
53
73
  supported = validator.supported?('4012001037141112')
@@ -59,11 +79,24 @@ puts valid # true
59
79
 
60
80
  # Get brand info
61
81
  info = validator.get_brand_info('visa')
62
- puts info['regexpBin']
82
+ puts info[:regexp_bin]
83
+
84
+ # Get detailed brand info
85
+ detailed = validator.get_brand_info_detailed('amex')
86
+ puts detailed
63
87
 
64
88
  # List all brands
65
89
  brands = validator.list_brands
66
- puts brands # ['elo', 'diners', 'visa', ...]
90
+ puts brands
91
+ # ['amex', 'aura', 'banesecard', 'diners', 'discover', 'elo', 'hipercard', 'jcb', 'maestro', 'mastercard', 'unionpay', 'visa']
92
+
93
+ # Validate card number using Luhn algorithm
94
+ is_valid = CreditcardIdentifier.luhn('4012001037141112')
95
+ puts is_valid # true
96
+
97
+ # Or using validator instance
98
+ is_valid = validator.luhn('4012001037141112')
99
+ puts is_valid # true
67
100
  ```
68
101
 
69
102
  ## API
@@ -76,7 +109,7 @@ Identify the credit card brand.
76
109
  **Parameters:**
77
110
  - `card_number` (String): The credit card number
78
111
 
79
- **Returns:** (String, nil) Brand name (e.g., 'visa', 'mastercard') or nil if not found
112
+ **Returns:** (Hash, nil) Brand hash or nil if not found
80
113
 
81
114
  #### `CreditcardIdentifier.supported?(card_number)`
82
115
  Check if the card number is supported.
@@ -88,19 +121,17 @@ Check if the card number is supported.
88
121
 
89
122
  ### Validator Class
90
123
 
91
- #### `initialize(data_path = nil)`
92
- Initialize validator with brand data.
124
+ #### `initialize`
125
+ Initialize validator with embedded brand data.
93
126
 
94
- **Parameters:**
95
- - `data_path` (String, nil): Path to brands.json. If nil, uses bundled data.
96
-
97
- #### `find_brand(card_number)`
127
+ #### `find_brand(card_number, detailed: false)`
98
128
  Identify the credit card brand.
99
129
 
100
130
  **Parameters:**
101
131
  - `card_number` (String): The credit card number
132
+ - `detailed` (Boolean): If true, returns detailed brand info with matched pattern
102
133
 
103
- **Returns:** (String, nil) Brand name or nil if not found
134
+ **Returns:** (Hash, nil) Brand hash or nil if not found
104
135
 
105
136
  #### `supported?(card_number)`
106
137
  Check if card number is supported.
@@ -110,12 +141,12 @@ Check if card number is supported.
110
141
 
111
142
  **Returns:** (Boolean) true if supported, false otherwise
112
143
 
113
- #### `validate_cvv(cvv, brand_name)`
144
+ #### `validate_cvv(cvv, brand_or_name)`
114
145
  Validate CVV for a specific brand.
115
146
 
116
147
  **Parameters:**
117
148
  - `cvv` (String): CVV code
118
- - `brand_name` (String): Brand name (e.g., 'visa', 'mastercard')
149
+ - `brand_or_name` (String | Hash): Brand name or brand hash from find_brand
119
150
 
120
151
  **Returns:** (Boolean) true if valid, false otherwise
121
152
 
@@ -127,16 +158,34 @@ Get information about a specific brand.
127
158
 
128
159
  **Returns:** (Hash, nil) Brand information or nil if not found
129
160
 
161
+ #### `get_brand_info_detailed(scheme)`
162
+ Get detailed information about a specific brand.
163
+
164
+ **Parameters:**
165
+ - `scheme` (String): Scheme name (e.g., 'visa', 'mastercard')
166
+
167
+ **Returns:** (Hash, nil) Detailed brand information or nil if not found
168
+
130
169
  #### `list_brands`
131
170
  List all supported brands.
132
171
 
133
172
  **Returns:** (Array<String>) List of brand names
134
173
 
174
+ #### `luhn(number)`
175
+ Validate a credit card number using the Luhn algorithm.
176
+
177
+ **Parameters:**
178
+ - `number` (String): Credit card number (digits only)
179
+
180
+ **Returns:** (Boolean) true if valid according to Luhn algorithm
181
+
182
+ **Raises:** TypeError if input is not a string
183
+
135
184
  ## Data Source
136
185
 
137
186
  This library uses the BIN data from the [bin-cc project](https://github.com/renatovico/bin-cc).
138
187
 
139
- The data is bundled with the gem, and can be updated by installing a newer version.
188
+ The data is embedded directly in the gem for optimal performance.
140
189
 
141
190
  ## Development
142
191
 
@@ -145,7 +194,7 @@ After checking out the repo, run `bundle install` to install dependencies.
145
194
  Run tests with:
146
195
 
147
196
  ```bash
148
- ruby test/test_validator.rb
197
+ bundle exec ruby test/test_validator.rb
149
198
  ```
150
199
 
151
200
  ## License
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Auto-generated by bin-cc build - DO NOT EDIT
4
- # Generated: 2026-01-11T20:12:36.612Z
4
+ # Generated: 2026-01-11T21:09:29.401Z
5
5
 
6
6
  module CreditcardIdentifier
7
7
  # Credit card brand data
@@ -43,7 +43,7 @@ module CreditcardIdentifier
43
43
  },
44
44
  {
45
45
  name: "aura",
46
- priority_over: [],
46
+ priority_over: ["maestro"],
47
47
  regexp_bin: /\A(50)/,
48
48
  regexp_full: /\A(?=.{16,19}$)(?:50)[0-9]*\z/,
49
49
  regexp_cvv: /\A\d{3}\z/,
@@ -55,6 +55,13 @@ module CreditcardIdentifier
55
55
  regexp_full: /\A(?=.{16}$)(?:636117|637473|637470|637472|650725|650046|650591|651668|651679)[0-9]*\z/,
56
56
  regexp_cvv: /\A\d{3}\z/,
57
57
  },
58
+ {
59
+ name: "maestro",
60
+ priority_over: [],
61
+ regexp_bin: /\A(5018|5020|5038|5893|6304|6759|676[1-3]|6706)/,
62
+ regexp_full: /\A(?=.{12,19}$)(?:5018|5020|5038|5893|6304|6759|676[1-3]|6706)[0-9]*\z/,
63
+ regexp_cvv: /\A\d{3}\z/,
64
+ },
58
65
  {
59
66
  name: "visa",
60
67
  priority_over: [],
@@ -64,10 +71,10 @@ module CreditcardIdentifier
64
71
  },
65
72
  {
66
73
  name: "discover",
67
- priority_over: ["hipercard"],
68
- regexp_bin: /\A(6011|622|64|65)/,
69
- regexp_full: /\A(?=.{16}$)(?:6011|622|64|65)[0-9]*\z/,
70
- regexp_cvv: /\A\d{4}\z/,
74
+ priority_over: ["hipercard", "unionpay"],
75
+ regexp_bin: /\A(6011|64[4-9]|65)/,
76
+ regexp_full: /\A(?=.{16,19}$)(?:6011|64[4-9]|65)[0-9]*\z/,
77
+ regexp_cvv: /\A\d{3}\z/,
71
78
  },
72
79
  {
73
80
  name: "hipercard",
@@ -76,5 +83,12 @@ module CreditcardIdentifier
76
83
  regexp_full: /\A(?=.{16,19}$)(?:38|60)[0-9]*\z/,
77
84
  regexp_cvv: /\A\d{3}\z/,
78
85
  },
86
+ {
87
+ name: "unionpay",
88
+ priority_over: [],
89
+ regexp_bin: /\A(62)/,
90
+ regexp_full: /\A(?=.{16,19}$)(?:62)[0-9]*\z/,
91
+ regexp_cvv: /\A\d{3}\z/,
92
+ },
79
93
  ].freeze
80
94
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Auto-generated by bin-cc build - DO NOT EDIT
4
- # Generated: 2026-01-11T20:12:36.612Z
4
+ # Generated: 2026-01-11T21:09:29.401Z
5
5
 
6
6
  module CreditcardIdentifier
7
7
  # Credit card brand data (detailed)
@@ -237,7 +237,7 @@ module CreditcardIdentifier
237
237
  ],
238
238
  countries: ["BR"],
239
239
  metadata: { "sourceFile" => "aura.json" },
240
- priority_over: [],
240
+ priority_over: ["maestro"],
241
241
  bins: []
242
242
  },
243
243
  {
@@ -312,6 +312,72 @@ module CreditcardIdentifier
312
312
  priority_over: ["discover"],
313
313
  bins: []
314
314
  },
315
+ {
316
+ scheme: "maestro",
317
+ brand: "Maestro",
318
+ type: "debit",
319
+ number: {
320
+ lengths: [12, 13, 14, 15, 16, 17, 18, 19],
321
+ luhn: true
322
+ },
323
+ cvv: {
324
+ length: 3
325
+ },
326
+ patterns: [
327
+ {
328
+ bin: "^5018",
329
+ length: [12, 13, 14, 15, 16, 17, 18, 19],
330
+ luhn: true,
331
+ cvv_length: 3
332
+ },
333
+ {
334
+ bin: "^5020",
335
+ length: [12, 13, 14, 15, 16, 17, 18, 19],
336
+ luhn: true,
337
+ cvv_length: 3
338
+ },
339
+ {
340
+ bin: "^5038",
341
+ length: [12, 13, 14, 15, 16, 17, 18, 19],
342
+ luhn: true,
343
+ cvv_length: 3
344
+ },
345
+ {
346
+ bin: "^5893",
347
+ length: [12, 13, 14, 15, 16, 17, 18, 19],
348
+ luhn: true,
349
+ cvv_length: 3
350
+ },
351
+ {
352
+ bin: "^6304",
353
+ length: [12, 13, 14, 15, 16, 17, 18, 19],
354
+ luhn: true,
355
+ cvv_length: 3
356
+ },
357
+ {
358
+ bin: "^6759",
359
+ length: [12, 13, 14, 15, 16, 17, 18, 19],
360
+ luhn: true,
361
+ cvv_length: 3
362
+ },
363
+ {
364
+ bin: "^676[1-3]",
365
+ length: [12, 13, 14, 15, 16, 17, 18, 19],
366
+ luhn: true,
367
+ cvv_length: 3
368
+ },
369
+ {
370
+ bin: "^6706",
371
+ length: [12, 13, 14, 15, 16, 17, 18, 19],
372
+ luhn: true,
373
+ cvv_length: 3
374
+ },
375
+ ],
376
+ countries: ["GLOBAL"],
377
+ metadata: { "sourceFile" => "maestro.json" },
378
+ priority_over: [],
379
+ bins: []
380
+ },
315
381
  {
316
382
  scheme: "visa",
317
383
  brand: "Visa",
@@ -453,41 +519,35 @@ module CreditcardIdentifier
453
519
  brand: "Discover",
454
520
  type: "credit",
455
521
  number: {
456
- lengths: [16],
522
+ lengths: [16, 19],
457
523
  luhn: true
458
524
  },
459
525
  cvv: {
460
- length: 4
526
+ length: 3
461
527
  },
462
528
  patterns: [
463
529
  {
464
530
  bin: "^6011",
465
- length: [16],
531
+ length: [16, 19],
466
532
  luhn: true,
467
- cvv_length: 4
468
- },
469
- {
470
- bin: "^622",
471
- length: [16],
472
- luhn: true,
473
- cvv_length: 4
533
+ cvv_length: 3
474
534
  },
475
535
  {
476
- bin: "^64",
477
- length: [16],
536
+ bin: "^64[4-9]",
537
+ length: [16, 19],
478
538
  luhn: true,
479
- cvv_length: 4
539
+ cvv_length: 3
480
540
  },
481
541
  {
482
542
  bin: "^65",
483
- length: [16],
543
+ length: [16, 19],
484
544
  luhn: true,
485
- cvv_length: 4
545
+ cvv_length: 3
486
546
  },
487
547
  ],
488
548
  countries: ["US"],
489
549
  metadata: { "sourceFile" => "discover.json" },
490
- priority_over: ["hipercard"],
550
+ priority_over: ["hipercard", "unionpay"],
491
551
  bins: []
492
552
  },
493
553
  {
@@ -520,5 +580,29 @@ module CreditcardIdentifier
520
580
  priority_over: [],
521
581
  bins: []
522
582
  },
583
+ {
584
+ scheme: "unionpay",
585
+ brand: "UnionPay",
586
+ type: "debit",
587
+ number: {
588
+ lengths: [16, 17, 18, 19],
589
+ luhn: true
590
+ },
591
+ cvv: {
592
+ length: 3
593
+ },
594
+ patterns: [
595
+ {
596
+ bin: "^62",
597
+ length: [16, 17, 18, 19],
598
+ luhn: true,
599
+ cvv_length: 3
600
+ },
601
+ ],
602
+ countries: ["CN", "GLOBAL"],
603
+ metadata: { "sourceFile" => "unionpay.json" },
604
+ priority_over: [],
605
+ bins: []
606
+ },
523
607
  ].freeze
524
608
  end
@@ -8,7 +8,34 @@ require_relative 'creditcard_identifier/brands_detailed'
8
8
  #
9
9
  # This module provides credit card validation using bin-cc data.
10
10
  module CreditcardIdentifier
11
- VERSION = '2.0.0'
11
+ VERSION = '2.1.0'
12
+
13
+ # Luhn lookup table for doubling digits
14
+ LUHN_LOOKUP = [0, 2, 4, 6, 8, 1, 3, 5, 7, 9].freeze
15
+
16
+ ##
17
+ # Validate a credit card number using the Luhn algorithm
18
+ #
19
+ # @param number [String] Credit card number (digits only)
20
+ # @return [Boolean] true if valid according to Luhn algorithm
21
+ # @raise [TypeError] if number is not a string
22
+ def self.luhn(number)
23
+ raise TypeError, 'Expected string input' unless number.is_a?(String)
24
+ return false if number.empty?
25
+
26
+ total = 0
27
+ x2 = true
28
+
29
+ (number.length - 1).downto(0) do |i|
30
+ value = number[i].ord - 48
31
+ return false if value < 0 || value > 9
32
+
33
+ x2 = !x2
34
+ total += x2 ? LUHN_LOOKUP[value] : value
35
+ end
36
+
37
+ (total % 10).zero?
38
+ end
12
39
 
13
40
  ##
14
41
  # Credit card validator using bin-cc data.
@@ -132,6 +159,15 @@ module CreditcardIdentifier
132
159
  def list_brands
133
160
  @brands.map { |b| b[:name] }
134
161
  end
162
+
163
+ ##
164
+ # Validate a credit card number using the Luhn algorithm
165
+ #
166
+ # @param number [String] Credit card number (digits only)
167
+ # @return [Boolean] true if valid according to Luhn algorithm
168
+ def luhn(number)
169
+ CreditcardIdentifier.luhn(number)
170
+ end
135
171
  end
136
172
 
137
173
  # Module-level convenience methods
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: creditcard-identifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Renato Viço
@@ -44,6 +44,7 @@ executables: []
44
44
  extensions: []
45
45
  extra_rdoc_files: []
46
46
  files:
47
+ - LICENSE
47
48
  - README.md
48
49
  - lib/creditcard_identifier.rb
49
50
  - lib/creditcard_identifier/brands.rb