פונקציה בPHP לאימות כרטיס אשראי
-
כרטיס אשראי בנוי להיות מאומת ע"י אלגוריתם לוהן.
אז לא צריך אימות דוקא לכרטיס אשראי צריך פוקנציה לאימות מספר שבנוי לפי האלגוריתם זה.
תבדוק את הקוד הבא, שלקחתי מפה: http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#PHP$numbers = "49927398716 49927398717 1234567812345678 1234567812345670"; foreach (explode (' ', $numbers) as $n) echo "$n is ", luhnTest($n) ? 'valid' : 'not valid', '</br>'; function luhnTest($num) { $sum = 0; $len = strlen($num); for ($i = $len-1; $i >= 0; $i--) { $ord = ord($num[$i]); if (($len - 1) & $i) { $sum += $ord; } else { $sum += $ord / 5 + (2 * $ord) % 10; } } return $sum % 10 == 0; }
-
ראיתי את זה, אבל אני מבין שיש עוד משהו
הרגע מצאתי את האתר הזה נראה לי שזה הפיתרון
https://www.codeguru.com/cpp/i-n/internet/security/article.php/c15307/PHP-Tip-Validating-a-Credit-Card.htm
תודה רבה -
@שואף כמובן שזה אפשרי. יש כמה סוגי עיסקאות.
יש אפשרות לשמור לך מסגרת ואז לשחרר אותה בסוף. וכו.
פעם עבדתי עם טרנזילה, מאמין שיש את זה בכל הgetways של סליקת אשראי.לגבי השאלה הראשונה, פעם סידרתי לעצמי קוד ב JS בשביל לבדוק את כל סוגי הכרטיסים, כולל כרטיסים בארץ (שלהם זה אלגוריתם שונה).
יש גם אפשרות לדעת לפי מספר הכרטיס לאיזה חברה הוא שייך (יש תחיליות וכמה כללים בזה) -
מצ"ב מחלקה שמצאתי וערכתי אותה לאימות כרטיס אשראי של ישראכרד מקומי, שהוא אלוגריתם אחר מהשאר.
/** * Validates popular debit and credit cards numbers against regular expressions and Luhn algorithm. * Also validates the CVC and the expiration date. * * @author Ignacio de Tomás <nacho@inacho.es> * @copyright 2014 Ignacio de Tomás (http://inacho.es) */ // $CreditCard1 = new CreditCard(); //$card = CreditCard::validCreditCard('5500005555555559', 'mastercard'); //$card = CreditCard::validCreditCard('123456789'); //print_r($card); //$validCvc = CreditCard::validCvc('001', 'visa'); //var_dump($validCvc); //$validDate = CreditCard::validDate('30', '01'); // past date //var_dump($validDate); //$validDate = CreditCard::validDate0('0218'); // past date //var_dump($validDate); //namespace Inacho; class CreditCard { protected static $cards = array( // Debit cards must come first, since they have more specific patterns than their credit-card equivalents. 'mastercard' => array( 'type' => 'mastercard', 'pattern' => '/^(5[0-5]|2[2-7])/', 'length' => array(16), 'cvcLength' => array(3), 'luhn' => true, ), 'visa' => array( 'type' => 'visa', 'pattern' => '/^4/', 'length' => array(13, 16), 'cvcLength' => array(3), 'luhn' => true, ), 'israrcard' => array( 'type' => 'israrcard', 'pattern' => '/^[0-9]/', 'length' => array(8,9), 'cvcLength' => array(3), 'luhn' => true, ), 'amex' => array( 'type' => 'amex', 'pattern' => '/^3[47]/', 'format' => '/(\d{1,4})(\d{1,6})?(\d{1,5})?/', 'length' => array(15), 'cvcLength' => array(3, 4), 'luhn' => true, ), 'dinersclub' => array( 'type' => 'dinersclub', 'pattern' => '/^3[0689]/', 'length' => array(14), 'cvcLength' => array(3), 'luhn' => true, ), 'visaelectron' => array( 'type' => 'visaelectron', 'pattern' => '/^4(026|17500|405|508|844|91[37])/', 'length' => array(16), 'cvcLength' => array(3), 'luhn' => true, ), /* 'maestro' => array( 'type' => 'maestro', 'pattern' => '/^(5(018|0[23]|[68])|6(39|7))/', 'length' => array(12, 13, 14, 15, 16, 17, 18, 19), 'cvcLength' => array(3), 'luhn' => true, ), 'forbrugsforeningen' => array( 'type' => 'forbrugsforeningen', 'pattern' => '/^600/', 'length' => array(16), 'cvcLength' => array(3), 'luhn' => true, ), 'dankort' => array( 'type' => 'dankort', 'pattern' => '/^5019/', 'length' => array(16), 'cvcLength' => array(3), 'luhn' => true, ), // Credit cards 'discover' => array( 'type' => 'discover', 'pattern' => '/^6([045]|22)/', 'length' => array(16), 'cvcLength' => array(3), 'luhn' => true, ), 'unionpay' => array( 'type' => 'unionpay', 'pattern' => '/^(62|88)/', 'length' => array(16, 17, 18, 19), 'cvcLength' => array(3), 'luhn' => false, ), 'jcb' => array( 'type' => 'jcb', 'pattern' => '/^35/', 'length' => array(16), 'cvcLength' => array(3), 'luhn' => true, ), */ ); public static function validCreditCard($number, $type = null) { $ret = array( 'valid' => false, 'number' => '', 'type' => '', ); // Strip non-numeric characters $number = preg_replace('/[^0-9]/', '', $number); if (empty($type)) { $type = self::creditCardType($number); } if (array_key_exists($type, self::$cards) && self::validCard($number, $type)) { return array( 'valid' => true, 'number' => $number, 'type' => $type, ); } return $ret; } public static function validCvc($cvc, $type) { return (ctype_digit($cvc) && array_key_exists($type, self::$cards) && self::validCvcLength($cvc, $type)); } public static function validDate0($monthyear) { if (strlen($monthyear)!=4) return false; // print $monthyear; $month = mb_substr($monthyear, 0, 2); $year = mb_substr($monthyear, 2, 2); if (self::validDate($year, $month)) return true; else return false; } public static function validDate($year, $month) { $year = '20'.$year; $month = str_pad($month, 2, '0', STR_PAD_LEFT); if (! preg_match('/^20\d\d$/', $year)) { return false; } if (! preg_match('/^(0[1-9]|1[0-2])$/', $month)) { return false; } // past date if ($year < date('Y') || $year == date('Y') && $month < date('m')) { return false; } return true; } public static function ValidateID($str) { $IDnum = strval($str); if(! ctype_digit($IDnum)) return false; if((strlen($IDnum)>9) || (strlen($IDnum)<5)) return false; while(strlen($IDnum)<9) { $IDnum = '0'.$IDnum ; } $mone = 0; for($i=0; $i<9; $i++) { $char = mb_substr($IDnum, $i, 1); $incNum = intval($char); $incNum*=($i%2)+1; if($incNum > 9) $incNum-=9; $mone+= $incNum; } if($mone%10==0) return true; else return false; } // PROTECTED // --------------------------------------------------------- protected static function creditCardType($number) { foreach (self::$cards as $type => $card) { if (preg_match($card['pattern'], $number) && self::validLength($number, $type)) { return $type; } } return ''; } protected static function validCard($number, $type) { return (self::validPattern($number, $type) && self::validLength($number, $type) && self::validLuhn($number, $type)); } protected static function validPattern($number, $type) { return preg_match(self::$cards[$type]['pattern'], $number); } protected static function validLength($number, $type) { foreach (self::$cards[$type]['length'] as $length) { if (strlen($number) == $length) { return true; } } return false; } protected static function validCvcLength($cvc, $type) { foreach (self::$cards[$type]['cvcLength'] as $length) { if (strlen($cvc) == $length) { return true; } } return false; } protected static function validLuhn($number, $type) { if (! self::$cards[$type]['luhn']) { return true; } else { return self::luhnCheck($number); } } protected static function luhnCheck($number) { $checksum = 0; for ($i=(2-(strlen($number) % 2)); $i<=strlen($number); $i+=2) { // print $i."<br/>"; $checksum += (int) ($number{$i-1}); // print_r($checksum); } // Analyze odd digits in even length strings or even digits in odd length strings. for ($i=(strlen($number)% 2) + 1; $i<strlen($number); $i+=2) { $digit = (int) ($number{$i-1}) * 2; if ($digit < 10) { $checksum += $digit; } else { $checksum += ($digit-9); } } if (($checksum % 10) == 0) { return true; } else { return self::luhnCheck2($number); } } protected static function luhnCheck2($number) { if ($number == 123456789) return false; //$checksum = 0; //$IDnum = $number; /* while(strlen($number)<9) { // print "123"; $number = '0'.$number ; } //$number = $IDnum;*/ // $ii = 0; $number = str_pad($number, 9,'0', STR_PAD_LEFT); //print $number; $mone = 0; for($i=0; $i<9; $i++) { $iii = $i; if ($i == 0) $ii = 0; else $ii = -$iii; $ii--; $char = mb_substr($number, $ii, 1); // print $char; $incNum = intval($char); $incNum*=($i+1); // print $incNum."<br/>"; // if($incNum > 9) // $incNum-=9; $mone+= $incNum; } if($mone%11==0){ return true; } else { return false; } /* for ($i=(2-(strlen($number) % 2)); $i<=strlen($number); $i+=2) { $checksum += (int) ($number{$i-1}); } // Analyze odd digits in even length strings or even digits in odd length strings. for ($i=(strlen($number)% 2) + 1; $i<strlen($number); $i+=2) { $digit = (int) ($number{$i-1}) * 2;+ if ($digit < 10) { $checksum += $digit; } else { $checksum += ($digit-9); } } if (($checksum % 10) == 0) { return true; } else { return false; } */ } }
-
אז זהו הפיתרון שלי
נראה שעובד תקין, קצר ולענין ב"הfunction validateTokef($tokef) { $monthInputed = substr($tokef, 0, 2); $yearInputed = substr($tokef, 2, 2); if ( !$monthInputed or $monthInputed > 12 or $yearInputed < date('y') or $yearInputed > (date('y') + 15) or ($yearInputed == date('y') and $monthInputed < date('m')) ) return false; else return true; } function validateCreditCard($card) { $pattern = '#4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11}#'; if (!preg_match($pattern, $card)) return false; if (!luhnTest($card)) return false; return true; } function luhnTest($num) { $str = ''; foreach (array_reverse(str_split($num)) as $i => $c) $str .= ($i % 2 ? $c * 2 : $c); return array_sum(str_split($str)) % 10 == 0; }