Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

VISA card wrongly determined as a JCB


TomCavendish

Recommended Posts

Posted

A customer has just sent me an email to say that he entered his VISA card number, and Osc told him that it was a JCB card.

 

We don't take JCB, so he couldn't make an order with us (although he entered a VISA card number).

 

I'm sure that most customers with this problem would not bother to send an email, so the problem could be the same for many Osc sites, and we'd never know about it.

 

The problem seems to be in determining the card type - a VISA wrongly determined as a JCB.

 

Anyone have any thoughts on how we can solve this?

 

Thanks,

 

TC.

  • 2 weeks later...
Posted

The first 6 numbers are 430509. It is coming up as a JCB in OSC but it is a Visa card.

 

I used a Switch card mod (UK) code below. I'm quite sure it didn't change the Visa or JCB parts, but it would help if someone could compare their code with mine below.

 

Please help.

 

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

 osCommerce, Open Source E-Commerce Solutions
 http://www.oscommerce.com

 Copyright (c) 2002 osCommerce

 Released under the GNU General Public License
*/

// start the card recognition and acceptance
	 
 class cc_validation {
   var $cc_type, $cc_number, $cc_expiry_month, $cc_expiry_year;
 
// Remove any non numeric characters.
 function cleancc($number) {
 return ereg_replace('[^0-9]', '', $number);
 }	
 
   function validate($number, $expiry_m, $expiry_y) {
     $this->cc_number = $number;

//  could not get the strip non numerics to work but left the function in and commented out the function call
//	$Number = cc_validation::cleancc($number);	
$Number = $number;

// 4 number and 6 number checks   
$NumberLeft4 = substr($Number, 0, 4);
   $NumberLeft6 = substr($Number, 0, 6);
   $NumberLength = strlen($Number);

if ( strtolower(CC_VAL) == 'true' ) {	
//empty these variables just to be sure
   $ShouldLength2='';
   $ShouldLength3='';	

// Diners Club
   if ( (($NumberLeft4 >= 3000) && ($NumberLeft4 <= 3059))
     || (($NumberLeft4 >= 3600) && ($NumberLeft4 <= 3699))
     || (($NumberLeft4 >= 3800) && ($NumberLeft4 <= 3889)) ) {
   $this->cc_type = 'Diners Club';
   $ShouldLength = 14;
    if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_DINERSCLUB) != 'true' ) {
       return -5;
    	 }
// American Express
     } elseif ( (($NumberLeft4 >= 3400) && ($NumberLeft4 <= 3499))
             || (($NumberLeft4 >= 3700) && ($NumberLeft4 <= 3799)) ) {
       $this->cc_type = 'American Express';
       $ShouldLength = 15;  
  if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_AMERICANEXPRESS) != 'true' ) {
        return -5;
        }
// Carte Blanche
     } elseif ( ($NumberLeft4 >= 3890) && ($NumberLeft4 <= 3899) ) {
       $this->cc_type = 'Carte Blanche';
       $ShouldLength = 14;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_CARTBLANCHE) != 'true' ) {
  return -5;
  }
// Australian Bankcard   
     } elseif ( $NumberLeft4 == 5610 ) {
       $this->cc_type = 'Australian BankCard';
 $ShouldLength = 16;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_OZBANKCARD) != 'true' ) {
     return -5;
  }
// Discover/Novus   
     } elseif ( $NumberLeft4 == 6011 ) {
       $this->cc_type = 'DiscoverNovus';
 $ShouldLength = 16;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_DISCOVERNOVUS) != 'true' ) {
  return -5;
  }
// Delta   
     } elseif ( (($NumberLeft6 >= 413733) && ($NumberLeft6 <= 413737))
           || (($NumberLeft6 >= 446200) && ($NumberLeft6 <= 446299))
           || (($NumberLeft6 >= 453978) && ($NumberLeft6 <= 453979))
           ||  ($NumberLeft6 == 454313)
           || (($NumberLeft6 >= 454432) && ($NumberLeft6 <= 454435))
           ||  ($NumberLeft6 == 454742)
           || (($NumberLeft6 >= 456725) && ($NumberLeft6 <= 456745))
           || (($NumberLeft6 >= 465830) && ($NumberLeft6 <= 465879))
           || (($NumberLeft6 >= 465901) && ($NumberLeft6 <= 465950))
           || (($NumberLeft6 >= 490960) && ($NumberLeft6 <= 490979))
           || (($NumberLeft6 >= 492181) && ($NumberLeft6 <= 492182))
           ||  ($NumberLeft6 == 498824) ) {
       $this->cc_type = 'Delta';
       $ShouldLength = 16;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_DELTA) != 'true' ) {
  return -5;
  }
// Electron   
     } elseif ( ($NumberLeft6 == 450875)
           || (($NumberLeft6 >= 484406) && ($NumberLeft6 <= 484455))
           || (($NumberLeft6 >= 491730) && ($NumberLeft6 <= 491759))
           ||  ($NumberLeft6 == 491880)
            ) {
       $this->cc_type = 'Electron';      
       $ShouldLength = 16;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_ELECTRON) != 'true' ) {
  return -5;
  }
// Mastercard   
     } elseif ( ($NumberLeft6 >= 510000) && ($NumberLeft6 <= 549999) ) {
       $this->cc_type = 'Mastercard';
       $ShouldLength = 16;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_MASTERCARD) != 'true' ) {      
     return -5;
  }
// Switch   
     } elseif ( (($NumberLeft6 >= 490302) && ($NumberLeft6 <= 490309))
           || (($NumberLeft6 >= 490335) && ($NumberLeft6 <= 490339))
           || (($NumberLeft6 >= 491101) && ($NumberLeft6 <= 491102))
           || (($NumberLeft6 >= 491174) && ($NumberLeft6 <= 491182))
           || (($NumberLeft6 >= 493600) && ($NumberLeft6 <= 493699))
           ||  ($NumberLeft6 == 564182)
           || (($NumberLeft6 >= 633300) && ($NumberLeft6 <= 633349))
           || (($NumberLeft6 >= 675900) && ($NumberLeft6 <= 675999)) ) {
       $this->cc_type = 'UK Switch';
       $ShouldLength = 16;
       $ShouldLength2= 18;
       $ShouldLength3= 19;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_SWITCH) != 'true' ) {
  return -5;
  }
// Solo
     } elseif ( (($NumberLeft6 >= 633450) && ($NumberLeft6 <= 633499))
           || (($NumberLeft6 >= 676700) && ($NumberLeft6 <= 676799)) ) {
       $this->cc_type = 'Solo';
       $ShouldLength = 16;
       $ShouldLength2= 18;
       $ShouldLength3= 19;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_SOLO) != 'true' ) {
  return -5;
  }
// JCB
     } elseif ( (($NumberLeft6 >= 352800) && ($NumberLeft6 <= 458999)) ) {
       $this->cc_type = 'JCB';
       $ShouldLength = 16;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_JCB) != 'true' ) {
        return -5;
  }
// Maestro    
     } elseif ( (($NumberLeft6 >= 500000) && ($NumberLeft6 <= 500099))
           || (($NumberLeft6 >= 560000) && ($NumberLeft6 <= 589999))
           || (($NumberLeft6 >= 600000) && ($NumberLeft6 <= 699999)) ) {
       $this->cc_type = 'Maestro';
    $ShouldLength = 16;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_MAESTRO) != 'true' ) {
        return -5;
  }
// Visa   
     } elseif ( (($NumberLeft6 >= 400000) && ($NumberLeft6 <= 499999))
           // ensure we exclude AMT only cards
           && !( (($NumberLeft6 >= 490300) && ($NumberLeft6 <= 490301))
              || (($NumberLeft6 >= 490310) && ($NumberLeft6 <= 490334))
              || (($NumberLeft6 >= 490340) && ($NumberLeft6 <= 490399))
              || (($NumberLeft6 >= 490400) && ($NumberLeft6 <= 490409))
              || ($NumberLeft6 == 490419)
              || ($NumberLeft6 == 490451)
              || ($NumberLeft6 == 490459)
              || ($NumberLeft6 == 490467)
              || (($NumberLeft6 >= 490475) && ($NumberLeft6 <= 490478))
              || (($NumberLeft6 >= 490500) && ($NumberLeft6 <= 490599))
              || (($NumberLeft6 >= 491103) && ($NumberLeft6 <= 491173))
              || (($NumberLeft6 >= 491183) && ($NumberLeft6 <= 491199))
              || (($NumberLeft6 >= 492800) && ($NumberLeft6 <= 492899))
              || (($NumberLeft6 >= 498700) && ($NumberLeft6 <= 498799)) ) ) {
       $this->cc_type = 'Visa';
    $ShouldLength  = 16;
       $ShouldLength2 = 13;
        if ( strtolower(MODULE_PAYMENT_CC_ACCEPT_VISA) != 'true' ) {
        return -5;
  }
     } else {
       return -1;
     }
  
