dragon-code / card-number
Generation and verification of card numbers using Luhn's algorithm.
Fund package maintenance!
Boosty
Yoomoney
Donationalerts
Installs: 8 581
Dependents: 0
Suggesters: 0
Security: 0
Stars: 55
Watchers: 3
Forks: 3
Open Issues: 0
Requires
- php: ^8.1
- archtechx/enums: ^0.3.2
Requires (Dev)
- illuminate/contracts: ^10.14 || ^11.0
- pestphp/pest: ^2.8
- symfony/var-dumper: ^6.3 || ^7.0
Suggests
- dragon-code/translation-set: Translation of validation rules into 78 localizations for Laravel Framework
README
Introduction
Generation and verification of card numbers using Luhn's algorithm: credit, customer loyalty and others.
Installation
To get the latest version of Card Number
, simply require the project using Composer:
composer require dragon-code/card-number
Or manually update require
block of composer.json
and run composer update
console command.
{ "require": { "dragon-code/card-number": "^1.5" } }
Usage
Validation
You can validate any numbers with the Luhn algorithm with any input format.
For example:
use DragonCode\CardNumber\CardNumber; CardNumber::isValid(18); // true CardNumber::isValid(12); // false CardNumber::isValid('0018'); // true CardNumber::isValid('0019'); // false CardNumber::isValid('123-455'); // true CardNumber::isValid('123-454'); // false CardNumber::isValid('12-3456-1239'); // true CardNumber::isValid('12-3456-1230'); // false CardNumber::isValid('5580 4733 7202 4733'); // true CardNumber::isValid('5580 4733 7202 4732'); // false CardNumber::isValid('5580-4733x7202_47 33'); // true CardNumber::isValid('5580-4733x7202_47 32'); // false
You can validate bank card numbers. To do this, pass the card type as the second argument:
use DragonCode\CardNumber\CardNumber; use DragonCode\CardNumber\Enums\CardType; CardNumber::isValid('4026 8434 8316 8683', CardType::visa); // true CardNumber::isValid('4019 1404 0123 4567', CardType::visa); // true CardNumber::isValid('2730 1684 6416 1841', CardType::visa); // false CardNumber::isValid('2201 6868 4646 8444', CardType::visa); // false CardNumber::isValid('4026 8434 8316 8683', 'visa'); // true CardNumber::isValid('4019 1404 0123 4567', 'visa'); // true CardNumber::isValid('2730 1684 6416 1841', 'visa'); // false CardNumber::isValid('2201 6868 4646 8444', 'visa'); // false
You can also check for invalid numbers:
use DragonCode\CardNumber\CardNumber; CardNumber::isInvalid(18); // false CardNumber::isInvalid(12); // true CardNumber::isInvalid('0018'); // false CardNumber::isInvalid('0019'); // true CardNumber::isInvalid('123-455'); // false CardNumber::isInvalid('123-454'); // true CardNumber::isInvalid('12-3456-1239'); // false CardNumber::isInvalid('12-3456-1230'); // true CardNumber::isInvalid('5580 4733 7202 4733'); // false CardNumber::isInvalid('5580 4733 7202 4732'); // true CardNumber::isInvalid('5580-4733x7202_47 33'); // false CardNumber::isInvalid('5580-4733x7202_47 32'); // true
In addition to numerical values, you can also validate number-letter combinations. For example:
use DragonCode\CardNumber\CardNumber; use DragonCode\CardNumber\Enums\CardType; CardNumber::isValid('EKN-OSX', CardType::chars); // true CardNumber::isValid('EKN-56X', CardType::chars); // true CardNumber::isValid('ekn-osx', 'chars'); // true CardNumber::isValid('ekn-56x', 'chars'); // true CardNumber::isValid('EKN-OSX'); // false CardNumber::isValid('EKN-56X'); // false
List of available validation types:
Custom Validators
In some cases there may not be enough built-in validators and therefore you can easily use your own.
To do this, create a class and inherit it from the abstract DragonCode\CardNumber\Validators\CardValidator
,
and then pass a reference to it in the cardType
parameter:
use DragonCode\CardNumber\CardNumber; use DragonCode\CardNumber\Validators\CardValidator; class SomeValidator extends CardValidator { protected static ?string $pattern = '/^[3-5]{3}/'; protected static array $numberLength = [4]; } CardNumber::isValid(3459, SomeValidator::class); // true CardNumber::isValid(2451, SomeValidator::class); // false CardNumber::isInvalid(3459, SomeValidator::class); // false CardNumber::isInvalid(2451, SomeValidator::class); // true
Generation
You can also easily generate any numbers using the Luhn algorithm:
use DragonCode\CardNumber\CardNumber; CardNumber::generate(1); // 18 CardNumber::generate(2); // 26 CardNumber::generate(10); // 109 CardNumber::generate(90); // 901 CardNumber::generate(908); // 9084
You can also use the formatter to format the resulting value:
use DragonCode\CardNumber\CardNumber; use DragonCode\CardNumber\Formatters\BankFormatter; use DragonCode\CardNumber\Formatters\LoyaltyFormatter; $loyalty = LoyaltyFormatter::create(); $bank = BankFormatter::create(); CardNumber::generate(1, $loyalty); // 0018 CardNumber::generate(2, $loyalty); // 0026 CardNumber::generate(12345, $loyalty); // 123-455 CardNumber::generate(23456, $loyalty); // 234-567 CardNumber::generate(123456, $loyalty); // 123-4566 CardNumber::generate(234567, $loyalty); // 234-5676 CardNumber::generate(123456123, $loyalty); // 12-3456-1239 CardNumber::generate(234567123, $loyalty); // 23-4567-1230 CardNumber::generate(558047337202473, $bank); // 5580 4733 7202 4733 CardNumber::generate(529391143678555, $bank); // 5293 9114 3678 5557
Formatters
You can also create your own formatter.
To do this, create a class and inherit it from the DragonCode\CardNumber\Formatters\Formatter
abstract class:
use DragonCode\CardNumber\Formatters\Formatter; class SomeFormatter extends Formatter { protected int $splitLength = 6; protected string $delimiter = '/'; }
And use this one:
use App\Cards\Formatters\SomeFormatter; use DragonCode\CardNumber\CardNumber; $formatter = SomeFormatter::create(); CardNumber::generate(558047337202473, $formatter); // 5580/473372/024733
List of available formatters:
DragonCode\CardNumber\Formatters\DefaultFormatter
DragonCode\CardNumber\Formatters\BankFormatter
DragonCode\CardNumber\Formatters\LoyaltyFormatter
DragonCode\CardNumber\Formatters\LoyaltyCharFormatter
In addition to numeric formatters, you can also use number-letter combinations.
For example, using the DragonCode\CardNumber\Formatters\LoyaltyCharFormatter
formatter,
you can generate a letter code instead of a numeric number, which will be valid when
verified by the Luhn's algorithm:
use DragonCode\CardNumber\CardNumber; use DragonCode\CardNumber\Formatters\LoyaltyCharFormatter; $formatter = LoyaltyCharFormatter::create(); CardNumber::generate(345678123, $formatter); // KN-OSXY-AEKF
Factories
In addition, you can specify factories as an incoming identifier parameter. In this way, you can form unique identification rules using fluent methods.
This is useful when, for example, you create a customer loyalty card number and want to specify in its number the year of issue as well as its level.
use DragonCode\CardNumber\CardNumber; use DragonCode\CardNumber\Factories\CustomerFactory; use DragonCode\CardNumber\Formatters\LoyaltyFormatter; $formatter = LoyaltyFormatter::create(); $customer = CustomerFactory::create()->level($user->loyalty_level)->customer($user->id); return CardNumber::generate($customer, $formatter); // For example, 230-4001-2348 // // 23 - year // 04 - loyalty level // 001234 - user id // 8 - control digit
use DragonCode\CardNumber\CardNumber; use DragonCode\CardNumber\Factories\BankFactory; use DragonCode\CardNumber\Formatters\BankFormatter; $formatter = BankFormatter::create(); $customer = BankFactory::create()->paymentType(3)->bank(12, 45, 75)->client(12345); return CardNumber::generate($customer, $formatter); // 3012 4575 0012 3452 // // 3 - payment type // 012 - bank ID // 45 - bank info // 75 - bank's program // 0012345 - client id // 2 - control digit
List of available factories:
DragonCode\CardNumber\Factories\BankFactory
DragonCode\CardNumber\Factories\CustomerFactory
Laravel
If you use the Laravel framework, you can also use the validation rule:
use DragonCode\CardNumber\Laravel\Validation\Rules\CardNumberRule; use Illuminate\Foundation\Http\FormRequest; class SomeRequest extends FormRequest { public function rules(): array { return [ 'number' => ['required', new CardNumberRule()] ]; } }
You can also check bank cards:
use DragonCode\CardNumber\Enums\CardType; use DragonCode\CardNumber\Laravel\Validation\Rules\CardNumberRule; use Illuminate\Foundation\Http\FormRequest; class SomeRequest extends FormRequest { public function rules(): array { return [ 'visa_card_1' => ['required', new CardNumberRule(CardType::visa)], 'visa_card_2' => ['required', new CardNumberRule('visa')], 'few_cards' => ['required', new CardNumberRule([CardType::visa, CardType::masterCard])], 'few_cards' => ['required', new CardNumberRule(['visa', 'mastercard'])], ]; } }
License
This package is licensed under the MIT License.