13,193,816 members (29,801 online)
Add your own
alternative version

#### Stats

34.3K views
11 bookmarked
Posted 12 May 2009

# Validating Credit Card Numbers

, 12 May 2009
 Rate this:
Please Sign up or sign in to vote.
Some code to process credit card orders.

## Introduction

When using ASP.NET to process online credit card orders, it is a good idea if you can perform some sort of validation on the credit card number before submitting it to your processor. I recently had to write some code to process credit card orders, and thought I’d share a bit of my code.

Fortunately, credit card numbers are created in a way that allows for some basic verification. This verification does not tell you if funds are available on the account, and it certainly doesn’t tell whether or not the person submitting the order is committing credit card fraud. In fact, it’s possible that the card number is mistyped in such a way that it just happens to pass verification. But, it does catch most typing errors, and reduces bandwidth usage by catching those errors before trying to actually process the credit card.

To validate a credit card number, you start by adding the value of every other digit, starting from the right-most digit and working left. Next, you do the same thing with the digits skipped in the first step, but this time you double the value of each digit and add the value of each digit in the result. Finally, you add both totals together, and if the result is evenly divisible by 10, then the card number has passed the validation.

Of course, this would be clearer with a bit of code, and Listing 1 shows my `IsCardNumberValid` method.

```public static bool IsCardNumberValid(string cardNumber)
{
int i, checkSum = 0;

// Compute checksum of every other digit starting from right-most digit
for (i = cardNumber.Length - 1; i >= 0; i -= 2)
checkSum += (cardNumber[i] - '0');

// Now take digits not included in first checksum, multiple by two,
// and compute checksum of resulting digits
for (i = cardNumber.Length - 2; i >= 0; i -= 2)
{
int val = ((cardNumber[i] - '0') * 2);
while (val > 0)
{
checkSum += (val % 10);
val /= 10;
}
}

// Number is valid if sum of both checksums MOD 10 equals 0
return ((checkSum % 10) == 0);
}```
Listing 1: Validating a credit card

The `IsCardNumberValid` method assumes that all spaces and other non-digit characters have been stripped from the card number string. This is a straightforward task, but Listing 2 shows the method I use for this.

```public static string NormalizeCardNumber(string cardNumber)
{
if (cardNumber == null)
cardNumber = String.Empty;

StringBuilder sb = new StringBuilder();

foreach (char c in cardNumber)
{
if (Char.IsDigit(c))
sb.Append(c);
}

return sb.ToString();
}```
Listing 2: Removing all non-digit characters from a credit card number

You will also be able to reduce bandwidth if you can avoid trying to submit a card that is not supported by the business. So, another task that can be useful is determining the credit card type.

```public enum CardType
{
Unknown = 0,
MasterCard = 1,
VISA = 2,
Amex = 3,
Discover = 4,
DinersClub = 5,
JCB = 6,
enRoute = 7
}

// Class to hold credit card type information
private class CardTypeInfo
{
public CardTypeInfo(string regEx, int length, CardType type)
{
RegEx = regEx;
Length = length;
Type = type;
}

public string RegEx { get; set; }
public int Length { get; set; }
public CardType Type { get; set; }
}

// Array of CardTypeInfo objects.
// Used by GetCardType() to identify credit card types.
private static CardTypeInfo[] _cardTypeInfo =
{
new CardTypeInfo("^(51|52|53|54|55)", 16, CardType.MasterCard),
new CardTypeInfo("^(4)", 16, CardType.VISA),
new CardTypeInfo("^(4)", 13, CardType.VISA),
new CardTypeInfo("^(34|37)", 15, CardType.Amex),
new CardTypeInfo("^(6011)", 16, CardType.Discover),
new CardTypeInfo("^(300|301|302|303|304|305|36|38)",
14, CardType.DinersClub),
new CardTypeInfo("^(3)", 16, CardType.JCB),
new CardTypeInfo("^(2131|1800)", 15, CardType.JCB),
new CardTypeInfo("^(2014|2149)", 15, CardType.enRoute),
};

public static CardType GetCardType(string cardNumber)
{
foreach (CardTypeInfo info in _cardTypeInfo)
{
if (cardNumber.Length == info.Length &&
Regex.IsMatch(cardNumber, info.RegEx))
return info.Type;
}

return CardType.Unknown;
}```
Listing 3: Determining a credit card’s type

Listing 3 is my code to determine a credit card’s type. I’m a big fan of table-driven code, when it makes sense, and so I created an array of `CardTypeInfo` objects. The `GetCardType()` method simply loops through this array, looking for the first description that would match the credit card number being tested. As before, this routine assumes all non-digit characters have been removed from the credit card number string.

The main reason I like table-driven code is because it makes the code simpler. This results in code that is easier to read and modify. `GetCardType()` returns a value from the `CardType` enum. `CardType.Unknown` is returned if the card number doesn’t match any card descriptions in the table.

Writing code to process credit cards involves a number of issues that need to be addressed. Hopefully, this code will give you a leg up on addressing a couple of them.

## License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

## About the Author

 Black Belt Coder United States
Jonathan Wood has been a software developer for more years than he cares to admit. His current focus is on using C# and ASP.NET MVC to develop website applications, and C++ and MFC to develop desktop applications. His consulting company, SoftCircuits, is known for producing various commercial and shareware products.

Having an entrepreneurial spirit, Jonathan also has a number of other online businesses that he built from scratch such as Black Belt Coder, SC Web Group and others. He also has expertise in designing brands (including graphics and logos) and search-engine optimization (SEO).

Jonathan is always willing to discuss consulting work or joint ventures with people looking to develop software or online businesses.

## Comments and Discussions

 First Prev Next
 Yuck PIEBALDconsult12-May-09 6:39 PIEBALDconsult 12-May-09 6:39
 Re: Yuck Jonathan Wood3-Jan-17 6:34 Jonathan Wood 3-Jan-17 6:34
 Re: Yuck PIEBALDconsult3-Jan-17 11:54 PIEBALDconsult 3-Jan-17 11:54
 Last Visit: 31-Dec-99 18:00     Last Update: 18-Oct-17 20:03 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.171018.2 | Last Updated 12 May 2009
Article Copyright 2009 by Jonathan Wood
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid