SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Enthusiast
    Join Date
    Jul 2002
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Credit Card valid numbers

    Can anyone offer a routine to check that a credit card number is valid.

    Many thanks
    dbg

  2. #2
    No. Phil.Roberts's Avatar
    Join Date
    May 2001
    Location
    Nottingham, UK
    Posts
    1,142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is the algorithm used within OsCommerce:

    PHP Code:
    <?php
    /**
    * $Id: cc_validation.php,v 1.1 2002/11/01 02:13:21 hpdl Exp $

    * osCommerce, Open Source E-Commerce Solutions
    * [url]http://www.oscommerce.com[/url]

    * Copyright (c) 2002 osCommerce

    * Released under the GNU General Public License
    */

    class cc_validation 
    {
        var 
    $cc_type$cc_number$cc_expiry_month$cc_expiry_year;

        function 
    validate($number$expiry_m$expiry_y)
        {
            
    $this->cc_number ereg_replace('[^0-9]'''$number);

            if (
    ereg('^30[0-5]{1}[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Diners Club';
                return -
    5;
            } elseif (
    ereg('^36[0-9]{2}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Diners Club';
                return -
    5;
            } elseif (
    ereg('^38[0-8]{1}[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Diners Club';
                return -
    5;
            } elseif (
    ereg('^34[0-9]{2}([0-9]{11})?$'$this->cc_number)) {
                
    $this->cc_type 'American Express';
                return -
    5;
            } elseif (
    ereg('^37[0-9]{2}([0-9]{11})?$'$this->cc_number)) {
                
    $this->cc_type 'American Express';
                return -
    5;
            } elseif (
    ereg('^5610([0-9]{12})?$'$this->cc_number)) {
                
    $this->cc_type 'Australian Bankcard';
                return -
    5;
            } elseif (
    ereg('^6011([0-9]{12})?$'$this->cc_number)) {
                
    $this->cc_type 'Discover/Novus';
                return -
    5;
            } elseif (
    ereg('^41373[3-7]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^4462[0-9]{2}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^45397[8-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^454313([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^45443[2-5]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^454742([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^45672[5-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^45673[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^45674[0-5]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^4658[3-7]{1}[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^4659[0-5]{1}[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^4609[6-7]{1}[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^49218[1-2]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^498824([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Delta';
            } elseif (
    ereg('^450875([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Electron';
                return -
    5;
            } elseif (
    ereg('^48440[6-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Electron';
                return -
    5;
            } elseif (
    ereg('^4844[1-4]{1}[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Electron';
                return -
    5;
            } elseif (
    ereg('^48445[0-5]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Electron';
                return -
    5;
            } elseif (
    ereg('^4917[3-5]{1}[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Electron';
                return -
    5;
            } elseif (
    ereg('^491880([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Electron';
                return -
    5;
            } elseif (
    ereg('^5[1-5]{1}[0-9]{14}$'$this->cc_number)) {
                
    $this->cc_type 'MasterCard';
            } elseif (
    ereg('^49030[2-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Switch';
            } elseif (
    ereg('^49033[5-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Switch';
            } elseif (
    ereg('^49110[1-2]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Switch';
            } elseif (
    ereg('^49117[4-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Switch';
            } elseif (
    ereg('^49118[0-2]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Switch';
            } elseif (
    ereg('^4936[0-9]{2}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Switch';
            } elseif (
    ereg('^564182([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Switch';
            } elseif (
    ereg('^6333[1-4]{1}[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Switch';
            } elseif (
    ereg('^6759[0-9]{2}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Switch';
            } elseif (
    ereg('^6334[5-9]{1}[0-9]{1}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Solo';
            } elseif (
    ereg('^6767[0-9]{2}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'UK Solo';
            } elseif (
    ereg('^3528[0-9]{2}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'JCB';
            } elseif (
    ereg('^4[0-4]{1}([0-9]{14})?$'$this->cc_number)) {
                
    $this->cc_type 'JCB';
            } elseif (
    ereg('^45[0-7]{1}([0-9]{13})?$'$this->cc_number)) {
                
    $this->cc_type 'JCB';
            } elseif (
    ereg('^458[0-9]{3}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'JCB';
            } elseif (
    ereg('^5000[0-9]{2}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Maestro';
                return -
    5;
            } elseif (
    ereg('^5[6-8]{1}([0-9]{14})?$'$this->cc_number)) {
                
    $this->cc_type 'Maestro';
                return -
    5;
            } elseif (
    ereg('^6[0-9]{5}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Maestro';
                return -
    5;
            } elseif (
    ereg('^4[0-9]{5}([0-9]{10})?$'$this->cc_number)) {
                
    $this->cc_type 'Visa';
            } else {
                return -
    1;
            } 

            if (
    is_numeric($expiry_m) && ($expiry_m 0) && ($expiry_m 13)) {
                
    $this->cc_expiry_month $expiry_m;
            } else {
                return -
    2;
            } 

            
    $current_year date('Y');
            
    $expiry_y substr($current_year02) . $expiry_y;
            if (
    is_numeric($expiry_y) && ($expiry_y >= $current_year) && ($expiry_y <= ($current_year 10))) {
                
    $this->cc_expiry_year $expiry_y;
            } else {
                return -
    3;
            } 

            if (
    $expiry_y == $current_year) {
                if (
    $expiry_m date('n')) {
                    return -
    4;
                } 
            } 

            return 
    $this->is_valid();
        } 

        function 
    is_valid()
        {
            
    $cardNumber strrev($this->cc_number);
            
    $numSum 0;

            for (
    $i 0$i strlen($cardNumber); $i++) {
                
    $currentNum substr($cardNumber$i1);
                
    // Double every second digit
                
    if ($i == 1) {
                    
    $currentNum *= 2;
                } 
                
    // Add digits of 2-digit numbers together
                
    if ($currentNum 9) {
                    
    $firstNum $currentNum 10;
                    
    $secondNum = ($currentNum $firstNum) / 10;
                    
    $currentNum $firstNum $secondNum;
                } 

                
    $numSum += $currentNum;
            } 
            
    // If the total has no remainder it's OK
            
    return ($numSum 10 == 0);
        } 


    ?>
    Usage:

    PHP Code:
    $cc_validation = new cc_validation();
    $result $cc_validation->validate('*cc number*''*expiry month*''*expiry year*');

    switch (
    $result) {
        case -
    1:
            
    // Unknown card
            
    break;
        case -
    2:
        case -
    3:
        case -
    4:
            
    // Invalid Date
            
    break;
        case -
    5:
            
    // Not accepted
            
    break;
        case 
    false:
            
    // Invalid number
            
    break;


  3. #3
    SitePoint Enthusiast
    Join Date
    Jul 2002
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you Phil
    Just the job!

    dbg

  4. #4
    midnight coder
    Join Date
    Dec 2000
    Location
    The flat edge of the world
    Posts
    838
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here's a more elegant solution, it uses the mod 10 algorithm, which actually tests if the number is a valid credit card number, not simply seeing if the number confines to the rules on each credit card company.

    http://www.sitepoint.com/article/728/1
    Work smarter, not harder. -Scrooge McDuck

  5. #5
    SitePoint Enthusiast
    Join Date
    Jul 2002
    Posts
    73
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you Robo
    My brain was beginning to hurt sorting out how to use Phil's code
    dbg

  6. #6
    No. Phil.Roberts's Avatar
    Join Date
    May 2001
    Location
    Nottingham, UK
    Posts
    1,142
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you'll compare the code I posted with the sitepoint article you'll notice that the code I posted DOES implement the MOD10 algorithm.

  7. #7
    midnight coder
    Join Date
    Dec 2000
    Location
    The flat edge of the world
    Posts
    838
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Heh, I stopped looking at the code after about the 2nd dozen regex
    Work smarter, not harder. -Scrooge McDuck


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •