我想知道如何仅根据信用卡的号码来判断信用卡的类型。有谁知道确定可靠的方法吗?
当前回答
另一个api解决方案在rapidapi银行卡位数检查有250K+发行卡类型。
只有一个GET rest api请求,并获得发卡机构信息,如:
{ "bin_number": 535177, "bank": "Finansbank A.S.", "scheme": "MASTERCARD", "type": "Debit", "country": "Turkey" }
其他回答
信用卡的第一个数字可以用来大致了解供应商:
签证:49、44或47 Visa电子:42、45、48、49 万事达卡:51 美国运通:34 就餐者:30、36、38 JCB: 35
看看这个:
http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CC70060A01B
function isValidCreditCard(type, ccnum) {
/* Visa: length 16, prefix 4, dashes optional.
Mastercard: length 16, prefix 51-55, dashes optional.
Discover: length 16, prefix 6011, dashes optional.
American Express: length 15, prefix 34 or 37.
Diners: length 14, prefix 30, 36, or 38. */
var re = new Regex({
"visa": "/^4\d{3}-?\d{4}-?\d{4}-?\d",
"mc": "/^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/",
"disc": "/^6011-?\d{4}-?\d{4}-?\d{4}$/",
"amex": "/^3[47]\d{13}$/",
"diners": "/^3[068]\d{12}$/"
}[type.toLowerCase()])
if (!re.test(ccnum)) return false;
// Remove all dashes for the checksum checks to eliminate negative numbers
ccnum = ccnum.split("-").join("");
// Checksum ("Mod 10")
// Add even digits in even length strings or odd digits in odd length strings.
var checksum = 0;
for (var i = (2 - (ccnum.length % 2)); i <= ccnum.length; i += 2) {
checksum += parseInt(ccnum.charAt(i - 1));
}
// Analyze odd digits in even length strings or even digits in odd length strings.
for (var i = (ccnum.length % 2) + 1; i < ccnum.length; i += 2) {
var digit = parseInt(ccnum.charAt(i - 1)) * 2;
if (digit < 10) { checksum += digit; } else { checksum += (digit - 9); }
}
if ((checksum % 10) == 0) return true;
else return false;
}
这是一个php类函数,通过CCnumber返回CCtype。 此代码不验证卡或不运行Luhn算法仅尝试查找基于本页表的信用卡类型。基本上使用CCnumber长度和CCcard前缀来确定CCcard类型。
<?php
class CreditcardType
{
public static $creditcardTypes = [
[
'Name' => 'American Express',
'cardLength' => [15],
'cardPrefix' => ['34', '37'],
], [
'Name' => 'Maestro',
'cardLength' => [12, 13, 14, 15, 16, 17, 18, 19],
'cardPrefix' => ['5018', '5020', '5038', '6304', '6759', '6761', '6763'],
], [
'Name' => 'Mastercard',
'cardLength' => [16],
'cardPrefix' => ['51', '52', '53', '54', '55'],
], [
'Name' => 'Visa',
'cardLength' => [13, 16],
'cardPrefix' => ['4'],
], [
'Name' => 'JCB',
'cardLength' => [16],
'cardPrefix' => ['3528', '3529', '353', '354', '355', '356', '357', '358'],
], [
'Name' => 'Discover',
'cardLength' => [16],
'cardPrefix' => ['6011', '622126', '622127', '622128', '622129', '62213','62214', '62215', '62216', '62217', '62218', '62219','6222', '6223', '6224', '6225', '6226', '6227', '6228','62290', '62291', '622920', '622921', '622922', '622923','622924', '622925', '644', '645', '646', '647', '648','649', '65'],
], [
'Name' => 'Solo',
'cardLength' => [16, 18, 19],
'cardPrefix' => ['6334', '6767'],
], [
'Name' => 'Unionpay',
'cardLength' => [16, 17, 18, 19],
'cardPrefix' => ['622126', '622127', '622128', '622129', '62213', '62214','62215', '62216', '62217', '62218', '62219', '6222', '6223','6224', '6225', '6226', '6227', '6228', '62290', '62291','622920', '622921', '622922', '622923', '622924', '622925'],
], [
'Name' => 'Diners Club',
'cardLength' => [14],
'cardPrefix' => ['300', '301', '302', '303', '304', '305', '36'],
], [
'Name' => 'Diners Club US',
'cardLength' => [16],
'cardPrefix' => ['54', '55'],
], [
'Name' => 'Diners Club Carte Blanche',
'cardLength' => [14],
'cardPrefix' => ['300', '305'],
], [
'Name' => 'Laser',
'cardLength' => [16, 17, 18, 19],
'cardPrefix' => ['6304', '6706', '6771', '6709'],
],
];
public static function getType($CCNumber)
{
$CCNumber = trim($CCNumber);
$type = 'Unknown';
foreach (CreditcardType::$creditcardTypes as $card) {
if (! in_array(strlen($CCNumber), $card['cardLength'])) {
continue;
}
$prefixes = '/^(' . implode('|', $card['cardPrefix']) . ')/';
if (preg_match($prefixes, $CCNumber) == 1) {
$type = $card['Name'];
break;
}
}
return $type;
}
}
压缩javascript版本
var getCardType = function (number) {
var cards = {
visa: /^4[0-9]{12}(?:[0-9]{3})?$/,
mastercard: /^5[1-5][0-9]{14}$/,
amex: /^3[47][0-9]{13}$/,
diners: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/,
discover: /^6(?:011|5[0-9]{2})[0-9]{12}$/,
jcb: /^(?:2131|1800|35\d{3})\d{11}$/
};
for (var card in cards) {
if (cards[card].test(number)) {
return card;
}
}
};
在卡牌范围识别(CRR)中,使用一系列正则表达式或其他硬编码范围的算法的一个缺点是,根据我的经验,bin / iin会随着时间的推移而变化。信用卡的联合品牌是一个持续的复杂问题。不同的购卡商/商家可能会要求你不同地对待同一张卡,这取决于例如地理位置。
Additionally, in the last few years with e.g. UnionPay cards in wider circulation, existing models do not cope with new ranges that sometimes interleave with broader ranges that they supersede. Knowing the geography your system needs to cover may help, as some ranges are restricted to use in particular countries. For example, ranges 62 include some AAA sub-ranges in the US, but if your merchant base is outside the US, you may be able to treat all 62 as UnionPay. You may be also asked to treat a card differently based on merchant location. E.g. to treat certain UK cards as debit domestically, but as credit internationally.
There are very useful set of rules maintained by one major Acquiring Bank. E.g. https://www.barclaycard.co.uk/business/files/BIN-Rules-EIRE.pdf and https://www.barclaycard.co.uk/business/files/BIN-Rules-UK.pdf. (Valid links as of June 2017, thanks to the user who provided a link to updated reference.) But be aware of the caveat that, while these CRR rules may represent the Card Issuing universe as it applies to the merchants acquired by that entity, it does not include e.g. ranges identified as CUP/UPI.
这些注释适用于磁条(MagStripe)或PKE (Pan Key Entry)场景。在ICC/EMV领域,情况又有所不同。
更新:本页上的其他答案(以及链接的维基百科页面)的JCB始终是16长。然而,在我的公司,我们有一个专门的工程师团队,他们在多个银行和地区认证我们的POS设备和软件。这个团队从JCB获得的最新认证卡包,有一个19长PAN的合格案例。