Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 160 lines (133 sloc) 4.722 kB
83ba577 @PawelDecowski Added licence text
authored
1 ###
6cbfe68 @PawelDecowski Merge branch 'feature/namespaced-events' into release/1.0
authored
2 jQuery Credit Card Validator 1.0
83ba577 @PawelDecowski Added licence text
authored
3
6cbfe68 @PawelDecowski Merge branch 'feature/namespaced-events' into release/1.0
authored
4 Copyright 2012-2015 Pawel Decowski
83ba577 @PawelDecowski Added licence text
authored
5
cec0273 @PawelDecowski Change licence to MIT
authored
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software
11 is furnished to do so, subject to the following conditions:
83ba577 @PawelDecowski Added licence text
authored
12
cec0273 @PawelDecowski Change licence to MIT
authored
13 The above copyright notice and this permission notice shall be included
14 in all copies or substantial portions of the Software.
83ba577 @PawelDecowski Added licence text
authored
15
cec0273 @PawelDecowski Change licence to MIT
authored
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 IN THE SOFTWARE.
83ba577 @PawelDecowski Added licence text
authored
23 ###
24
abb491d @PawelDecowski Initial commit
authored
25 $ = jQuery
26
014c549 @gabrieljoelc Improved accepted card types
gabrieljoelc authored
27 $.fn.validateCreditCard = (callback, options) ->
c910c8d @PawelDecowski Added number length and Luhn validation
authored
28 card_types = [
88b5430 @PawelDecowski Refactoring
authored
29 {
84afd65 @PawelDecowski Added support of more cards
authored
30 name: 'amex'
31 pattern: /^3[47]/
32 valid_length: [ 15 ]
33 }
34 {
35 name: 'diners_club_carte_blanche'
36 pattern: /^30[0-5]/
37 valid_length: [ 14 ]
38 }
39 {
40 name: 'diners_club_international'
41 pattern: /^36/
42 valid_length: [ 14 ]
43 }
44 {
45 name: 'jcb'
46 pattern: /^35(2[89]|[3-8][0-9])/
7bf1bfa @jamesallardice Fixes issue where JCB card number lengths are incorrectly reported in…
jamesallardice authored
47 valid_length: [ 16 ]
84afd65 @PawelDecowski Added support of more cards
authored
48 }
49 {
50 name: 'laser'
f6df246 @PawelDecowski Fix Laser card regex
authored
51 pattern: /^(6304|670[69]|6771)/
84afd65 @PawelDecowski Added support of more cards
authored
52 valid_length: [ 16..19 ]
53 }
54 {
5aa0711 @PawelDecowski Change Visa Electron string id to visa_electron
authored
55 name: 'visa_electron'
88b5430 @PawelDecowski Refactoring
authored
56 pattern: /^(4026|417500|4508|4844|491(3|7))/
c910c8d @PawelDecowski Added number length and Luhn validation
authored
57 valid_length: [ 16 ]
88b5430 @PawelDecowski Refactoring
authored
58 }
59 {
60 name: 'visa'
61 pattern: /^4/
d376d67 @PawelDecowski Remove 13 as a valid length for VISA
authored
62 valid_length: [ 16 ]
88b5430 @PawelDecowski Refactoring
authored
63 }
64 {
65 name: 'mastercard'
66 pattern: /^5[1-5]/
c910c8d @PawelDecowski Added number length and Luhn validation
authored
67 valid_length: [ 16 ]
88b5430 @PawelDecowski Refactoring
authored
68 }
69 {
70 name: 'maestro'
71 pattern: /^(5018|5020|5038|6304|6759|676[1-3])/
c910c8d @PawelDecowski Added number length and Luhn validation
authored
72 valid_length: [ 12..19 ]
88b5430 @PawelDecowski Refactoring
authored
73 }
74 {
75 name: 'discover'
76 pattern: /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/
c910c8d @PawelDecowski Added number length and Luhn validation
authored
77 valid_length: [ 16 ]
88b5430 @PawelDecowski Refactoring
authored
78 }
79 ]
ddb105a @PawelDecowski Refactoring
authored
80
d7135e6 @PawelDecowski Make binding optional
authored
81 bind = false
82
83 if callback
84 if typeof callback == 'object'
85 # callback has been skipped and only options parameter has been passed
86 options = callback
87 bind = false
88 callback = null
89 else if typeof callback == 'function'
90 bind = true
91
177132a @PawelDecowski Initiatialise empty options param if undefined
authored
92 options ?= {}
93
014c549 @gabrieljoelc Improved accepted card types
gabrieljoelc authored
94 options.accept ?= (card.name for card in card_types)
ddb105a @PawelDecowski Refactoring
authored
95
014c549 @gabrieljoelc Improved accepted card types
gabrieljoelc authored
96 for card_type in options.accept
97 if card_type not in (card.name for card in card_types)
98 throw "Credit card type '#{ card_type }' is not supported"
ddb105a @PawelDecowski Refactoring
authored
99
c910c8d @PawelDecowski Added number length and Luhn validation
authored
100 get_card_type = (number) ->
ddb105a @PawelDecowski Refactoring
authored
101 for card_type in (card for card in card_types when card.name in options.accept)
102 if number.match card_type.pattern
c910c8d @PawelDecowski Added number length and Luhn validation
authored
103 return card_type
abb491d @PawelDecowski Initial commit
authored
104
c910c8d @PawelDecowski Added number length and Luhn validation
authored
105 null
ddb105a @PawelDecowski Refactoring
authored
106
c910c8d @PawelDecowski Added number length and Luhn validation
authored
107 is_valid_luhn = (number) ->
88b5430 @PawelDecowski Refactoring
authored
108 sum = 0
abb491d @PawelDecowski Initial commit
authored
109
1d9f4dc Fixed backwards compatibility issue with how coffeescript compiles th…
Mark Garringer authored
110 for digit, n in number.split('').reverse()
111 digit = +digit # the + casts the string to int
88b5430 @PawelDecowski Refactoring
authored
112 if n % 2
113 digit *= 2
c910c8d @PawelDecowski Added number length and Luhn validation
authored
114 if digit < 10 then sum += digit else sum += digit - 9
115 else
116 sum += digit
1d9f4dc Fixed backwards compatibility issue with how coffeescript compiles th…
Mark Garringer authored
117
c910c8d @PawelDecowski Added number length and Luhn validation
authored
118 sum % 10 == 0
119
120 is_valid_length = (number, card_type) ->
121 number.length in card_type.valid_length
1d9f4dc Fixed backwards compatibility issue with how coffeescript compiles th…
Mark Garringer authored
122
b89fc3c @PawelDecowski Pass the input element into `this` variable in callback
authored
123 validate_number = (number) =>
c910c8d @PawelDecowski Added number length and Luhn validation
authored
124 card_type = get_card_type number
1ed0c80 @PawelDecowski Demo: added valid number indicator
authored
125 luhn_valid = false
126 length_valid = false
c910c8d @PawelDecowski Added number length and Luhn validation
authored
127
128 if card_type?
1ed0c80 @PawelDecowski Demo: added valid number indicator
authored
129 luhn_valid = is_valid_luhn number
130 length_valid = is_valid_length number, card_type
c910c8d @PawelDecowski Added number length and Luhn validation
authored
131
ff28c08 @PawelDecowski Merge branch 'release/1.0' into feature/binding-optional
authored
132 card_type: card_type
133 valid: luhn_valid and length_valid
134 luhn_valid: luhn_valid
135 length_valid: length_valid
abb491d @PawelDecowski Initial commit
authored
136
ff28c08 @PawelDecowski Merge branch 'release/1.0' into feature/binding-optional
authored
137 validate = =>
e03fc41 @PawelDecowski Keyup fallback if input event is not supported
authored
138 number = normalize $(this).val()
1d9f4dc Fixed backwards compatibility issue with how coffeescript compiles th…
Mark Garringer authored
139 validate_number number
e03fc41 @PawelDecowski Keyup fallback if input event is not supported
authored
140
141 normalize = (number) ->
142 number.replace /[ -]/g, ''
143
ff28c08 @PawelDecowski Merge branch 'release/1.0' into feature/binding-optional
authored
144 if not bind
145 return validate()
146
147 this.on('input.jccv', =>
1343040 @PawelDecowski Detach event with .off instead of .unbind
authored
148 $(this).off('keyup.jccv') # if input event is fired (so is supported) then unbind keyup
ff28c08 @PawelDecowski Merge branch 'release/1.0' into feature/binding-optional
authored
149 callback.call this, validate()
e03fc41 @PawelDecowski Keyup fallback if input event is not supported
authored
150 )
d7135e6 @PawelDecowski Make binding optional
authored
151
e03fc41 @PawelDecowski Keyup fallback if input event is not supported
authored
152 # bind keyup in case input event isn't supported
ff28c08 @PawelDecowski Merge branch 'release/1.0' into feature/binding-optional
authored
153 this.on('keyup.jccv', =>
154 callback.call this, validate()
abb491d @PawelDecowski Initial commit
authored
155 )
d7135e6 @PawelDecowski Make binding optional
authored
156
84afd65 @PawelDecowski Added support of more cards
authored
157 # run validation straight away in case the card number is prefilled
ff28c08 @PawelDecowski Merge branch 'release/1.0' into feature/binding-optional
authored
158 callback.call this, validate()
88b5430 @PawelDecowski Refactoring
authored
159
ff28c08 @PawelDecowski Merge branch 'release/1.0' into feature/binding-optional
authored
160 this
Something went wrong with that request. Please try again.