PHPackages                             dragon-code/card-number - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Validation &amp; Sanitization](/categories/validation)
4. /
5. dragon-code/card-number

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

dragon-code/card-number
=======================

Generation and verification of card numbers using Luhn's algorithm.

1.8.0(2mo ago)6512.8k↓34.8%6MITPHPPHP ^8.1CI passing

Since Jul 1Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/TheDragonCode/card-number)[ Packagist](https://packagist.org/packages/dragon-code/card-number)[ Fund](https://boosty.to/dragon-code)[ Fund](https://yoomoney.ru/to/410012608840929)[ RSS](/packages/dragon-code-card-number/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (8)Versions (18)Used By (0)

Card Number using Luhn's algorithm
==================================

[](#card-number-using-luhns-algorithm)

  ![Card Number](https://camo.githubusercontent.com/6a2a827ecfe81659c9e95ba2169d4499e33b0ea6c8c50574c01cad2686d017d3/68747470733a2f2f62616e6e6572732e6265796f6e64636f2e64652f436172642532304e756d6265722e706e673f7061747465726e3d746f706f677261706879267374796c653d7374796c655f3226666f6e7453697a653d3130307078266d643d312673686f7757617465726d61726b3d31267468656d653d6c69676874267061636b6167654d616e616765723d636f6d706f7365722b72657175697265267061636b6167654e616d653d647261676f6e2d636f6465253246636172642d6e756d626572266465736372697074696f6e3d47656e65726174696f6e2b616e642b766572696669636174696f6e2b6f662b636172642b6e756d626572732b7573696e672b4c75686e253237732b616c676f726974686d2e26696d616765733d68747470732533412532462532467777772e7068702e6e6574253246696d616765732532466c6f676f732532466e65772d7068702d6c6f676f2e737667)[![Stable Version](https://camo.githubusercontent.com/ebb72a48d9d9b651974b9a1ef51a2c489f228c41169496fbbbaa4657721576c7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f546865447261676f6e436f64652f636172642d6e756d6265723f6c6162656c3d737461626c65267374796c653d666c61742d737175617265)](https://packagist.org/packages/dragon-code/card-number)[![Total Downloads](https://camo.githubusercontent.com/4c9c044c6b8d0151adfc09130fe1667f3f7d391fb0491b87b7cfa37055c2232a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f647261676f6e2d636f64652f636172642d6e756d6265722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/dragon-code/card-number)[![License](https://camo.githubusercontent.com/422db9fd40f5831c765cf6530b6750c081b696bd18d904cf89554df98c676277/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e3f7374796c653d666c61742d737175617265)](LICENSE)

Introduction
------------

[](#introduction)

Generation and verification of card numbers using Luhn's algorithm: credit, customer loyalty and others.

Installation
------------

[](#installation)

To get the latest version of `Card Number`, simply require the project using [Composer](https://getcomposer.org):

```
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
-----

[](#usage)

### Validation

[](#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:

TypeCodeEnumAmericanExpress`amex``DragonCode\CardNumber\Enums\CardType::americanExpress`Chars Number`chars``DragonCode\CardNumber\Enums\CardType::chars`Dankort`dankort``DragonCode\CardNumber\Enums\CardType::dankort`DinersClub`dinersclub``DragonCode\CardNumber\Enums\CardType::dinersClub`Discovery`discovery``DragonCode\CardNumber\Enums\CardType::discovery`Forbrugsforeningen`forbrugsforeningen``DragonCode\CardNumber\Enums\CardType::forbrugsforeningen`HiperCard`hipercard``DragonCode\CardNumber\Enums\CardType::hiperCard`Jcb`jcb``DragonCode\CardNumber\Enums\CardType::jcb`Maestro`maestro``DragonCode\CardNumber\Enums\CardType::maestro`MasterCard`mastercard``DragonCode\CardNumber\Enums\CardType::masterCard`Mir`mir``DragonCode\CardNumber\Enums\CardType::mir`Ralf Ringer`ralfringer``DragonCode\CardNumber\Enums\CardType::ralfRinger`Troy`troy``DragonCode\CardNumber\Enums\CardType::troy`Unionpay`unionpay``DragonCode\CardNumber\Enums\CardType::unionPay`Visa`visa``DragonCode\CardNumber\Enums\CardType::visa`VisaElectron`visaelectron``DragonCode\CardNumber\Enums\CardType::visaElectron`Yves Rocher`yvesrocher``DragonCode\CardNumber\Enums\CardType::yvesRocher`#### Custom Validators

[](#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

[](#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

[](#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

[](#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

[](#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
-------

[](#license)

This package is licensed under the [MIT License](LICENSE).

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance88

Actively maintained with recent releases

Popularity38

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity61

Established project with proven stability

 Bus Factor1

Top contributor holds 86.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~71 days

Recently: every ~184 days

Total

15

Last Release

60d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b77790e612f1c9beed1e1533e36eba4954fbd6da2a5c9f71e845cd0f5465f0ad?d=identicon)[Helldar](/maintainers/Helldar)

---

Top Contributors

[![andrey-helldar](https://avatars.githubusercontent.com/u/10347617?v=4)](https://github.com/andrey-helldar "andrey-helldar (106 commits)")[![actions-user](https://avatars.githubusercontent.com/u/65916846?v=4)](https://github.com/actions-user "actions-user (6 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (5 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (5 commits)")

---

Tags

credit-cardcredit-cardscreditcardcustomerdebitdebit-cardloyaltyloyaltyprogramluhnluhn-algorithmluhn-checksumluhn-generationluhn-validationvalidationvalidatorvalidatorvalidationgeneratorgenerationcredit-cardluhncustomerscreditdebitloyalty

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/dragon-code-card-number/health.svg)

```
[![Health](https://phpackages.com/badges/dragon-code-card-number/health.svg)](https://phpackages.com/packages/dragon-code-card-number)
```

###  Alternatives

[intervention/validation

Additional validation rules for the Laravel framework

6826.7M8](/packages/intervention-validation)[laravel-validation-rules/credit-card

Validate credit card number, expiration date, cvc

2412.2M5](/packages/laravel-validation-rules-credit-card)[inacho/php-credit-card-validator

Validates popular debit and credit cards numbers against regular expressions and Luhn algorithm. Also validates the CVC and the expiration date

2051.4M11](/packages/inacho-php-credit-card-validator)[nekman/luhn-algorithm

Implementation of the Luhn algorithm in PHP. Used in validation of credit card numbers and some national identification numbers.

22819.4k](/packages/nekman-luhn-algorithm)[phpexperts/datatype-validator

An easy to use data type validator (both strict and fuzzy).

141.1M2](/packages/phpexperts-datatype-validator)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
