首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP通用信用卡驗證類:支援主流卡組織、長度檢查與Luhn校驗

     編輯:PHP 相關知識

企業級信用卡驗證解決方案:四步驗證流程

本類實現完整的信用卡號驗證:

  1. 清洗輸入(移除空格/連字符)。
  2. 根據前 4 位(BIN)識別卡組織並檢查長度是否符合該組織標準。
  3. 執行 Luhn (Mod 10) 校驗。
  4. 返回結構化結果(是否有效、卡類型、錯誤信息)。

完整類代碼(PHP 8+ 風格)

<?php
declare(strict_types=1);

class CreditCardValidator {
    private const BIN_RULES = [
        // [min, max, name, validLengths]
        [3000, 3059, 'Diners Club', [14]],
        [3600, 3699, 'Diners Club', [14]],
        [3800, 3889, 'Diners Club', [14]],
        [3400, 3499, 'American Express', [15]],
        [3700, 3799, 'American Express', [15]],
        [3528, 3589, 'JCB', [16]],
        [3890, 3899, 'Carte Blanche', [14]],
        [4000, 4999, 'Visa', [13, 16]],
        [5100, 5599, 'MasterCard', [16]],
        [5610, 5610, 'Australian BankCard', [16]],
        [6011, 6011, 'Discover/Novus', [16]],
    ];

    public function validate(string $number): array {
        $number = $this->sanitize($number);
        if ($number === '') return $this->fail('Empty card number');

        $bin = (int)substr($number, 0, 4);
        $len = strlen($number);

        // 識別卡類型與長度
        $cardInfo = $this->identify($bin, $len);
        if (!$cardInfo) return $this->fail("Unsupported card type (BIN: $bin)");

        [$name, $validLengths] = $cardInfo;
        if (!in_array($len, $validLengths, true)) {
            return $this->fail("$name requires " . implode('/', $validLengths) . " digits, got $len");
        }

        // Luhn 校驗
        if (!$this->luhnCheck($number)) {
            return $this->fail("$name number failed Luhn check");
        }

        return ['valid' => true, 'type' => $name, 'number' => $number];
    }

    private function sanitize(string $input): string {
        return substr(preg_replace('/\D/', '', $input), 0, 19);
    }

    private function identify(int $bin, int $len): ?array {
        foreach (self::BIN_RULES as [$min, $max, $name, $lengths]) {
            if ($bin >= $min && $bin <= $max) {
                // Visa 特殊處理:13/16 位均可
                if ($name === 'Visa' && $len === 14) return null; // 明確拒絕 14 位
                return [$name, $lengths];
            }
        }
        return null;
    }

    private function luhnCheck(string $num): bool {
        $sum = 0;
        $len = strlen($num);
        for ($i = $len - 1; $i >= 0; $i--) {
            $d = (int)$num[$i];
            if (($len - 1 - $i) % 2 === 1) {
                $d *= 2;
                if ($d > 9) $d -= 9;
            }
            $sum += $d;
        }
        return $sum % 10 === 0;
    }

    private function fail(string $msg): array {
        return ['valid' => false, 'error' => $msg];
    }
}

// 使用示例
$validator = new CreditCardValidator();
$tests = [
    '49927398716',           // 有效測試號
    '49927398717',           // Luhn 失敗
    '4539 1234 5678 9101',   // Visa 16 位(含空格)
    '378282246310005',       // Amex 15 位
    '6011111111111117',      // Discover
    '1234567812345678',      // 無效 BIN
];
foreach ($tests as $t) {
    $res = $validator->validate($t);
    echo $t . ' => ' . json_encode($res, JSON_UNESCAPED_UNICODE) . PHP_EOL;
}

輸出示例

49927398716 => {"valid":true,"type":"Visa","number":"49927398716"}
49927398717 => {"valid":false,"error":"Visa number failed Luhn check"}
4539 1234 5678 9101 => {"valid":true,"type":"Visa","number":"4539123456789101"}
378282246310005 => {"valid":true,"type":"American Express","number":"378282246310005"}
6011111111111117 => {"valid":true,"type":"Discover/Novus","number":"6011111111111117"}
1234567812345678 => {"valid":false,"error":"Unsupported card type (BIN: 1234)"}

擴展建議

  • 接入 BIN 數據庫(如 binlist.net)實現精確到發卡銀行、卡等級(金/鉑/商務)識別。
  • 增加有效期檢查(MM/YY 格式、未過期)。
  • 結合 CVV 長度驗證(Amex 4 位,其他 3 位)。
  • 對於高風險交易,調用發卡行驗證服務(AVS、3D Secure)。

此類代碼結構清晰、易維護、可單元測試,適合直接集成至電商訂單、支付網關、會員綁卡等核心流程。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved