Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ composer.lock

/build
/vendor

/.idea/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a new line following this

5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
}
],
"require": {
"php": ">=5.3.0",
"lib-pcre": ">=7.3"
"php": ">=5.6.0",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a potentially breaking change, should we do this?

"lib-pcre": ">=7.3",
"ext-ctype": "*"
},
"require-dev": {
"phpunit/phpunit": "4.7.*"
Expand Down
112 changes: 106 additions & 6 deletions src/CreditCard.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@

namespace Inacho;

/**
* Class CreditCard
* @package Inacho
*/
class CreditCard
{
/**
* Debit cards must come first, since they have more specific patterns than their credit-card equivalents.
* @var array
*/
protected static $cards = array(
// Debit cards must come first, since they have more specific patterns than their credit-card equivalents.

'visaelectron' => array(
'type' => 'visaelectron',
'pattern' => '/^4(026|17500|405|508|844|91[37])/',
Expand Down Expand Up @@ -43,6 +49,13 @@ class CreditCard
'cvcLength' => array(3),
'luhn' => true,
),
'mir' => array(
'type' => 'mir',
'pattern' => '/^220[0-4]/',
'length' => array(16),
'cvcLength' => array(3),
'luhn' => true,
),
// Credit cards
'visa' => array(
'type' => 'visa',
Expand Down Expand Up @@ -82,7 +95,7 @@ class CreditCard
),
'unionpay' => array(
'type' => 'unionpay',
'pattern' => '/^(62|88)/',
'pattern' => '/^(62|81)/',
'length' => array(16, 17, 18, 19),
'cvcLength' => array(3),
'luhn' => false,
Expand All @@ -94,8 +107,28 @@ class CreditCard
'cvcLength' => array(3),
'luhn' => true,
),
'uatp' => array(
'type' => 'uatp',
'pattern' => '/^1/',
'length' => array(15),
'cvcLength' => array(3),
'luhn' => true,
),
'rupay' => array(
'type' => 'rupay',
'pattern' => '/^(60|6521|6522)/',
'length' => array(16),
'cvcLength' => array(3),
'luhn' => true,
),
);

/**
* @param string $number
* @param null $type
*
* @return array
*/
public static function validCreditCard($number, $type = null)
{
$ret = array(
Expand All @@ -119,14 +152,32 @@ public static function validCreditCard($number, $type = null)
);
}

$ret['validation'] = array(
'pattern' => !empty($type) && self::validPattern($number, $type),
'length' => !empty($type) && self::validLength($number, $type),
'luhn' => !empty($type) && self::validLuhn($number, $type),
);

return $ret;
}

/**
* @param string $cvc
* @param string $type
*
* @return bool
*/
public static function validCvc($cvc, $type)
{
return (ctype_digit($cvc) && array_key_exists($type, self::$cards) && self::validCvcLength($cvc, $type));
}

/**
* @param int $year
* @param int $month
*
* @return bool
*/
public static function validDate($year, $month)
{
$month = str_pad($month, 2, '0', STR_PAD_LEFT);
Expand All @@ -147,9 +198,11 @@ public static function validDate($year, $month)
return true;
}

// PROTECTED
// ---------------------------------------------------------

/**
* @param string $number
*
* @return int|string
*/
protected static function creditCardType($number)
{
foreach (self::$cards as $type => $card) {
Expand All @@ -161,16 +214,46 @@ protected static function creditCardType($number)
return '';
}

/**
* @param string $bin
*
* @return string|null
*/
public static function determineCreditCardType($bin)
{
$type = self::creditCardType($bin);

return !empty($type) ? $type : null;
}

/**
* @param string $number
* @param string $type
*
* @return bool
*/
protected static function validCard($number, $type)
{
return (self::validPattern($number, $type) && self::validLength($number, $type) && self::validLuhn($number, $type));
}

/**
* @param string $number
* @param string $type
*
* @return false|int
*/
protected static function validPattern($number, $type)
{
return preg_match(self::$cards[$type]['pattern'], $number);
}

/**
* @param string $number
* @param string $type
*
* @return bool
*/
protected static function validLength($number, $type)
{
foreach (self::$cards[$type]['length'] as $length) {
Expand All @@ -182,6 +265,12 @@ protected static function validLength($number, $type)
return false;
}

/**
* @param string $cvc
* @param string $type
*
* @return bool
*/
protected static function validCvcLength($cvc, $type)
{
foreach (self::$cards[$type]['cvcLength'] as $length) {
Expand All @@ -193,6 +282,12 @@ protected static function validCvcLength($cvc, $type)
return false;
}

/**
* @param string $number
* @param string $type
*
* @return bool
*/
protected static function validLuhn($number, $type)
{
if (! self::$cards[$type]['luhn']) {
Expand All @@ -202,6 +297,11 @@ protected static function validLuhn($number, $type)
}
}

/**
* @param string $number
*
* @return bool
*/
protected static function luhnCheck($number)
{
$checksum = 0;
Expand Down
7 changes: 7 additions & 0 deletions tests/Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ class Test extends PHPUnit_Framework_TestCase
'dankort' => array(
'5019717010103742',
),
'mir' => array(
'2200524572467853',
'2201338708835472',
'2202410737880339',
'2203027541752030',
'2204500360586886',
),

// Credit cards
'visa' => array(
Expand Down