// function to check the number length
// Is the number the right length?
   
  if ( !( ($NumberLength == $ShouldLength)
         || ( !(empty($ShouldLength2)) && ($NumberLength == $ShouldLength2) )
         || ( !(empty($ShouldLength3)) && ($NumberLength == $ShouldLength3) ) ) ) {
         return -6;
        }
} else {
$this->cc_type = 'CC';
}
if ( strtolower(CC_BLACK) == 'true' ) {    
// Blacklist check
   $card_info = tep_db_query("select c.blacklist_card_number from " . TABLE_BLACKLIST . " c where c.blacklist_card_number = '" . $Number . "'");
     if (tep_db_num_rows($card_info) != 0) { // card not found in database
       return -7;
     }
}
// checks the expiry just in case the javascript does not
     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_year, 0, 2) . $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, $i, 1);

// Double every second digit
       if ($i % 2 == 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);
   }
 }
?>

Posted

And I've got another one.

 

A customer tried to order with his Mastercard, but sent me an email to say he got a message saying cards with 5436 are not accepted.

 

The site is in its 2nd month and around half the people who have created accounts have not ordered anything, so I think it could be a widespread problem.

 

Is anyone cleaver enough to work out why these card numbers are being rejected?

 

My head is on the block as I persuaded the company I work for to change from ASP to PHP (Osc). :(

  • 1 year later...
Posted

i had the same problem with mastercard and reverted to the original *mastercard* processing via the admin for the switch contrib. that has worked better but today i got another rejected mastercard complaint so the original isnt perfect either. but 1 complaint is better than many !! havent had probs with visa/jcb tho...

always here to offer some useless advice....

Posted

How are you processing your payments? Are the card details sent to you, for entering manually into a terminal later?

 

If so not many UK banks like it done like this.

 

Why dont you use a proper payment gateway provided by the bank your merchant account is with, or use PSP to process the payments such as Secure Trading?

  • 3 months later...
Posted

I now check barclays merchant account once a month for the latest verification updates, i then modify the verification scripts. this means that cards should all get through. i added my lastest verifications to the switch contribution for everyone to use if they wish.

always here to offer some useless advice....

  • 10 months later...
Posted

Additionally, mastercard seem to be adding new cards but barclays havent updated their bin ranges since january06. for this reason, i have implemented a bit of code that sets the card detection to 'unknown card' if it cannot match the number to a type. The mod10 check should still flush out any bad cards though. Basically genuine cards will all get through but a type may not be detected. put the following code in where the

 

return-1

 

is in the cc_validation file like so:

 

else {

 

/*** CANNOT DETECT CARD TYPE ***/

 

$this->cc_type = 'Unknown Type';

 

// TURN CARD TYPE ERROR DETECTING BACK ON return -1;

 

}

 

 

and and for those of you who are interested, i get the 'latest' bin ranges from here:

http://www.barclaycardmerchantservices.co....f/binranges.pdf

they then have to be incorporated in to the code manually for each card type which can take a while.

always here to offer some useless advice....

  • 1 year later...
Posted

I tried adding this script

 

else {

 

/*** CANNOT DETECT CARD TYPE ***/

 

$this->cc_type = 'Unknown Type';

 

// TURN CARD TYPE ERROR DETECTING BACK ON return -1;

 

}

 

and now I get the following error

 

"The credit card number entered is invalid.<br>Please check the number and try again."

 

Shouldn't this validate all card numbers? :'(

  • 5 months later...

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...