1/*================================================================================================*/ 2/* 3 * 4 * donwloaded from http://www.braemoor.co.uk/software/creditcard.shtml 5 * adapted by Valerie Isaksen 6 * 7 */ 8/* 9 10 This routine checks the credit card number. The following checks are made: 11 12 1. A number has been provided 13 2. The number is a right length for the card 14 3. The number has an appropriate prefix for the card 15 4. The number has a valid modulus 10 number check digit if required 16 17 If the validation fails an error is reported. 18 19 The structure of credit card formats was gleaned from a variety of sources on the web, although the 20 best is probably on Wikepedia ("Credit card number"): 21 22 http://en.wikipedia.org/wiki/Credit_card_number 23 24 Parameters: 25 cardnumber number on the card 26 cardname name of card as defined in the card list below 27 28 Author: John Gardner 29 Date: 1st November 2003 30 Updated: 26th Feb. 2005 Additional cards added by request 31 Updated: 27th Nov. 2006 Additional cards added from Wikipedia 32 Updated: 18th Jan. 2008 Additional cards added from Wikipedia 33 Updated: 26th Nov. 2008 Maestro cards extended 34 Updated: 19th Jun. 2009 Laser cards extended from Wikipedia 35 Updated: 11th Sep. 2010 Typos removed from Diners and Solo definitions (thanks to Noe Leon) 36 Updated: 10th April 2012 New matches for Maestro, Diners Enroute and Switch 37 Updated: 17th October 2012 Diners Club prefix 38 not encoded 38 39 */ 40 41/* 42 If a credit card number is invalid, an error reason is loaded into the global ccErrorNo variable. 43 This can be be used to index into the global error string array to report the reason to the user 44 if required: 45 46 e.g. if (!checkCreditCard (number, name) alert (ccErrors(ccErrorNo); 47 */ 48 49var ccErrorNo = 0; 50 51 52/*************************************************************************\ 53 boolean isExpiryDate([int year, int month]) 54 return true if the date is a valid expiry date, 55 else return false. 56 \*************************************************************************/ 57function CreditCardisExpiryDate(month, year,paymentmethod_id) { 58 document.getElementById("cc_expiredate_errormsg_"+paymentmethod_id).style.display="none"; 59 document.getElementById("cc_expiredate_errormsg_"+paymentmethod_id).innerHTML =''; 60 today = new Date(); 61 expiry = new Date(year, month); 62 if (today.getTime() > expiry.getTime()) { 63 var error_msg = ccErrors [5] ; 64 document.getElementById("cc_expiredate_errormsg_"+ paymentmethod_id).style.display="block"; 65 document.getElementById("cc_expiredate_errormsg_"+ paymentmethod_id).innerHTML =error_msg; 66 return false; 67 } else 68 return true; 69} 70 71 72 73 74 75 76function CheckCreditCardNumber(cardnumber, paymentmethod_id){ 77 for (cardType = 0; cardType < 13 ; cardType++) { 78 if(checkCreditCard(cardnumber,cardType)){ 79 return true; 80 } 81 } 82 var error_msg = ccErrors [ccErrorNo] ; 83 document.getElementById("cc_cardnumber_errormsg_"+ paymentmethod_id).style.display="block"; 84 document.getElementById("cc_cardnumber_errormsg_"+ paymentmethod_id).innerHTML =error_msg; 85 86 return false; 87} 88function razCCerror(paymentmethod_id){ 89 90 document.getElementById("cc_cardnumber_errormsg_" + paymentmethod_id).style.display="none"; 91 document.getElementById("cc_cardnumber_errormsg_" + paymentmethod_id).innerHTML =''; 92 93 return true; 94} 95function checkCreditCard (cardnumber, cardname) { 96 97 // Array to hold the permitted card characteristics 98 var cards = new Array(); 99 100 // Define the cards we support. You may add addtional card types as follows. 101 102 // Name: As in the selection box of the form - must be same as user's 103 // Length: List of possible valid lengths of the card number for the card 104 // prefixes: List of possible prefixes for the card 105 // checkdigit: Boolean to say whether there is a check digit 106 107 cards [0] = {name: "Visa", 108 length: "13,16", 109 prefixes: "4", 110 checkdigit: true}; 111 cards [1] = {name: "MasterCard", 112 length: "16", 113 prefixes: "51,52,53,54,55", 114 checkdigit: true}; 115 cards [2] = {name: "DinersClub", 116 length: "14,16",
117 prefixes: "36,38,54,55", 118 checkdigit: true}; 119 cards [3] = {name: "CarteBlanche", 120 length: "14", 121 prefixes: "300,301,302,303,304,305", 122 checkdigit: true}; 123 cards [4] = {name: "AmEx", 124 length: "15", 125 prefixes: "34,37", 126 checkdigit: true}; 127 cards [5] = {name: "Discover", 128 length: "16", 129 prefixes: "6011,622,64,65", 130 checkdigit: true}; 131 cards [6] = {name: "JCB", 132 length: "16", 133 prefixes: "35", 134 checkdigit: true}; 135 cards [7] = {name: "enRoute", 136 length: "15", 137 prefixes: "2014,2149", 138 checkdigit: true}; 139 cards [8] = {name: "Solo", 140 length: "16,18,19", 141 prefixes: "6334,6767", 142 checkdigit: true}; 143 cards [9] = {name: "Switch", 144 length: "16,18,19", 145 prefixes: "4903,4905,4911,4936,564182,633110,6333,6759", 146 checkdigit: true}; 147 cards [10] = {name: "Maestro", 148 length: "12,13,14,15,16,18,19", 149 prefixes: "5018,5020,5038,6304,6759,6761,6762,6763", 150 checkdigit: true}; 151 cards [11] = {name: "VisaElectron", 152 length: "16", 153 prefixes: "4026,417500,4508,4844,4913,4917", 154 checkdigit: true}; 155 cards [12] = {name: "LaserCard", 156 length: "16,17,18,19", 157 prefixes: "6304,6706,6771,6709", 158 checkdigit: true}; 159 160 // Establish card type 161 var cardType = -1; 162 for (var i=0; i<cards.length; i++) { 163 // See if it is this card (ignoring the case of the string) 164 if (typeof cardname != 'undefined') 165 if (cardname != null) 166 if (cardname.toLowerCase () == cards[i].name.toLowerCase()) { 167 cardType = i; 168 break; 169 } 170 } 171 172 // If card type not found, report an error 173 if (cardType == -1) { 174 ccErrorNo = 0; 175 return false; 176 } 177 178 // Ensure that the user has provided a credit card number 179 if (cardnumber.length == 0) { 180 ccErrorNo = 1; 181 return false; 182 } 183 184 // Now remove any spaces from the credit card number 185 cardnumber = cardnumber.replace (/\s/g, ""); 186 187 // Check that the number is numeric 188 var cardNo = cardnumber 189 var cardexp = /^[0-9]{13,19}$/; 190 if (!cardexp.exec(cardNo)) { 191 ccErrorNo = 2; 192 return false; 193 } 194 195 // Now check the modulus 10 check digit - if required 196 if (cards[cardType].checkdigit) { 197 var checksum = 0; // running checksum total 198 var mychar = ""; // next char to process 199 var j = 1; // takes value of 1 or 2 200 201 // Process each digit one by one starting at the right 202 var calc; 203 for (i = cardNo.length - 1; i >= 0; i--) { 204 205 // Extract the next digit and multiply by 1 or 2 on alternative digits. 206 calc = Number(cardNo.charAt(i)) * j; 207 208 // If the result is in two digits add 1 to the checksum total 209 if (calc > 9) { 210 checksum = checksum + 1; 211 calc = calc - 10; 212 } 213 214 // Add the units element to the checksum total 215 checksum = checksum + calc; 216 217 // Switch the value of j 218 if (j ==1) {j = 2} else {j = 1}; 219 } 220 221 // All done - if checksum is divisible by 10, it is a valid modulus 10. 222 // If not, report an error. 223 if (checksum % 10 != 0) { 224 ccErrorNo = 3; 225 return false; 226 } 227 } 228 229 // Check it's not a spam number 230 if (cardNo == '5490997771092064') { 231 ccErrorNo = 5; 232 return false; 233 } 234 235 // The following are the card-specific checks we undertake. 236 var LengthValid = false; 237 var PrefixValid = false; 238 var undefined; 239 240 // We use these for holding the valid lengths and prefixes of a card type 241 var prefix = new Array (); 242 var lengths = new Array (); 243 244 // Load an array with the valid prefixes for this card 245 prefix = cards[cardType].prefixes.split(","); 246 247 // Now see if any of them match what we have in the card number 248 for (i=0; i<prefix.length; i++) { 249 var exp = new RegExp ("^" + prefix[i]); 250 if (exp.test (cardNo)) PrefixValid = true; 251 } 252 253 // If it isn't a valid prefix there's no point at looking at the length 254 if (!PrefixValid) { 255 ccErrorNo = 3; 256 return false;
257 } 258 259 // See if the length is valid for this card 260 lengths = cards[cardType].length.split(","); 261 for (j=0; j<lengths.length; j++) { 262 if (cardNo.length == lengths[j]) LengthValid = true; 263 } 264 265 // See if all is OK by seeing if the length was valid. We only check the length if all else was 266 // hunky dory. 267 if (!LengthValid) { 268 ccErrorNo = 4; 269 return false; 270 }; 271 272 // The credit card is in the required format. 273 return true; 274} 275 276/*================================================================================================*/
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.