How to Correctly Detect Credit Card Type
How to Correctly Detect Credit Card Type

How to Correctly Detect Credit Card Type

Most merchants do mistakes in detecting the credit card type. There are many credit card type detection libraries available online. But, they don’t have any reference or guide attached to them. Thus, people who are not good with coding can’t use those libraries. In this article, we will tell you about the credit card type detection library and process.We will also discuss the card detection algorithm, data structures and provide you further references.



How to Correctly Detect Credit Card Type

The algorithm uses the first six digit of your card number to check the credit card issuer or card type. Below is usually a simple rule to start with checking the credit card type.

• American Express credit card numbers always start with 3.

• Visa credit card numbers always start with the digit 4.

• Diners Club credit card numbers always start with 3.

• Discover credit card numbers always start with 6.

• JCB credit card numbers always start with 3.

• Master credit card numbers can start from 5 or 2.

How to Correctly Detect Credit Card Type
How to Correctly Detect Credit Card Type

For other credit card issuers, the algorithm is not simple. The second digit of the credit card may depend on the first digit. Most times these digits come from a disjoint number range. Hence, it is difficult to write a general algorithm. These rules can also change if the credit card issuer starts releasing new credit cards. Sometimes credit card companies team up with other banks. Due to this the starting digit of card type changes with time.

By implementing the detection system correctly, your payment form will become more usable. It will become easy for you to process payments. You can remove the card type field from your website. Hence, your website will become smoother. If your website has a great user interface, then card type detection will work better. Your website will immediately tell about the recognized card types. If the card is not supported, then your website will send a negative request. Thus, your customer will get to know that the card is not usable on your website. This will save your customer time because he won’t waste time typing the card details.



Complete Credit Card Type List

Below is the complete list of Card types and its card number prefixes. You can bookmark this page because of its frequent updates:

Issuing NetworkCard Number PrefixStatus
American Express (AmEx)34, 37Active
China T-Union31Active
China UnionPay62, 88Active
Dankort5019Active
Diners Club International (DCI)300-305, 309, 36, 38-39Active
Discover Card6011, 622126-622925, 644-649, 65Active
InterPayment636Active
InstaPayment637-639Active
Japan Credit Bureau (JCB)3528-3589Active
Maestro5018, 5020, 5038, 5612, 5893, 6304, 6759, 6761, 6762, 6763, 0604, 6390Active
MasterCard2221-2720, 51-55Active
RuPay60, 6521, 6522Active
UATP1Active
Verve506099–506198, 650002–650027Active
Visa Electron4026, 417500, 4405, 4508, 4844, 4913, 4917Active
Visa4Active
Bankcard5610, 560221–560225Inactive
enRoute2014, 2149Inactive
Laser6304, 6706, 6771, 6709Inactive
Solo6334, 6767Inactive
Switch4903, 4905, 4911, 4936, 564182, 633110, 6333, 6759Inactive


Part of this list is from this credit card validator. Check it out if you want to validate some credit cards. It is free for now. Feel free to credit back to this page upon using the above recent date. The link as below


https://www.creditcardrush.com/how-to-correctly-detect-credit-card-type/


Bad Credit Card Regular Expressions

Most of the Javascript libraries online only use regular expressions to check the credit card number prefixes. Online tutorials also talk about only regular expressions.These expressions are not good for checking card numbers who have prefixes in number ranges. If you want to include the number ranges also, then the code will become very hard to write. The time complexity of the program will be too much for some old computers. Also, it is difficult to write such large codes and maintain them.Here we have included an example of Javascript code which you can use to detect Discover credit cards. Discover credit cards start with 65, 622126-622925, 6011 and 644-649.


/^(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)/


This code takes too much time when matching the card number with range 644-649 or 622126-622925. These number ranges aremostly represented by character sets in Javascript, eg. /[1-10]/ to match numbers from 1 to 10. The character sets only works for ranges with single digit variations.If you want to compare card number with a range spanning multiple digits like 120-920, you have to divide it into smaller ranges.For example, you should break 120-920 into ranges like 120-129, 130-199, 200-799, 800-899, 900-909, and 910-920. After that, you have to match every rangeindividually. Due to this splitting, the code becomes very hard to write and read.

Due to this problem, many Javascript scripts and libraries don’t include Discover cards in their code. They also skip popular credit card types like MasterCard and Visa. If you are skipping these card types, then your code will shorten to:


/^(6011|65|64[4-9]|622)/


These regular expressions have various limitations. Due to these limitations, it is not easy to detect every card type. You have to write long code which is hard to manage. The code without number ranges looks very clean. Thus, most people copy and paste it without any verification.Due to this, most of the card type detection data structures and algorithms are incomplete, incorrect and outdated.



Better Card Type Detection Mechanism

Better Card Type Detection Mechanism
Better Card Type Detection Mechanism

As we have already discussed before, the card detection algorithm is not very optimized.Instead of using regular expressions, you can use a special data structure known as “inversionMap”. InversionMap is a special data structure which you can check at the Google Closure library. InversionMap is perfect for mapping int (integer) ranges to int values. Thus, this data structure is perfect for the card detection system. You can use the same credit card type detection code with this data structure. The previous code looks like this in the inversionMap data structure:

var cardTypes = {
mastercard: [
[2221, 2720],
[51, 55]
],
visa: [...]
}


