Title:       Credit Card Functions
Author:      Anthony Main
Email:       anthony.main@webdynamix.biz
Environment: c#
Keywords:    credit card, validation, luhn, card type, visa, mastercard, solo, switch, maestro
Level:       Intermediate
Description: Various methods for validating credit card details
Section      .NET
SubSection   General

WDX - C# Credit Card Valudation Functions

Introduction

Here is my Payment class for doing basic credit/debit card validation checks in c#. Includes the following functions:

Background

The LUHN check was taken from another example, however I do not remember where to give credit please let me know if you find it elsewhere so I can give credit.

The Card Type lookup is fairly rudamentory. It follows some simple rules as found in Wikipedia for identifying card type. These are not exhaustive and may not always be valid as there is no defined standard, but they will give a fairly accurate lookup facility for checking against a user submitted type.

Using the code

The class contains two static methods which can be called from your routines to aid with your validation, all you need to do is pass in the card number.

LUHN Check

        public static bool IsLUHNValid(string ccNo)
        {
            bool isValid = false;
            int indicator = 1; // will be indicator for every other number
            int firstNumToAdd = 0; // will be used to store sum of first set of numbers
            int secondNumToAdd = 0; // will be used to store second set of numbers
            string num1; // will be used if every other number added is greater than 10, store the left-most integer here
            string num2; // will be used if ever yother number added is greater than 10, store the right-most integer here

            // Convert our creditNo string to a char array
            char[] ccArr = ccNo.ToCharArray();

            if (IsNumeric(ccNo))
            {
                for (int i=ccArr.Length-1;i>=0;i--)
                {
                    char ccNoAdd = ccArr[i];
                    int ccAdd = Int32.Parse(ccNoAdd.ToString());
                    if (indicator == 1)
                    {
                        // If we are on the odd number of numbers, add that number to our total
                        firstNumToAdd += ccAdd;
                        // set our indicator to 0 so that our code will know to skip to the next piece
                        indicator = 0;
                    }
                    else
                    {
                        // if the current integer doubled is greater than 10
                        // split the sum in to two integers and add them together
                        // we then add it to our total here
                        if ((ccAdd + ccAdd) >= 10)
                        {
                            int temporary = (ccAdd + ccAdd);
                            num1 = temporary.ToString().Substring(0,1);
                            num2 = temporary.ToString().Substring(1,1);
                            secondNumToAdd += (Convert.ToInt32(num1) + Convert.ToInt32(num2));
                        }
                        else
                        {
                            // otherwise, just add them together and add them to our total
                            secondNumToAdd += ccAdd + ccAdd;
                        }
                        // set our indicator to 1 so for the next integer we will perform a different set of code
                        indicator = 1;
                    }
                }
                // If the sum of our 2 numbers is divisible by 10, then the card is valid. Otherwise, it is not
                if ((firstNumToAdd + secondNumToAdd) % 10 == 0)
                {
                    isValid = true;
                }
                else
                {
                    isValid = false;
                }
            }
            else
                isValid = false;

            return isValid;
        }

Get Card Type

        public enum CardType
        {
            Invalid,
            Unknown,
            AmericanExpress,
            Bankcard,
            DinersClubInternational,
            DinersClubUSandCanada,
            DiscoverCard,
            JCB,
            Maestro,
            MasterCard,
            SoloDebit,
            SwitchDebit,
            Visa,
            VisaElectron,
            enRoute
        }

        public static CardType GetCardType(string strCardNumber)
        {
            strCardNumber = strCardNumber.Replace(" ", "");

            // Check American Express
            if (strCardNumber.Substring(0, 2)=="34" || strCardNumber.Substring(0, 2)=="37")
            {
                if (strCardNumber.Length==15)
                    return CardType.AmericanExpress;
                else
                    return CardType.Invalid;
            }

            // Check Bankcard
            if (strCardNumber.Substring(0, 3).ToUpper == "DNE") return CardType.Bankcard;

            // Check Diners Club Internationl
            if (strCardNumber.Substring(0, 2).ToUpper == "36" || strCardNumber.Substring(0, 2).ToUpper == "38" || (Convert.ToInt32(strCardNumber.Substring(0, 3)) >= 300 && Convert.ToInt32(strCardNumber.Substring(0, 3)) <= 305))
                if (strCardNumber.Length==14)
                    return CardType.DinersClubInternational;
                else
                    return CardType.Invalid;

            // Check Diners Club US and Canadaa
            if (strCardNumber.Substring(0, 2).ToUpper == "55") return CardType.DinersClubUSandCanada;

            // Check Discover Card
            if (strCardNumber.Substring(0, 4).ToUpper == "6011")
                if (strCardNumber.Length==16)
                    return CardType.Bankcard;
                 else
                    return CardType.Invalid;

            // Check JCB Card
            if (strCardNumber.Substring(0, 4).ToUpper == "2131" || trCardNumber.Substring(0, 4).ToUpper == "1800" )
                if (strCardNumber.Length==15)
                    return CardType.JCB;
                else
                    return CardType.Invalid;

            // Check Maestro Card
            if (strCardNumber.Substring(0, 4).ToUpper == "5020")
                if (strCardNumber.Length==16)
                    return CardType.Maestro;
                else
                    return CardType.Invalid;

            // Check MasterCard
            if ((Convert.ToInt32(strCardNumber.Substring(0, 3)) >= 51 && Convert.ToInt32(strCardNumber.Substring(0, 3)) <= 55))
                if (strCardNumber.Length==16)
                    return CardType.MasterCard;
                else
                    return CardType.Invalid;

            // Check Solo Card
            if (strCardNumber.Substring(0, 2).ToUpper == "63" || strCardNumber.Substring(0, 4).ToUpper == "6767")
                if (strCardNumber.Length==16 || strCardNumber.Length==18 || strCardNumber.Length==19)
                    return CardType.SoloDebit;
                else
                    return CardType.Invalid;

            // Check Switch Card
            if (strCardNumber.Substring(0, 4).ToUpper == "4903" || strCardNumber.Substring(0, 4).ToUpper == "4905" || strCardNumber.Substring(0, 4).ToUpper == "4911" || strCardNumber.Substring(0, 4).ToUpper == "4936" || strCardNumber.Substring(0, 6).ToUpper == "564182" || strCardNumber.Substring(0, 6).ToUpper == "633110" || strCardNumber.Substring(0, 4).ToUpper == "6333" || strCardNumber.Substring(0, 4).ToUpper == "6759")
                if (strCardNumber.Length==16 || strCardNumber.Length==18 || strCardNumber.Length==19)
                    return CardType.SwitchDebit;
                else
                    return CardType.Invalid;

            // Check Visa Electron Card
            if (strCardNumber.Substring(0, 6).ToUpper == "417500")
                if (strCardNumber.Length==16)
                    return CardType.VisaElectron;
                else
                    return CardType.Invalid;

            // Check Visa Card
            if (strCardNumber.Substring(0, 1).ToUpper == "4")
                if (strCardNumber.Length==16)
                    return CardType.Visa;
                else
                    return CardType.Invalid;

            // Check enRoute Card
            if (strCardNumber.Substring(0, 4).ToUpper == "2014" || strCardNumber.Substring(0, 4).ToUpper == "2149")
                if (strCardNumber.Length==15)
                    return CardType.enRoute;
                else
                    return CardType.Invalid;

            return CardType.Unknown;

        }
	}

History

1.0 - 22 August 2006 - Checks are appropriate to prefixes dicated on Wikipedia on this date