Tuesday 10 March 2015

Credit Card validation regex script in PHP using Luhn algorithm


Credit card validation is essential for e-commerce websites. Credit card numbers entered by users will not be necessarily correct always. The credit card payment processing companies (visa,mastercard) charge merchandise for each transaction carried out. This also includes the failed transactions. Therefore it becomes essential to validate the credit card number before sending it to the payment gateways. The unique credit card numbers are generated by the issuing banks using "Luhn formula". This tutorial explains how to validate the credit card number entered by user and get the name of the payment network (visa, mastercard etc..) of the credit card. There are different formats for the credit card numbers allotted by the payment networks. The various payment networks and their credit card number formats are given below.


# Visa : 16 digit for new and 13 digit number for old cards. Number starts with 4
# Mastercard : 16 digit number starting with 51 through 55
# America Express (Amex) : 15 digit number starting with 34 or 37
# Maestro : 12, 16 or 19 digit number with prefixes, including 50, 56-58, 67,6304 or 6390.
# Discover : 16 digit number beginning with 6011 or 65
# JCB : 16 digit number starting with 35 or 15 digit number starting with 2131,1800
Luhn algorithm is used to generate credit card numbers by the banks. This formula is only used for distinguishing specific numbers from random numbers. This eliminates the accidental errors by users while providing the credit card number. To validate credit card number; we will proceed with two steps.

1. Check if the credit card number is valid using Luhn algorithm The following function returns whether the credit card number is valid or not using Luhn formula.
function is_valid_card($number)
{
    // Remove Spaces and hyphens for some credit cards
    $number=preg_replace('/\D/', '', $number);
 
    // Set the string length and parity
    $number_length=strlen($number);
    $parity=$number_length % 2;    
    // Apply Luhn's algorthm for the number
    $total=0;
    for ($i=0; $i<$number_length; $i++)
    {
        $digit=$number[$i];
        if ($i % 2 == $parity)
        {
            $digit*=2;
            // If the sum is two digits, add them together (in effect)
            if ($digit > 9)
            {
                $digit-=9;
            }
        }
        // Add all the digits
        $total+=$digit;
    }
    // If the modulo 10 equals 0, then number is valid
    if($total % 10 == 0)
    {  
        //if card is valid; identify the card company
        return validateCard($number);
    }    
    else
        return "Invalid Card";
}

2. Identify the payment network using regular expression
function validateCard($number, $extra_check = false){
    $cards = array(
        "visa" => "(4\d{12}(?:\d{3})?)",
        "mastercard" => "(5[1-5]\d{14})",
        "amex" => "(3[47]\d{13})",
        "maestro" => "((?:5020|5038|6304|6579|6761)\d{12}(?:\d\d)?)",
        "dinersclub" => "(3(?:0[0-5]|[68][0-9])[0-9]{11})",
        "discover" => "(6(?:011|5[0-9]{2})[0-9]{12})",
        "jcb" => "(35[2-8][89]\d\d\d{10})",
    );
    $names = array("Visa", "Mastercard", "American Express", "Maestro", "Diners Club", "Discover", "JCB");
    $matches = array();
    $pattern = "#^(?:".implode("|", $cards).")$#";
    $result = preg_match($pattern, str_replace(" ", "", $number), $matches);
    if($extra_check && $result > 0){
        $result = (validateCard($number))?1:0;
    }
    if($result==0)
       return "Invalid Card";    
    else
    return ($result>0)?$names[sizeof($matches)-2]:false;
}

The Credit card number is supplied to ‘is_valid_card()’ function as an argument. If the card is valid, then validateCard() function is internally called which returns the name of the payment network.

No comments:

Post a Comment