Auto-detecting Credit Card Type

There was a time when people thought the internet required a completely different payment method than the real world. After a very short period of time, everyone came to realize that credit cards were actually quite well-suited to the web, and so the credit card form was born. You’ve probably seen such form frequently and always with the same fields:

  1. Your name
  2. Credit card type
  3. Credit card number
  4. Expiration date

Recently, I’ve come across several sites who have done away with the credit card type field. Both Amazon and GitHub don’t require you to select a credit card type in their form. As you fill in the credit card number, the user interface changes to show the type of credit card being used.

Amazon waits until the entire credit card number is entered and then displays an icon representing the credit card type.

Amazon’s Credit Card Detection

GitHub updates the interface a bit faster, waiting until it has enough information to figure out the credit card type. Initially, there are several credit card icons showing. Once the actual credit card type is determined, all of the icons fade except the one representing the credit card type.

GitHub’s Credit Card Detection

This credit card type detection is a nice addition to the standard payment form because it frees up the user from entering what is actually redundant information. It’s trivial to determine the type of credit card being used once you understand how credit card numbers work.

What’s in a Credit Card Number?

Despite looking somewhat random, credit card numbers are actually governed by strict conventions. There is a standard called ISO/IEC 7812 that specifies the format for identification numbers on credit cards as well as other card-based identification numbers. The entire identification number is separated into three parts:

  1. Issuer Identification Number (IIN). The IIN is the first four to six digits of the overall identification number and it represents the company that issued the card. In the case of credit cards, the IIN represents the issuing bank.
  2. Account Number. The next few numbers are your personal identification number. For credit cards, this is your account number.
  3. Check Digit. The very last digit is used to verify the overall validity of the identification number. Calculations are used with the preceding numbers to determine that the number format is correct.

Consider the sample MasterCard number 5555-5555-5555-4444 (don’t worry, all banks have sample credit card numbers you can use for testing purposes). The first four digits, 5555, is the IIN representing the fake bank issuing the MasterCard. The numbers 5555-5555-444 are the individual account number and the last 4 is the check digit.

Detecting Credit Card Type

The interesting thing about the IIN is that it also determines the type of credit card. Here are some common IIN patterns:

  • MasterCard IINs have the first two digts in the range 51-55
  • Visa IINs always begin with a 4
  • American Expression IINs always begin with 34 or 37

Knowing this, it’s possible to write a simple JavaScript function to determine the type of credit card given an account number.

function getCreditCardType(accountNumber)
{ //start without knowing the credit card type var result = "unknown"; //first check for MasterCard if (/^5[1-5]/.test(accountNumber)) { result = "mastercard"; } //then check for Visa else if (/^4/.test(accountNumber)) { result = "visa"; } //then check for AmEx else if (/^3[47]/.test(accountNumber)) { result = "amex"; } return result; }

This function makes extensive use of regular expressions to verify the credit card type. The accountNumber argument should be a string (the same as the value of the text input field you’ll be evaluating). You can use getCreditCardType() like this:

var type = getCreditCardType("5555-5555-5555-4444");

switch (type)
{
  case "mastercard":
    //show MasterCard icon
    break;

  case "visa":
    //show Visa icon
    break;

  case "amex":
    //show American Express icon
    break;

  default:
    //don't do anything
}

Keep in mind that the getCreditCardType() function looks at only the first few digits, and so works both when there are dashes in the account number and when there are not.

The only thing left to do is tie this functionality into a form. To do so, listen for both the keyup and blur events. You need to listen to both because users will either type their credit card number or will paste it in. In the latter case, keyup will never fire and you won’t get the credit card detection.

function handleEvent(event)
{
  var value   = event.target.value,    
      type    = getCreditCardType(value);

  switch (type)
  {
    case "mastercard":
        //show MasterCard icon
        break;

    case "visa":
        //show Visa icon
        break;

    case "amex":
        //show American Express icon
        break;

    default:
        //clear all icons?
        //show error?
  }
}

// or window.onload
document.addEventListener("DOMContentLoaded", function(){
  var textbox = document.getElementById("cc-num");
  textbox.addEventListener("keyup", handleEvent, false);
  textbox.addEventListener("blur", handleEvent, false);
}, false);

This code assumes a textbox with an ID of cc-num exists on the page. Using the DOM Level 2 addEventListener() method, a DOMContentLoaded event handler sets up the rest of the event handlers for the page. In a full web application, you would include this code wherever you initialize other event handlers. The keyup and blur events are assigned to call handleEvent(). Inside of handleEvent(), the current value of the textbox is retrieved via event.target.value and passed to the getCreditCardType() function. Once the type is determined, appropriate changes to the user interface are made.

What About Security?

Client-side validation is designed as a convenience to the user, not as a security precaution for your system. Auto-detecting the credit card type in this manner gives no indication as to whether or not the credit card number as a whole is valid. The server should be both auto-detecting the credit card type using the same algorithm as well as validating whether or not the credit card number is valid. Merchant systems typically do both of these checks for you.

Another aspect to keep in mind: if you’re not auto-detecting all credit card types that you accept, be sure to have a way for the user to specify the card type. Amazon displays a dropdown box of available credit card types if it fails to determine the type by looking at the credit card number alone. GitHub, on the other hand, auto-detects all credit card types that it accepts.

Simpler Forms = Faster Checkout

It’s a widely-accepted principle that simpler forms are better forms. Anytime you can make a form easier to fill out, you should definitely take the opportunity to do so. In the case of credit cards, we’ve been asking users to provide redundant information for so long that we tend to accept the status quo. Amazon and GitHub are definitely first-movers in this area, but I expect to see more sites adopt auto-detecting of credit card types in their forms.

Going the Extra Mile

While it’s helpful to identify the type of credit card being used, and in turn eliminating one form field, it’s even more helpful to verify that the entire credit card number is valid before submitting the form. Most credit card numbers can be validated using Luhn algorithm. Luhn algorithm can be very easily implemented in Javascript, allowing you to verify the credit card number format in the browser. Keep in mind that this doesn’t ensure that the credit card is valid for use, only that the number does, in fact, represent a valid credit card number.

Pitfalls to Avoid

  • Don’t forget that determining the type of credit card is not the same as validating the credit card. The IIN may be valid while the rest of the number is bogus.
  • Don’t ever rely purely on JavaScript to validation sensitive information such as credit card numbers. You must always have validation on the server as well.
  • If you’re only accepting a few credit card types, make sure that’s obvious in the user interface.
  • Don’t save the auto-detected credit card type to a form field for submission to the server.

Things to Do

  • Apply the same logic for detecting credit card type on the server.
  • If there’s a credit card type you’re not auto-detecting, be sure to provide some way for the user to specify the type manually. Amazon does this by showing a dropdown of available credit card types if it can’t auto-detect.

Further Reading