Skip to content
Open
Show file tree
Hide file tree
Changes from all 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

7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Require the package in `composer.json`

```json
"require": {
"inacho/php-credit-card-validator": "1.*"
"habil/php-credit-card-validator": "1.*"
Copy link

Choose a reason for hiding this comment

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

This should probably stay inacho since it's referring to this repo.

},
```

Expand All @@ -24,7 +24,7 @@ If you are using Laravel, add an alias in `config/app.php`
...
'View' => 'Illuminate\Support\Facades\View',

'CreditCard' => 'Inacho\CreditCard',
'CreditCard' => 'Sivax\CreditCard',

),
```
Expand Down Expand Up @@ -98,3 +98,6 @@ bool(false)
Execute the following command to run the unit tests:

vendor/bin/phpunit

### Disclaimer
Many thanks to [inacho](https://github.com/inacho "inacho"). This repository based on it's [PHP Credit Card Validator](https://github.com/inacho/php-credit-card-validator "PHP Credit Card Validator") repository.
9 changes: 5 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "inacho/php-credit-card-validator",
"name": "habil/php-credit-card-validator",
Copy link

Choose a reason for hiding this comment

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

Should stay "inacho".

"type": "library",
"description": "Validates popular debit and credit cards numbers against regular expressions and Luhn algorithm. Also validates the CVC and the expiration date",
"keywords": ["creditcard", "creditcards", "debit", "credit", "card", "cards", "validator", "cvc", "laravel"],
Expand All @@ -11,15 +11,16 @@
}
],
"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.*"
},
"autoload": {
"psr-4": {
"Inacho\\": "src/"
"Sivax\\": "src/"
Copy link

Choose a reason for hiding this comment

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

Should stay "Inacho".

}
}
}
133 changes: 117 additions & 16 deletions src/CreditCard.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@
* @copyright 2014 Ignacio de Tomás (http://inacho.es)
*/

namespace Inacho;
namespace Sivax;
Copy link

Choose a reason for hiding this comment

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

Wrong namespace


/**
* Class CreditCard
* @package Sivax
Copy link

Choose a reason for hiding this comment

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

Wrong package name

*/
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,23 +152,41 @@ 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);

if (! preg_match('/^20\d\d$/', $year)) {
if (!preg_match('/^20\d\d$/', $year)) {
return false;
}

if (! preg_match('/^(0[1-9]|1[0-2])$/', $month)) {
if (!preg_match('/^(0[1-9]|1[0-2])$/', $month)) {
return false;
}

Expand All @@ -147,9 +198,11 @@ public static function validDate($year, $month)
return true;
}

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

/**
* @param string $number
*
* @return string
*/
protected static function creditCardType($number)
{
foreach (self::$cards as $type => $card) {
Expand All @@ -161,16 +214,47 @@ 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));
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 +266,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,29 +283,40 @@ 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']) {
if (!self::$cards[$type]['luhn']) {
return true;
} else {
return self::luhnCheck($number);
}
}

/**
* @param string $number
*
* @return bool
*/
protected static function luhnCheck($number)
{
$checksum = 0;
for ($i=(2-(strlen($number) % 2)); $i<=strlen($number); $i+=2) {
$checksum += (int) ($number{$i-1});
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;
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);
$checksum += ($digit - 9);
}
}

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