Jump to content

PHP Алгоритм определения типа банковской карты


KirKMS

Recommended Posts

Всем привет.

Сегодня я вам покажу как можно определить какой тип банковской карты по её номеру.

Может кому пригодиться в проекте.Например для системы оплат итд.

Есть три части для проверки номера карты:

PATTERN - соответствует шаблону эмитентов (например, VISA/Mastercard/etc.)

CHECKSUM - действительно ли это контрольная сумма (например, не только 13 случайных чисел после "34", чтобы сделать ее номером карты AMEX)

ДЕЙСТВИТЕЛЬНО СУЩЕСТВУЕТ - у него фактически есть связанная учетная запись (вы вряд ли получите это без учетной записи продавца).

шаблон

Префикс MASTERCARD = 51-55, длина = 16 (контрольная сумма Mod10)

Префикс VISA = 4, длина = 13 или 16 (Mod10)

Префикс AMEX = 34 или 37, длина = 15 (Mod10)

Diners Club/Carte Prefix = 300-305, 36 или 38, Length = 14 (Mod10)

Префикс Discover = 6011,622126-622925,644-649,65, Length = 16, (Mod10)

и т.д.. (подробный список префиксов)

Контрольная сумма

Большинство карт используют алгоритм Луна для контрольных сумм:

 

Вот и сама функция 

function check_cc($cc, $extra_check = false){
    $cards = array(
        "visa" => "(4\d{12}(?:\d{3})?)",
        "amex" => "(3[47]\d{13})",
        "jcb" => "(35[2-8][89]\d\d\d{10})",
        "maestro" => "((?:5020|5038|6304|6579|6761)\d{12}(?:\d\d)?)",
        "solo" => "((?:6334|6767)\d{12}(?:\d\d)?\d?)",
        "mastercard" => "(5[1-5]\d{14})",
        "switch" => "(?:(?:(?:4903|4905|4911|4936|6333|6759)\d{12})|(?:(?:564182|633110)\d{10})(\d\d)?\d?)",
    );
    $names = array("Visa", "American Express", "JCB", "Maestro", "Solo", "Mastercard", "Switch");
    $matches = array();
    $pattern = "#^(?:".implode("|", $cards).")$#";
    $result = preg_match($pattern, str_replace(" ", "", $cc), $matches);
    if($extra_check && $result > 0){
        $result = (validatecard($cc))?1:0;
    }
    return ($result>0)?$names[sizeof($matches)-2]:false;
}

Пример вывода

$cards = array(
    "4111 1111 1111 1111",
);

foreach($cards as $c){
    $check = check_cc($c, true);
    if($check!==false)
        echo $c." - ".$check;
    else
        echo "$c - Not a match";
    echo "<br/>";
}

Выведет нам 4111 1111 1111 1111 - Visa

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...