Posted By

geneticcode on 12/01/14


Tagged

javascript js validation credit card validate creditcard


Versions (?)

Credit Card Parser & Validator


 / Published in: JavaScript
 

URL: http://geneticcoder.blogspot.com/2014/11/advanced-client-side-credit-card.html

With publicly available information and a little math it is possible to not only validate a given card number, but to determine the financial institution that issued the card, the type of industry the issuer belongs to, the actual account number and more.

Fiddle: http://jsfiddle.net/qLq29frn/1/

  1. // CreditCard object definition
  2. function CreditCard(ccn){
  3. // Card properties
  4. this.valid = true;
  5. this.error = "None";
  6. this.digits = "";
  7. this.industry = "N/A";
  8. this.MII = "N/A";
  9. this.IIN = "N/A";
  10. this.issuer = "N/A";
  11. this.validation = "None";
  12. this.accountNumber = "N/A";
  13. this.checksum = "N/A";
  14.  
  15. // Methods
  16. // +++++
  17. // Luhn Algorithm check
  18. this.luhnCheck = function(){
  19. var i = this.digits.length;
  20. var even = true; //zero is even
  21. var sum = 0;
  22. while(i--){
  23. even = !even;
  24. digit = parseInt(this.digits[i]);
  25. if(even){
  26. digit = digit * 2;
  27. if(digit > 9){
  28. d = String(digit);
  29. digit = parseInt(d[0]) + parseInt(d[1]);
  30. }
  31. }
  32. sum += digit;
  33. }
  34. return (sum % 10) === 0;
  35. };
  36. // Determine the issuer based on the IIN
  37. // Data source: http://en.wikipedia.org/wiki/Bank_card_number#Issuer_identification_number_.28IIN.29
  38. this.getIssuer = function(){
  39. var iin = this.IIN;
  40. var i = this.digits.length;
  41. var validLength = false;
  42. if(iin.substring(0,2) === "34" || iin.substring(0,2) === "37"){
  43. this.issuer = "American Express";
  44. this.validation = "Luhn";
  45. validLength = i === 15;
  46. }else if(iin.substring(0,2) === "56"){
  47. this.issuer = "Bankcard";
  48. this.validation = "Luhn";
  49. validLength = i === 16;
  50. }else if(iin.substring(0,2) === "62"){
  51. this.issuer = "China UnionPay (Discover)";
  52. this.validation = "Length";
  53. validLength = i > 15 && i < 20;
  54. }else if(iin.substring(0,2) === "30" || iin.substring(0,2) === "36" || iin.substring(0,2) === "38" || iin.substring(0,2) === "39"){
  55. this.issuer = "Diners Club International";
  56. this.validation = "Luhn";
  57. validLength = i === 14;
  58. }else if(iin.substring(0,2) === "20" || iin.substring(0,2) === "21"){
  59. this.issuer = "Diners Club enRoute";
  60. this.validation = "Length";
  61. validLength = i === 15;
  62. }else if(iin.substring(0,2) === "54" || iin.substring(0,2) === "55"){
  63. this.issuer = "Diners Club";
  64. this.validation = "Luhn";
  65. validLength = i === 16;
  66. }else if(iin.substring(0,2) === "60" || iin.substring(0,2) === "62" || iin.substring(0,2) === "64" || iin.substring(0,2) === "65"){
  67. this.issuer = "Discover Card";
  68. this.validation = "Luhn";
  69. validLength = i === 16;
  70. }else if(iin.substring(0,3) === "636"){
  71. this.issuer = "InterPayment";
  72. this.validation = "Luhn";
  73. validLength = i > 15 && i < 20;
  74. }else if(iin.substring(0,3) === "637" || iin.substring(0,3) === "638" || iin.substring(0,3) === "639"){
  75. this.issuer = "InstaPayment";
  76. this.validation = "Luhn";
  77. validLength = i === 16;
  78. }else if(iin.substring(0,2) === "35"){
  79. this.issuer = "JCB";
  80. this.validation = "Luhn";
  81. validLength = i === 16;
  82. }else if(iin.substring(0,4) === "6304" || iin.substring(0,4) === "6706" || iin.substring(0,4) === "6771" || iin.substring(0,4) === "6709"){
  83. this.issuer = "Laser";
  84. this.validation = "Luhn";
  85. validLength = i > 15 && i < 20;
  86. }else if(iin.substring(0,4) === "5019"){
  87. this.issuer = "Dankort";
  88. this.validation = "Luhn";
  89. validLength = i === 16;
  90. }else if(iin.substring(0,2) === "50" || (parseInt(iin.substring(0,2)) > 55 && parseInt(iin.substring(0,2)) < 70)){
  91. this.issuer = "Maestro";
  92. this.validation = "Luhn";
  93. validLength = i > 11 && i < 20;
  94. }else if((parseInt(iin.substring(0,2)) > 21 && parseInt(iin.substring(0,2)) < 28) || (parseInt(iin.substring(0,2)) > 50 && parseInt(iin.substring(0,2)) < 56)){
  95. this.issuer = "MasterCard";
  96. this.validation = "Luhn";
  97. validLength = i === 16;
  98. }else if(iin.substring(0,4) === "6334" || iin.substring(0,4) === "6767"){
  99. this.issuer = "Solo";
  100. this.validation = "Luhn";
  101. validLength = i === 16 || i === 18 || i === 19;
  102. }else if(iin.substring(0,4) === "4903" || iin.substring(0,4) === "4905" || iin.substring(0,4) === "4905" || iin.substring(0,4) === "4911" || iin.substring(0,4) === "4936" || iin === "564182" || iin === "633110" || iin.substring(0,4) === "6333" || iin.substring(0,4) === "6759"){
  103. this.issuer = "Switch";
  104. this.validation = "Luhn";
  105. validLength = i === 16 || i === 18 || i === 19;
  106. }else if(iin.substring(0,4) === "4026" || iin === "417500" || iin.substring(0,4) === "4405" || iin.substring(0,4) === "4508" || iin.substring(0,4) === "4844" || iin.substring(0,4) === "4913" || iin.substring(0,4) === "4917"){
  107. this.issuer = "Visa Electron";
  108. this.validation = "Luhn";
  109. validLength = i === 16;
  110. }else if(iin.substring(0,1) === "4"){
  111. this.issuer = "Visa";
  112. this.validation = "Luhn";
  113. validLength = i === 16 || i === 13;
  114. }else if(iin.substring(0,1) === "1"){
  115. this.issuer = "UATP";
  116. this.validation = "Luhn";
  117. validLength = i === 15;
  118. }else{
  119. this.issuer = "Not Known";
  120. this.validation = "Length";
  121. validLength = true;
  122. }
  123. if(!validLength){
  124. this.valid = false;
  125. this.error = "Invalid card length for "+this.issuer;
  126. }
  127. };
  128. // Constructor method, called at the bottom
  129. this.construct = function(cardNumber){
  130. // Iterate through the card number
  131. cardNumber = String(cardNumber);
  132. var i = cardNumber.length;
  133. var realNumber = ""; //string containing card digits only
  134. var c = 0; //the real card number index
  135. for( y = 0; i > y; y++){
  136. char = cardNumber[y];
  137. if(!isNaN(char)){
  138. realNumber += char;
  139. // Get Industry
  140. if(c === 0){
  141. this.MII = char;
  142. switch(char){
  143. case '0':
  144. this.industry = "ISO/TC 68";
  145. break;
  146. case '1':
  147. case '2':
  148. this.industry = "Airline";
  149. break;
  150. case '3':
  151. this.industry = "Travel/Entertainment";
  152. break;
  153. case '4':
  154. case '5':
  155. this.industry = "Banking/Financial";
  156. break;
  157. case '6':
  158. this.industry = "Merch/Banking";
  159. break;
  160. case '7':
  161. this.industry = "Petroleum";
  162. break;
  163. case '8':
  164. this.industry = "Telecomm";
  165. break;
  166. case '9':
  167. this.industry = "National Assignment";
  168. break;
  169. }
  170. }
  171. c++;
  172. }else{
  173. // check for invalid characters
  174. if(char !== " " && char !== "-"){
  175. this.valid = false;
  176. this.industry = "N/A";
  177. this.error = "Invalid characters (Accepts numbers, spaces, and hyphens only.)";
  178. }
  179.  
  180. }
  181. }
  182. // Validate length
  183. if (realNumber.length > 19 || realNumber.length<12){
  184. this.valid = false;
  185. this.industry = "N/A";
  186. this.error = "Invalid card length";
  187. }
  188. this.digits = realNumber;
  189. this.IIN = realNumber.substring(0, 6);
  190. this.accountNumber = realNumber.substring(6, (realNumber.length - 1));
  191. this.checksum = realNumber.substring((realNumber.length - 1), realNumber.length);
  192. this.getIssuer();
  193. if(this.validation === "Luhn"){
  194. if(this.luhnCheck() === false){
  195. this.valid = false;
  196. this.error = "Failed Luhn Algorithm Check";
  197. }
  198. }
  199. };
  200.  
  201.  
  202. // Initialize the class
  203. this.construct(ccn);
  204. }

Report this snippet  

You need to login to post a comment.