Validating Credit Card Numbers

Lately, I’ve been working on an e–commerce website and discovered a handy algorithm for validating card numbers. The Luhn algorithm (also known as mod 10) is a checksum formula and is used to protect against accidental errors rather than malicious attacks.

The algorithm is particularly useful for checking to see if the card number ‘looks’ right before sending it off to the payment provider for processing. This reduces the amount of rejected card payments, which is always a good thing. :)

More details of how the algorithm works can be found on Wikipedia and my annotated PHP implementation can be found below.

/* PHP function for validating card numbers */
function checkLuhn($cardNumber) {
    // Copyright (c) Richard Warrender. Licenced under the LGPL.
    // https://richardwarrender.com//

    // Get total amount of digits to process
    $digitCount = strlen((String) $cardNumber);
    // Checksum must be zero to begin with
    $checksum = 0;

    // Loop round card number extracting digits
    for($i = 1; $i<=$digitCount; $i++) {
            // Extract digit number
            $digits[$i] = (int) substr($cardNumber, -$i, 1);

            // Check to see if this the luhn number, we need to double it
            if(($i%2) == 0) {
                    // Double luhn digit
                    $digit = $digits[$i] * 2;

                    // If greater or equal to 10, then use sum of digits
                    if($digit >= 10) {
                            // Get first digit
                            $firstDigit = substr($digit, 0, 1);
                            // Get second digit
                            $secondDigit = substr($digit, 1, 1);
                            /// Add together and replace original luhn digit
                            $digit = $firstDigit + $secondDigit;
                    }

                    // Reload back into array
                    $digits[$i] = $digit;
            }
            // Keep a running total for use in checksum
            $checksum += $digits[$i];
    }

    if(($checksum % 10) == 0) {
            return true;
    } else {
            return false;
    }
}