credit_card_validations 1.5.1 → 2.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.
@@ -0,0 +1,66 @@
1
+ # == CreditCardValidations Factory
2
+ # Generates card number that passes validation
3
+ #
4
+ # #random
5
+ # CreditCardValidations::Factory.random
6
+ # #or particular brand
7
+ # CreditCardValidations::Factory.random(:maestro) # "6010430241237266856"
8
+ #
9
+ #
10
+ #
11
+ module CreditCardValidations
12
+ class Factory
13
+ class << self
14
+ def random(brand = nil)
15
+ if brand.nil?
16
+ brand = Detector.brands.keys.sample
17
+ else
18
+ raise RuntimeError.new("Unsupported brand") if Detector.brands[brand].nil?
19
+ end
20
+ generate(Detector.brands[brand][:rules].sample)
21
+
22
+ end
23
+
24
+ def generate(rule)
25
+ number(rule[:prefixes].sample, rule[:length].sample, rule.fetch(:options, {})[:skip_luhn])
26
+ end
27
+
28
+ def number(prefix, length, skip_luhn = false)
29
+ number = prefix.dup
30
+ 1.upto(length - (prefix.length + 1)) do
31
+ number << "#{rand(9)}"
32
+ end
33
+ #if skip luhn
34
+ if skip_luhn
35
+ number += "#{rand(9)}"
36
+ else
37
+ number += last_digit(number).to_s
38
+ end
39
+ number
40
+ end
41
+
42
+ #extracted from darkcoding-credit-card
43
+
44
+ def last_digit(number)
45
+ # Calculate sum
46
+ sum, pos = 0, 0
47
+ length = number.length + 1
48
+
49
+ reversed_number = number.reverse
50
+ while pos < length do
51
+ odd = reversed_number[pos].to_i * 2
52
+ odd -= 9 if odd > 9
53
+
54
+ sum += odd
55
+
56
+ sum += reversed_number[pos + 1].to_i if pos != (length - 2)
57
+
58
+ pos += 2
59
+ end
60
+
61
+ (((sum / 10).floor + 1) * 10 - sum) % 10
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -1,3 +1,8 @@
1
+ # == CreditCardValidations Luhn
2
+ # simple class to validate Luhn numbers.
3
+ #
4
+ # Luhn.valid? 4111111111111111
5
+ #
1
6
  module CreditCardValidations
2
7
  class Luhn
3
8
  def self.valid?(number)
@@ -1,17 +1,22 @@
1
- #Major Industry Identifier (MII)
1
+ # == CreditCardValidations Mmi
2
2
  #
3
- #The first digit of a credit card number is the Major Industry Identifier (MII), which represents the category of entity which issued the card. MII digits represent the following issuer categories:
4
- #0 – ISO/TC 68 and other future industry assignments
5
- #1 Airlines
6
- #2Airlines and other future industry assignments
7
- #3Travel and entertainment and banking/financial
8
- #4Banking and financial
9
- #5Banking and financial
10
- #6Merchandising and banking/financial
11
- #7Petroleum and other future industry assignments
12
- #8Healthcare, telecommunications and other future industry assignments
13
- #9National assignment
14
- #For example, American Express, Diner's Club, Carte Blanche, and JCB are in the travel and entertainment category; VISA, MasterCard, and Discover are in the banking and financial category (Discover being in the Merchandising and banking/financial category); and Sun Oil and Exxon are in the petroleum category.
3
+ # Implements Major Industry Identifier (MII) detection
4
+ #
5
+ # The first digit of a credit card number is the Major Industry Identifier (MII), which represents the category of entity which issued the card. MII digits represent the following issuer categories:
6
+ # 0 ISO/TC 68 and other future industry assignments
7
+ # 1 Airlines
8
+ # 2 Airlines and other future industry assignments
9
+ # 3 Travel and entertainment and banking/financial
10
+ # 4 Banking and financial
11
+ # 5 Banking and financial
12
+ # 6 Merchandising and banking/financial
13
+ # 7 Petroleum and other future industry assignments
14
+ # 8 Healthcare, telecommunications and other future industry assignments
15
+ # 9 – National assignment
16
+ # For example, American Express, Diner's Club, Carte Blanche,
17
+ # and JCB are in the travel and entertainment category;
18
+ # VISA, MasterCard, and Discover are in the banking and financial category (Discover being in the Merchandising and banking/financial category);
19
+ # and Sun Oil and Exxon are in the petroleum category.
15
20
 
