Click here to Skip to main content
Click here to Skip to main content
 
Add your own
alternative version

Ultimate .NET Credit Card Utility Class

, 29 Aug 2007 CPOL
A powerfully simple .NET utility class for validating and testing credit card numbers in C# and VB.
UltimateCreditCardUtilityCS_src.zip
CredCardUtilityTestsCS
CreditCardUtilityTests
bin
Debug
CreditCardUtility.dll
CreditCardUtilityTest.dll
nunit.framework.dll
CreditCardUtilityTests.csproj.user
Properties
CreditCardTestSiteCS
Bin
CreditCardUtility.dll
RadAjax.Net2.dll
RadInput.Net2.dll
images
innerBkgnd.png
loading4.gif
pageBkgn.jpg
UltimateCreditCardUtility.gif
CreditCardUtilityCS
bin
Debug
CreditCardUtility.dll
CreditCardUtility.csproj.user
Properties
UltimateCreditCardUtilityVB_src.zip
CreditCardTestSiteVB
Bin
CreditCardUtility.dll
RadAjax.Net2.dll
RadInput.Net2.dll
images
innerBkgnd.png
loading4.gif
pageBkgn.jpg
UltimateCreditCardUtility.gif
CreditCardUtilityTestsVB
CreditCardUtilityTests
bin
Debug
CreditCardUtility.dll
CreditCardUtilityTests.dll
nunit.framework.dll
CreditCardUtilityTests.vbproj.user
My Project
Application.myapp
Settings.settings
CreditCardUtilityVB
CreditCardUtility
bin
Debug
CreditCardUtility.dll
CreditCardUtility.pdb
My Project
Application.myapp
Settings.settings
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;

namespace Bluelaser.Utilities
{
    public class CreditCardUtility
    {
        //=========================================================================
        // CreditCardUtility Change Log
        //
        // Date             Developer       Description
        // 30 Aug 2007      T. Anglin       Changed test credit card numbers returned
        //                                  by GetCardTestNumber to match PayPal
        //                                  issued test numbers.
        //=========================================================================

        private const string cardRegex = "^(?:(?<Visa>4\\d{3})|(?<MasterCard>5[1-5]\\d{2})|(?<Discover>6011)|(?<DinersClub>(?:3[68]\\d{2})|(?:30[0-5]\\d))|(?<Amex>3[47]\\d{2}))([ -]?)(?(DinersClub)(?:\\d{6}\\1\\d{4})|(?(Amex)(?:\\d{6}\\1\\d{5})|(?:\\d{4}\\1\\d{4}\\1\\d{4})))$";

        public static bool IsValidNumber(string cardNum)
        {
            Regex cardTest = new Regex(cardRegex);

            //Determine the card type based on the number
            CreditCardTypeType? cardType = GetCardTypeFromNumber(cardNum);

            //Call the base version of IsValidNumber and pass the 
            //number and card type
            if (IsValidNumber(cardNum, cardType))
                return true;
            else
                return false;
        }

        public static bool IsValidNumber(string cardNum, CreditCardTypeType? cardType)
        {
            //Create new instance of Regex comparer with our 
            //credit card regex pattern
            Regex cardTest = new Regex(cardRegex);

            //Make sure the supplied number matches the supplied
            //card type
            if (cardTest.Match(cardNum).Groups[cardType.ToString()].Success)
            {
                //If the card type matches the number, then run it
                //through Luhn's test to make sure the number appears correct
                if (PassesLuhnTest(cardNum))
                    return true;
                else
                    //The card fails Luhn's test
                    return false;
            }
            else
                //The card number does not match the card type
                return false;
        }

