jquery_payment 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bbe943b4869a023e4fba27d4668edec3330d5e98
4
+ data.tar.gz: 6f73bb991dd38e166dbe948840549d71459216eb
5
+ SHA512:
6
+ metadata.gz: ce56e8553f93bb46ae0028af09b8707a1cd9d9018fed95abefaae3bf733059ae8ba22024d3b5b0cb6e7da2186cdc3234da75312d1c99dfc12327b89486b4992f
7
+ data.tar.gz: b2ae9ae6513af5ed06f5a9e914e32bab9959ae558d423baceb11e85b584ca501acf47a2628e153f72aec40e5f8fa83b1e1d8ab7bfa899ab304d491a915aac6d5
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jquery_payment.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Victor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ 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, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # JqueryPayment
2
+
3
+ This is a gem wrapper for [jquery.payment](https://github.com/stripe/jquery.payment)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'jquery_payment'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install jquery_payment
18
+
19
+ ## Usage
20
+
21
+
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jquery_payment/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jquery_payment"
8
+ spec.version = JqueryPayment::VERSION
9
+ spec.authors = ["ampvchen"]
10
+ spec.email = ["self@vchen.me"]
11
+ spec.description = %q{jquery.payments gem wrapper}
12
+ spec.summary = %q{jquery.payments gem wrapper}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ # coffee-script
25
+ spec.add_dependency "coffee-script"
26
+ end
@@ -0,0 +1,3 @@
1
+ module JqueryPayment
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,8 @@
1
+ require "jquery_payment/version"
2
+
3
+ module JqueryPayment
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,439 @@
1
+ $ = jQuery
2
+ $.payment = {}
3
+ $.payment.fn = {}
4
+ $.fn.payment = (method, args...) ->
5
+ $.payment.fn[method].apply(this, args)
6
+
7
+ # Utils
8
+
9
+ defaultFormat = /(\d{1,4})/g
10
+
11
+ cards = [
12
+ {
13
+ type: 'maestro'
14
+ pattern: /^(5018|5020|5038|6304|6759|676[1-3])/
15
+ format: defaultFormat
16
+ length: [12..19]
17
+ cvcLength: [3]
18
+ luhn: true
19
+ }
20
+ {
21
+ type: 'dinersclub'
22
+ pattern: /^(36|38|30[0-5])/
23
+ format: defaultFormat
24
+ length: [14]
25
+ cvcLength: [3]
26
+ luhn: true
27
+ }
28
+ {
29
+ type: 'laser'
30
+ pattern: /^(6706|6771|6709)/
31
+ format: defaultFormat
32
+ length: [16..19]
33
+ cvcLength: [3]
34
+ luhn: true
35
+ }
36
+ {
37
+ type: 'jcb'
38
+ pattern: /^35/
39
+ format: defaultFormat
40
+ length: [16]
41
+ cvcLength: [3]
42
+ luhn: true
43
+ }
44
+ {
45
+ type: 'unionpay'
46
+ pattern: /^62/
47
+ format: defaultFormat
48
+ length: [16..19]
49
+ cvcLength: [3]
50
+ luhn: false
51
+ }
52
+ {
53
+ type: 'discover'
54
+ pattern: /^(6011|65|64[4-9]|622)/
55
+ format: defaultFormat
56
+ length: [16]
57
+ cvcLength: [3]
58
+ luhn: true
59
+ }
60
+ {
61
+ type: 'mastercard'
62
+ pattern: /^5[1-5]/
63
+ format: defaultFormat
64
+ length: [16]
65
+ cvcLength: [3]
66
+ luhn: true
67
+ }
68
+ {
69
+ type: 'amex'
70
+ pattern: /^3[47]/
71
+ format: /(\d{1,4})(\d{1,6})?(\d{1,5})?/
72
+ length: [15]
73
+ cvcLength: [3..4]
74
+ luhn: true
75
+ }
76
+ {
77
+ type: 'visa'
78
+ pattern: /^4/
79
+ format: defaultFormat
80
+ length: [13..16]
81
+ cvcLength: [3]
82
+ luhn: true
83
+ }
84
+ ]
85
+
86
+ cardFromNumber = (num) ->
87
+ num = (num + '').replace(/\D/g, '')
88
+ return card for card in cards when card.pattern.test(num)
89
+
90
+ cardFromType = (type) ->
91
+ return card for card in cards when card.type is type
92
+
93
+ luhnCheck = (num) ->
94
+ odd = true
95
+ sum = 0
96
+
97
+ digits = (num + '').split('').reverse()
98
+
99
+ for digit in digits
100
+ digit = parseInt(digit, 10)
101
+ digit *= 2 if (odd = !odd)
102
+ digit -= 9 if digit > 9
103
+ sum += digit
104
+
105
+ sum % 10 == 0
106
+
107
+ hasTextSelected = ($target) ->
108
+ # If some text is selected
109
+ return true if $target.prop('selectionStart')? and
110
+ $target.prop('selectionStart') isnt $target.prop('selectionEnd')
111
+
112
+ # If some text is selected in IE
113
+ return true if document?.selection?.createRange?().text
114
+
115
+ false
116
+
117
+ # Private
118
+
119
+ # Format Card Number
120
+
121
+ reFormatCardNumber = (e) ->
122
+ setTimeout =>
123
+ $target = $(e.currentTarget)
124
+ value = $target.val()
125
+ value = $.payment.formatCardNumber(value)
126
+ $target.val(value)
127
+
128
+ formatCardNumber = (e) ->
129
+ # Only format if input is a number
130
+ digit = String.fromCharCode(e.which)
131
+ return unless /^\d+$/.test(digit)
132
+
133
+ $target = $(e.currentTarget)
134
+ value = $target.val()
135
+ card = cardFromNumber(value + digit)
136
+ length = (value.replace(/\D/g, '') + digit).length
137
+
138
+ upperLength = 16
139
+ upperLength = card.length[card.length.length - 1] if card
140
+ return if length >= upperLength
141
+
142
+ # Return if focus isn't at the end of the text
143
+ return if $target.prop('selectionStart')? and
144
+ $target.prop('selectionStart') isnt value.length
145
+
146
+ if card && card.type is 'amex'
147
+ # Amex cards are formatted differently
148
+ re = /^(\d{4}|\d{4}\s\d{6})$/
149
+ else
150
+ re = /(?:^|\s)(\d{4})$/
151
+
152
+ # If '4242' + 4
153
+ if re.test(value)
154
+ e.preventDefault()
155
+ $target.val(value + ' ' + digit)
156
+
157
+ # If '424' + 2
158
+ else if re.test(value + digit)
159
+ e.preventDefault()
160
+ $target.val(value + digit + ' ')
161
+
162
+ formatBackCardNumber = (e) ->
163
+ $target = $(e.currentTarget)
164
+ value = $target.val()
165
+
166
+ return if e.meta
167
+
168
+ # Return unless backspacing
169
+ return unless e.which is 8
170
+
171
+ # Return if focus isn't at the end of the text
172
+ return if $target.prop('selectionStart')? and
173
+ $target.prop('selectionStart') isnt value.length
174
+
175
+ # Remove the trailing space
176
+ if /\d\s$/.test(value)
177
+ e.preventDefault()
178
+ $target.val(value.replace(/\d\s$/, ''))
179
+ else if /\s\d?$/.test(value)
180
+ e.preventDefault()
181
+ $target.val(value.replace(/\s\d?$/, ''))
182
+
183
+ # Format Expiry
184
+
185
+ formatExpiry = (e) ->
186
+ # Only format if input is a number
187
+ digit = String.fromCharCode(e.which)
188
+ return unless /^\d+$/.test(digit)
189
+
190
+ $target = $(e.currentTarget)
191
+ val = $target.val() + digit
192
+
193
+ if /^\d$/.test(val) and val not in ['0', '1']
194
+ e.preventDefault()
195
+ $target.val("0#{val} / ")
196
+
197
+ else if /^\d\d$/.test(val)
198
+ e.preventDefault()
199
+ $target.val("#{val} / ")
200
+
201
+ formatForwardExpiry = (e) ->
202
+ digit = String.fromCharCode(e.which)
203
+ return unless /^\d+$/.test(digit)
204
+
205
+ $target = $(e.currentTarget)
206
+ val = $target.val()
207
+
208
+ if /^\d\d$/.test(val)
209
+ $target.val("#{val} / ")
210
+
211
+ formatForwardSlash = (e) ->
212
+ slash = String.fromCharCode(e.which)
213
+ return unless slash is '/'
214
+
215
+ $target = $(e.currentTarget)
216
+ val = $target.val()
217
+
218
+ if /^\d$/.test(val) and val isnt '0'
219
+ $target.val("0#{val} / ")
220
+
221
+ formatBackExpiry = (e) ->
222
+ # If shift+backspace is pressed
223
+ return if e.meta
224
+
225
+ $target = $(e.currentTarget)
226
+ value = $target.val()
227
+
228
+ # Return unless backspacing
229
+ return unless e.which is 8
230
+
231
+ # Return if focus isn't at the end of the text
232
+ return if $target.prop('selectionStart')? and
233
+ $target.prop('selectionStart') isnt value.length
234
+
235
+ # Remove the trailing space
236
+ if /\d(\s|\/)+$/.test(value)
237
+ e.preventDefault()
238
+ $target.val(value.replace(/\d(\s|\/)*$/, ''))
239
+ else if /\s\/\s?\d?$/.test(value)
240
+ e.preventDefault()
241
+ $target.val(value.replace(/\s\/\s?\d?$/, ''))
242
+
243
+ # Restrictions
244
+
245
+ restrictNumeric = (e) ->
246
+ # Key event is for a browser shortcut
247
+ return true if e.metaKey or e.ctrlKey
248
+
249
+ # If keycode is a space
250
+ return false if e.which is 32
251
+
252
+ # If keycode is a special char (WebKit)
253
+ return true if e.which is 0
254
+
255
+ # If char is a special char (Firefox)
256
+ return true if e.which < 33
257
+
258
+ input = String.fromCharCode(e.which)
259
+
260
+ # Char is a number or a space
261
+ !!/[\d\s]/.test(input)
262
+
263
+ restrictCardNumber = (e) ->
264
+ $target = $(e.currentTarget)
265
+ digit = String.fromCharCode(e.which)
266
+ return unless /^\d+$/.test(digit)
267
+
268
+ return if hasTextSelected($target)
269
+
270
+ # Restrict number of digits
271
+ value = ($target.val() + digit).replace(/\D/g, '')
272
+ card = cardFromNumber(value)
273
+
274
+ if card
275
+ value.length <= card.length[card.length.length - 1]
276
+ else
277
+ # All other cards are 16 digits long
278
+ value.length <= 16
279
+
280
+ restrictExpiry = (e) ->
281
+ $target = $(e.currentTarget)
282
+ digit = String.fromCharCode(e.which)
283
+ return unless /^\d+$/.test(digit)
284
+
285
+ return if hasTextSelected($target)
286
+
287
+ value = $target.val() + digit
288
+ value = value.replace(/\D/g, '')
289
+
290
+ return false if value.length > 6
291
+
292
+ restrictCVC = (e) ->
293
+ $target = $(e.currentTarget)
294
+ digit = String.fromCharCode(e.which)
295
+ return unless /^\d+$/.test(digit)
296
+
297
+ val = $target.val() + digit
298
+ val.length <= 4
299
+
300
+ setCardType = (e) ->
301
+ $target = $(e.currentTarget)
302
+ val = $target.val()
303
+ cardType = $.payment.cardType(val) or 'unknown'
304
+
305
+ unless $target.hasClass(cardType)
306
+ allTypes = (card.type for card in cards)
307
+
308
+ $target.removeClass('unknown')
309
+ $target.removeClass(allTypes.join(' '))
310
+
311
+ $target.addClass(cardType)
312
+ $target.toggleClass('identified', cardType isnt 'unknown')
313
+ $target.trigger('payment.cardType', cardType)
314
+
315
+ # Public
316
+
317
+ # Formatting
318
+
319
+ $.payment.fn.formatCardCVC = ->
320
+ @payment('restrictNumeric')
321
+ @on('keypress', restrictCVC)
322
+ this
323
+
324
+ $.payment.fn.formatCardExpiry = ->
325
+ @payment('restrictNumeric')
326
+ @on('keypress', restrictExpiry)
327
+ @on('keypress', formatExpiry)
328
+ @on('keypress', formatForwardSlash)
329
+ @on('keypress', formatForwardExpiry)
330
+ @on('keydown', formatBackExpiry)
331
+ this
332
+
333
+ $.payment.fn.formatCardNumber = ->
334
+ @payment('restrictNumeric')
335
+ @on('keypress', restrictCardNumber)
336
+ @on('keypress', formatCardNumber)
337
+ @on('keydown', formatBackCardNumber)
338
+ @on('keyup', setCardType)
339
+ @on('paste', reFormatCardNumber)
340
+ this
341
+
342
+ # Restrictions
343
+
344
+ $.payment.fn.restrictNumeric = ->
345
+ @on('keypress', restrictNumeric)
346
+ this
347
+
348
+ # Validations
349
+
350
+ $.payment.fn.cardExpiryVal = ->
351
+ $.payment.cardExpiryVal($(this).val())
352
+
353
+ $.payment.cardExpiryVal = (value) ->
354
+ value = value.replace(/\s/g, '')
355
+ [month, year] = value.split('/', 2)
356
+
357
+ # Allow for year shortcut
358
+ if year?.length is 2 and /^\d+$/.test(year)
359
+ prefix = (new Date).getFullYear()
360
+ prefix = prefix.toString()[0..1]
361
+ year = prefix + year
362
+
363
+ month = parseInt(month, 10)
364
+ year = parseInt(year, 10)
365
+
366
+ month: month, year: year
367
+
368
+ $.payment.validateCardNumber = (num) ->
369
+ num = (num + '').replace(/\s+|-/g, '')
370
+ return false unless /^\d+$/.test(num)
371
+
372
+ card = cardFromNumber(num)
373
+ return false unless card
374
+
375
+ num.length in card.length and
376
+ (card.luhn is false or luhnCheck(num))
377
+
378
+ $.payment.validateCardExpiry = (month, year) =>
379
+ # Allow passing an object
380
+ if typeof month is 'object' and 'month' of month
381
+ {month, year} = month
382
+
383
+ return false unless month and year
384
+
385
+ month = $.trim(month)
386
+ year = $.trim(year)
387
+
388
+ return false unless /^\d+$/.test(month)
389
+ return false unless /^\d+$/.test(year)
390
+ return false unless parseInt(month, 10) <= 12
391
+
392
+ if year.length is 2
393
+ prefix = (new Date).getFullYear()
394
+ prefix = prefix.toString()[0..1]
395
+ year = prefix + year
396
+
397
+ expiry = new Date(year, month)
398
+ currentTime = new Date
399
+
400
+ # Months start from 0 in JavaScript
401
+ expiry.setMonth(expiry.getMonth() - 1)
402
+
403
+ # The cc expires at the end of the month,
404
+ # so we need to make the expiry the first day
405
+ # of the month after
406
+ expiry.setMonth(expiry.getMonth() + 1, 1)
407
+
408
+ expiry > currentTime
409
+
410
+ $.payment.validateCardCVC = (cvc, type) ->
411
+ cvc = $.trim(cvc)
412
+ return false unless /^\d+$/.test(cvc)
413
+
414
+ if type
415
+ # Check against a explicit card type
416
+ cvc.length in cardFromType(type)?.cvcLength
417
+ else
418
+ # Check against all types
419
+ cvc.length >= 3 and cvc.length <= 4
420
+
421
+ $.payment.cardType = (num) ->
422
+ return null unless num
423
+ cardFromNumber(num)?.type or null
424
+
425
+ $.payment.formatCardNumber = (num) ->
426
+ card = cardFromNumber(num)
427
+ return num unless card
428
+
429
+ upperLength = card.length[card.length.length - 1]
430
+
431
+ num = num.replace(/\D/g, '')
432
+ num = num[0..upperLength]
433
+
434
+ if card.format.global
435
+ num.match(card.format)?.join(' ')
436
+ else
437
+ groups = card.format.exec(num)
438
+ groups?.shift()
439
+ groups?.join(' ')
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jquery_payment
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - ampvchen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: coffee-script
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: jquery.payments gem wrapper
56
+ email:
57
+ - self@vchen.me
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - LICENSE
65
+ - README.md
66
+ - Rakefile
67
+ - jquery_payment.gemspec
68
+ - lib/jquery_payment.rb
69
+ - lib/jquery_payment/version.rb
70
+ - vendor/assets/javascript/jquery.payment.coffee
71
+ homepage: ''
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.0.6
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: jquery.payments gem wrapper
95
+ test_files: []