16
21
 
17
22
  module CreditCardValidations
@@ -1,5 +1,10 @@
1
+ # String extension for brand detecting and number validation
1
2
  #
2
- #
3
+ # require 'credit_card_validations/string'
4
+ # '5274 5763 9425 9961'.credit_card_brand
5
+ # '5274 5763 9425 9961'.credit_card_brand_name
6
+ # '5274 5763 9425 9961'.valid_credit_card_brand?(:mastercard, :visa)
7
+ # '5274 5763 9425 9961'.valid_credit_card_brand?(:amex)
3
8
  #
4
9
  class String
5
10
  def credit_card_brand
@@ -9,4 +14,9 @@ class String
9
14
  def valid_credit_card_brand?(*brands)
10
15
  CreditCardValidations::Detector.new(self).valid?(*brands)
11
16
  end
17
+
18
+ def credit_card_brand_name
19
+ CreditCardValidations::Detector.new(self).brand_name
20
+ end
21
+
12
22
  end
@@ -1,3 +1,3 @@
1
1
  module CreditCardValidations
2
- VERSION = "1.5.1"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -0,0 +1,238 @@
1
+ ---
2
+ :visa:
3
+ :rules:
4
+ - :length:
5
+ - 13
6
+ - 16
7
+ :prefixes:
8
+ - '4'
9
+ :mastercard:
10
+ :rules:
11
+ - :length:
12
+ - 16
13
+ :prefixes:
14
+ - '51'
15
+ - '52'
16
+ - '53'
17
+ - '54'
18
+ - '55'
19
+ :options:
20
+ :brand_name: MasterCard
21
+ :amex:
22
+ :rules:
23
+ - :length:
24
+ - 15
25
+ :prefixes:
26
+ - '34'
27
+ - '37'
28
+ :options:
29
+ :brand_name: American Express
30
+ :diners:
31
+ :rules:
32
+ - :length:
33
+ - 14
34
+ :prefixes:
35
+ - '300'
36
+ - '301'
37
+ - '302'
38
+ - '303'
39
+ - '304'
40
+ - '305'
41
+ - '36'
42
+ - '38'
43
+ :options:
44
+ :brand_name: Diners Club
45
+ :diners_us:
46
+ :rules:
47
+ - :length:
48
+ - 16
49
+ :prefixes:
50
+ - '54'
51
+ - '55'
52
+ :options:
53
+ :brand_name: Diners Club US
54
+ :discover:
55
+ :rules:
56
+ - :length:
57
+ - 16
58
+ :prefixes:
59
+ - '6011'
60
+ - '644'
61
+ - '645'
62
+ - '646'
63
+ - '647'
64
+ - '648'
65
+ - '649'
66
+ - '65'
67
+ :jcb:
68
+ :rules:
69
+ - :length:
70
+ - 15
71
+ - 16
72
+ :prefixes:
73
+ - '3528'
74
+ - '3529'
75
+ - '353'
76
+ - '354'
77
+ - '355'
78
+ - '356'
79
+ - '357'
80
+ - '358'
81
+ - :length:
82
+ - 15
83
+ :prefixes:
84
+ - '1800'
85
+ - '2131'
86
+ - :length:
87
+ - 19
88
+ :prefixes:
89
+ - '357266'
90
+ :options:
91
+ :brand_name: JCB
92
+ :laser:
93
+ :rules:
94
+ - :length:
95
+ - 16
96
+ - 17
97
+ - 18
98
+ - 19
99
+ :prefixes:
100
+ - '6304'
101
+ - '6706'
102
+ - '6771'
103
+ :solo:
104
+ :rules:
105
+ - :length:
106
+ - 16
107
+ - 18
108
+ - 19
109
+ :prefixes:
110
+ - '6334'
111
+ - '6767'
112
+ :switch:
113
+ :rules:
114
+ - :length:
115
+ - 16
116
+ - 18
117
+ - 19
118
+ :prefixes:
119
+ - '633110'
120
+ - '633312'
121
+ - '633304'
122
+ - '633303'
123
+ - '633301'
124
+ - '633300'
125
+ :maestro:
126
+ :rules:
127
+ - :length:
128
+ - 12
129
+ - 13
130
+ - 14
131
+ - 15
132
+ - 16
133
+ - 17
134
+ - 18
135
+ - 19
136
+ :prefixes:
137
+ - '500'
138
+ - '5010'
139
+ - '5011'
140
+ - '5012'
141
+ - '5013'
142
+ - '5014'
143
+ - '5015'
144
+ - '5016'
145
+ - '5017'
146
+ - '5018'
147
+ - '502'
148
+ - '503'
149
+ - '504'
150
+ - '505'
151
+ - '506'
152
+ - '507'
153
+ - '508'
154
+ - '509'
155
+ - '56'
156
+ - '57'
157
+ - '58'
158
+ - '59'
159
+ - '6010'
160
+ - '6012'
161
+ - '6013'
162
+ - '6014'
163
+ - '6015'
164
+ - '6016'
165
+ - '6017'
166
+ - '6018'
167
+ - '6019'
168
+ - '602'
169
+ - '603'
170
+ - '604'
171
+ - '605'
172
+ - '6060'
173
+ - '621'
174
+ - '627'
175
+ - '629'
176
+ - '670'
177
+ - '671'
178
+ - '672'
179
+ - '673'
180
+ - '674'
181
+ - '675'
182
+ - '677'
183
+ - '6760'
184
+ - '6761'
185
+ - '6762'
186
+ - '6763'
187
+ - '6764'
188
+ - '6765'
189
+ - '6766'
190
+ - '6768'
191
+ - '6769'
192
+ - '679'
193
+ :unionpay:
194
+ :rules:
195
+ - :length:
196
+ - 16
197
+ - 17
198
+ - 18
199
+ - 19
200
+ :prefixes:
201
+ - '622'
202
+ - '624'
203
+ - '625'
204
+ - '626'
205
+ - '628'
206
+ :options:
207
+ :skip_luhn: true
208
+ :brand_name: China UnionPay
209
+ :dankrot:
210
+ :rules:
211
+ - :length:
212
+ - 16
213
+ :prefixes:
214
+ - '5019'
215
+ :rupay:
216
+ :rules:
217
+ - :length:
218
+ - 16
219
+ :prefixes:
220
+ - '6061'
221
+ - '6062'
222
+ - '6063'
223
+ - '6064'
224
+ - '6065'
225
+ - '6066'
226
+ - '6067'
227
+ - '6068'
228
+ - '6069'
229
+ - '607'
230
+ - '608'
231
+ :options:
232
+ :skip_luhn: true
233
+ :hipercard:
234
+ :rules:
235
+ - :length:
236
+ - 19
237
+ :prefixes:
238
+ - '384'
@@ -0,0 +1,69 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe "ActiveModel Validator" do
4
+
5
+ let(:model) { CreditCard.new }
6
+
7
+ describe "Proc support" do
8
+ it "should be valid if brands from proc valid" do
9
+ card = model.dup
10
+ card.card_type = "Master Card"
11
+ card.number6 = CreditCardValidations::Factory.random(:visa)
12
+ card.valid?.must_equal false
13
+ card.number6 = CreditCardValidations::Factory.random(:mastercard)
14
+ card.valid?.must_equal true
15
+
16
+ end
17
+
18
+ end
19
+
20
+ describe "Any Brand" do
21
+ it "should be valid for all prepared valid numbers" do
22
+ VALID_NUMBERS.each do |_, numbers|
23
+
24
+ numbers.each do |number|
25
+ card = model
26
+ card.number4 = number
27
+ card.number5 = number
28
+ card.valid?.must_equal true
29
+
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+
36
+ describe "Except Amex and Maestro brand" do
37
+ it "should reject all other valid numbers" do
38
+ VALID_NUMBERS.except(:amex, :maestro) do |_, numbers|
39
+ card = model
40
+ card.number = numbers.first
41
+ card.valid?.must_equal false
42
+ end
43
+ end
44
+
45
+ it "should accept using except options" do
46
+ VALID_NUMBERS.except(:amex, :maestro) do |_, numbers|
47
+ card = model
48
+ card.number3 = numbers.first
49
+ card.valid?.must_equal true
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ describe "Only Amex and Mestro brands" do
56
+
57
+
58
+ it "should accept amex and maestro brand if valid" do
59
+ VALID_NUMBERS.slice(:amex, :maestro) do |_, numbers|
60
+ card = model
61
+ card.number = numbers.first
62
+ card.number2 = numbers.first
63
+ card.valid?.must_equal true
64
+ end
65
+ end
66
+
67
+
68
+ end
69
+ end