        public static CreditCardTypeType? GetCardTypeFromNumber(string cardNum)
        {
            //Create new instance of Regex comparer with our
            //credit card regex pattern
            Regex cardTest = new Regex(cardRegex);

            //Compare the supplied card number with the regex
            //pattern and get reference regex named groups
            GroupCollection gc = cardTest.Match(cardNum).Groups;
           
            //Compare each card type to the named groups to 
            //determine which card type the number matches
            if (gc[CreditCardTypeType.Amex.ToString()].Success)
            {
                return CreditCardTypeType.Amex;
            }
            else if (gc[CreditCardTypeType.MasterCard.ToString()].Success)
            {
                return CreditCardTypeType.MasterCard;
            }
            else if (gc[CreditCardTypeType.Visa.ToString()].Success)
            {
                return CreditCardTypeType.Visa;
            }
            else if (gc[CreditCardTypeType.Discover.ToString()].Success)
            {
                return CreditCardTypeType.Discover;
            }
            else
            {
                //Card type is not supported by our system, return null
                //(You can modify this code to support more (or less)
                // card types as it pertains to your application)
                return null;
            }
        }

        public static string GetCardTestNumber(CreditCardTypeType cardType)
        {
            //According to PayPal, the valid test numbers that should be used
            //for testing card transactions are:
            //Credit Card Type              Credit Card Number
            //American Express              378282246310005
            //American Express              371449635398431
            //American Express Corporate    378734493671000
            //Diners Club                   30569309025904
            //Diners Club                   38520000023237
            //Discover                      6011111111111117
            //Discover                      6011000990139424
            //MasterCard                    5555555555554444
            //MasterCard                    5105105105105100
            //Visa                          4111111111111111
            //Visa                          4012888888881881
            //Src: https://www.paypal.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
            //Credit: Scott Dorman, http://www.geekswithblogs.net/sdorman

            //Return bogus CC number that passes Luhn and format tests
            switch (cardType)
            {
                case CreditCardTypeType.Amex:
                    return "3782 822463 10005";
                case CreditCardTypeType.Discover:
                    return "6011 1111 1111 1117";
                case CreditCardTypeType.MasterCard:
                    return "5105 1051 0510 5100";
                case CreditCardTypeType.Visa:
                    return "4111 1111 1111 1111";
                default:
                    return null;
            }
        }

        public static bool PassesLuhnTest(string cardNumber)
        {
            //Clean the card number- remove dashes and spaces
            cardNumber = cardNumber.Replace("-", "").Replace(" ", "");
            
            //Convert card number into digits array
            int[] digits = new int[cardNumber.Length];
            for (int len = 0; len < cardNumber.Length; len++)
            {
                digits[len] = Int32.Parse(cardNumber.Substring(len, 1));
            }

            //Luhn Algorithm
            //Adapted from code availabe on Wikipedia at
            //http://en.wikipedia.org/wiki/Luhn_algorithm
            int sum = 0;
            bool alt = false;
            for (int i = digits.Length - 1; i >= 0; i--)
            {
                int curDigit = digits[i];
                if (alt)
                {
                    curDigit *= 2;
                    if (curDigit > 9)
                    {
                        curDigit -= 9;
                    }
                }
                sum += curDigit;
                alt = !alt;
            }

            //If Mod 10 equals 0, the number is good and this will return true
            return sum % 10 == 0;
        }
    }

    /// <summary>
    /// CreditCardTypeType copied for PayPal WebPayment Pro API
    /// (If you use the PayPal API, you do not need this definition)
    /// </summary>
    public enum CreditCardTypeType
    {
        Visa,
        MasterCard,
        Discover,
        Amex,
        Switch,
        Solo
    }

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

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

Share

About the Author

BlueLaser05
Web Developer
United States United States
Todd Anglin is an Experts Exchange ASP.NET Master and a Telerik Technical Evangelist responsible for building a strong Telerik community across the globe. Before joining Telerik, Todd worked as a developer in a Fortune 200 financial services company in San Antonio as a Systems Analyst supporting applications on a wide range of platforms and technologies, including Unix, Windows Server, Informix, Oracle, and SQL Server. Todd graduated Magna Cum Laude with Business Honors from Mays Business School at Texas A&M University with a BBA in MIS and now resides with his wife in The Woodlands, Texas.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141216.1 | Last Updated 29 Aug 2007
Article Copyright 2007 by BlueLaser05
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid