1 | define(["dojo/_base/lang", "./_base"], function(lang, validate){ |
---|
2 | |
---|
3 | /*===== |
---|
4 | return { |
---|
5 | // summary: |
---|
6 | // Module provides validation functions for Credit Cards, using account number |
---|
7 | // rules in conjunction with the Luhn algorigthm, with a pluggable card info database. |
---|
8 | }; |
---|
9 | =====*/ |
---|
10 | |
---|
11 | validate._cardInfo = { |
---|
12 | // summary: |
---|
13 | // A dictionary list of credit card abbreviations |
---|
14 | // description: |
---|
15 | // A hash of valid CC abbreviations and regular expressions |
---|
16 | // |
---|
17 | // - mc: Mastercard |
---|
18 | // - ec: Eurocard |
---|
19 | // - vi: Visa |
---|
20 | // - ax: American Express |
---|
21 | // - dc: Diners Club |
---|
22 | // - bl: Carte Blanch |
---|
23 | // - di: Discover |
---|
24 | // - jcb: JCB |
---|
25 | // - er: Enroute |
---|
26 | // example: |
---|
27 | // Define your own card, gift-card, whatever. Starts with 7, |
---|
28 | // is 15 total length. |
---|
29 | // | dojo.mixin(dojox.validate._cardInfo, { |
---|
30 | // | "my":"7[0-9]{14}" |
---|
31 | // | }); |
---|
32 | |
---|
33 | 'mc':'5[1-5][0-9]{14}', |
---|
34 | 'ec':'5[1-5][0-9]{14}', |
---|
35 | 'vi':'4(?:[0-9]{12}|[0-9]{15})', |
---|
36 | 'ax':'3[47][0-9]{13}', |
---|
37 | 'dc':'3(?:0[0-5][0-9]{11}|[68][0-9]{12})', |
---|
38 | 'bl':'3(?:0[0-5][0-9]{11}|[68][0-9]{12})', |
---|
39 | 'di':'6011[0-9]{12}', |
---|
40 | 'jcb':'(?:3[0-9]{15}|(2131|1800)[0-9]{11})', |
---|
41 | 'er':'2(?:014|149)[0-9]{11}' |
---|
42 | }; |
---|
43 | |
---|
44 | validate.isValidCreditCard = function(value, ccType){ |
---|
45 | // summary: |
---|
46 | // Validate a credit card number by type with Luhn checking. |
---|
47 | // description: |
---|
48 | // Checks if a credit card type matches the # scheme in a passed value, and if |
---|
49 | // the Luhn checksum is accurate (unless its an Enroute card, in which case |
---|
50 | // the checkSum is skipped), returning a Boolean to check against. |
---|
51 | // value: String|Int |
---|
52 | // A Value (credit card number) to validate |
---|
53 | // ccType: String |
---|
54 | // A credit-card abbreviation. |
---|
55 | // example: |
---|
56 | // | if(dojox.validate.isValidCreditCard("12345", "mc")){ |
---|
57 | // | console.log('inconceivable'); |
---|
58 | // | } |
---|
59 | |
---|
60 | return ((ccType.toLowerCase() == 'er' || validate.isValidLuhn(value)) && |
---|
61 | validate.isValidCreditCardNumber(value, ccType.toLowerCase())); // Boolean |
---|
62 | }; |
---|
63 | |
---|
64 | validate.isValidCreditCardNumber = function(value, ccType){ |
---|
65 | // summary: |
---|
66 | // Checks if value matches the pattern for that card or any card types if none is specified |
---|
67 | // value: String|Int |
---|
68 | // CC #, white spaces and dashes are ignored |
---|
69 | // ccType: String? |
---|
70 | // One of the abbreviation values in `dojox.validate._cardInfo` -- |
---|
71 | // if Omitted, function returns a `|` delimited string of matching card types, |
---|
72 | // or false if no matches found. |
---|
73 | |
---|
74 | value = String(value).replace(/[- ]/g,''); //ignore dashes and whitespaces |
---|
75 | |
---|
76 | var cardinfo = validate._cardInfo, results = []; |
---|
77 | if(ccType){ |
---|
78 | var expr = '^' + cardinfo[ccType.toLowerCase()] + '$'; |
---|
79 | return expr ? !!value.match(expr) : false; // boolean |
---|
80 | } |
---|
81 | |
---|
82 | for(var p in cardinfo){ |
---|
83 | if(value.match('^' + cardinfo[p] + '$')){ |
---|
84 | results.push(p); |
---|
85 | } |
---|
86 | } |
---|
87 | return results.length ? results.join('|') : false; // String|Boolean |
---|
88 | }; |
---|
89 | |
---|
90 | validate.isValidCvv = function(/* String|Int */value, /* String */ccType) { |
---|
91 | // summary: |
---|
92 | // Validate the security code (CCV) for a passed credit-card type. |
---|
93 | |
---|
94 | if(!lang.isString(value)){ |
---|
95 | value = String(value); |
---|
96 | } |
---|
97 | var format; |
---|
98 | switch (ccType.toLowerCase()){ |
---|
99 | case 'mc': |
---|
100 | case 'ec': |
---|
101 | case 'vi': |
---|
102 | case 'di': |
---|
103 | format = '###'; |
---|
104 | break; |
---|
105 | case 'ax': |
---|
106 | format = '####'; |
---|
107 | break; |
---|
108 | } |
---|
109 | |
---|
110 | return !!format && value.length && validate.isNumberFormat(value, { format: format }); // Boolean |
---|
111 | }; |
---|
112 | |
---|
113 | // TODO: return functions defined in this module, rather than sticking them into "validate" |
---|
114 | return validate; |
---|
115 | }); |
---|