You can use this code to check the Mastercard, VISA, etc credit card number ranges. Compared to the previous code, this code is very easy to verify and read. It is very easy to manage this code. You can easily update the number ranges in this code. Sometimes the number ranges of the credit card can change.For example, the number range of the Discover credit cards and China UnionPay got new number range after their partnership. Many old libraries have not updated the new range of Discover credit cards. It is very hard to write and update regular expressions. Thus, most of the coders don’t edit the regular expression codes.

You can easily convert these codes into a complete credit card detection system. All you have to do is combine this code with the inversion map data structure. First, you need to make an empty inversion map. After that, you have to insert individual ranges to your inversion map. You can insert new ranges by the SpliceInversion method. After adding all the ranges in InversionMap, you can query it with card numbers. You need to use at method for making any query.

There is a disadvantage of using inversion map data structure in your code. You need to write more code when compared with the regular expression code. After zipping the whole code the size of the file will be 1.2kB only. For achieving such small size, you can use Google advanced compilation mode which you can find in the Google Closure library. This tool will automatically remove the unreachable code.


Card Type Detection Algorithm without External Library Supports

Card Type Detection Algorithm without External Library Supports
Card Type Detection Algorithm without External Library Supports

By the complete definition of card type table above, you can have a data structure like this


var cardTypeRanges = {
'American Express' : "34,37",
'China T-Union' : "31",
'China UnionPay' : "62,88",
'Dankort' : "5019",
'DCI' : "300-305,309,36,38-39",
'Discover' : "6011,622126-622925,644-649,65",
'InterPayment' : "636",
'InstaPayment' : "637-639",
'JCB' : "3528-3589",
'Maestro' : "5018,5020,5038,5612,5893,6304,6759,6761,6762,6763,0604,6390",
'Mastercard' : "2221-2720,51-55",
'RuPay' : "60,6521,6522",
'UATP' : "1",
'Verve' : "506099-506198,650002-650027",
'Visa' : "4"
};

This cardTypeRanges definition is easy to understand and matches the HTML data table of  card type prefixes above. 

The next step is to get a credit card input. Remove all the white spaces because input may have spaces. And match that input card number against this cardTypeRanges object to find out which card network the input belongs to.  There are many ways to do that. One of the best ways is to transform cardTypeRanges into an array sorted in descending order of ranges of prefixes to compare with the input number. 



What happened of not sorted ? The reason we need to sort it so it matches correctly. For example,  a card numbers starts with 622126 maybe belong to China UnionPay or Discover.  Now if our newly created array is not sorted, the function may compare the input 622126xxx against China UnionPay range definition and return China UnionPay as the result. However, this is wrong because it should Discover as it matches more digits. 

The transformation function to create sortedCardTypeRanges 

var sortedCardTypeRanges = [];
function transform() {
//load sortedCardTypeRanges
for (var key in cardTypeRanges) {
sortedCardTypeRanges.push(cardTypeRanges[key] + '|' + key);
}
//sort sortedCardTypeRanges
for (var i = 0; i < sortedCardTypeRanges.length - 1; i++) {
for (var j = i + 1; j < sortedCardTypeRanges.length; j++) {
var x = sortedCardTypeRanges[i].split('|')[0]; if (x.indexOf('-') > 0) x = x.split('-')[0];
var y = sortedCardTypeRanges[j].split('|')[0]; if (y.indexOf('-') > 0) y = y.split('-')[0];
if (y.length > x.length)
[sortedCardTypeRanges[i], sortedCardTypeRanges[j]]
= [sortedCardTypeRanges[j], sortedCardTypeRanges[i]];
}
}
}

author: Tommy N. @ CreditCardRush

The newly created array should look like this

var sortedCardTypeRanges = [
'650002-650027|Verve',
'622126-622925|Discover',
'506099-506198|Verve',
'31|China T-Union',
...,
'1|UATP'
]

Next we just need to loop through the array above to see if the provided card number matches the prefix range (For Ex: 650002-650027) or one prefix (For Ex: 31). We should break the loop right away upon found and return the network name. To compare with a prefix range, we use greater or equal and smaller or equal comparison, while its just a "contain" or a "indexOf(x) == 0" function for a single prefix match.

The get card type function by comparing the input credit card number with the sorted list we have

//cc: card number input
function getCardType(cc) {
var cardType;
for (var i = 0; i < sortedCardTypeRanges.length - 1; i++) {
var oAr = sortedCardTypeRanges[i].split('|');
if (oAr[0].indexOf('-') > 0) {
var arr = oAr[0].split('-'), tmp = cc.substring(0, arr[0].length);
if (tmp >= arr[0] && tmp <= arr[1]) {
cardType = oAr[1];
break;
}
} else {
if (cc.indexOf(oAr[0]) == 0) {
cardType = oAr[1];
break;
}
}
}
return cardType;
}

author: Tommy N. @ CreditCardRush

Thoughts on "How to Correctly Detect Credit Card Type"

Credit Card Rush is protected by reCAPTCHA and the Google's Privacy Policy and Terms of Service that work.

Something wrong. Try FREE CC Giveaways. Or go to Free Gifts

Disable adblock to see the secrets. Once done, hit refresh button below. Or just try around for fun stuff