همهی راهنماها
راهنمایی با این جستوجو پیدا نشد.
شبا و کارت بانکی
اعتبارسنجی شمارهٔ شبا (IBAN) با ISO 7064 mod-97-10 و شمارهٔ کارت بانکی با چکسام Luhn، و پیدا کردن بانک صادرکننده.
در این صفحه
شروع سریع
<?php
require 'vendor/autoload.php';
use RtlyKit\Validation\BankCard;
use RtlyKit\Validation\Sheba;
use function RtlyKit\is_bank_card;
use function RtlyKit\is_sheba;
var_dump(Sheba::isValid('IR800170000000000000000123')); // bool(true)
var_dump(is_sheba('800170000000000000000123')); // bool(true)، IR خودکار اضافه میشود
var_dump(BankCard::isValid('6037-9912-3456-7893')); // bool(true)
var_dump(is_bank_card('۶۰۳۷۹۹۱۲۳۴۵۶۷۸۹۳')); // bool(true)، رقمهای فارسی
echo Sheba::getBankName('IR800170000000000000000123'), "\n"; // بانک ملی ایران
echo BankCard::getBankName('6219861234567898'), "\n"; // بانک سامانشمارههای این مثالها ساختگیاند. چکسامشان درست است، ولی به هیچ حساب واقعی تعلق ندارند. هر دو کلاس قرارداد Validator را دارند، برای ورودی بد خطا پرتاب نمیکنند و توابع کمکی validate_sheba() و validate_bank_card() هم دارند.
شبا (IBAN)
قالب
شمارهٔ شبا همان IBAN ایرانی است: IR، دو رقم کنترل و یک BBAN ۲۲ رقمی، رویهم ۲۶ نویسه. سه رقم اول BBAN بانک را مشخص میکند.
IR 80 017 0000000000000000123
│ │ │ └─ بقیهٔ BBAN (۱۹ رقم)
│ │ └──── کد بانک (۳ رقم)
│ └─────── رقمهای کنترل
└────────── کد کشوریکسانسازی
Sheba::normalize() حرفها را بزرگ میکند، رقمهای فارسی و عربی را انگلیسی میکند و فاصله، خط تیره و نیمفاصله را حذف میکند. رشتهای که دقیقاً ۲۴ رقم باشد (شکلی که بانکها معمولاً بدون IR چاپ میکنند) پیشوند IR میگیرد. ورودی دیگر همانطور که تایپ شده میماند و در بررسی قالب رد میشود:
echo Sheba::normalize('800170000000000000000123'); // IR800170000000000000000123
echo Sheba::normalize('ir80 0170 0000'); // IR8001700000
echo json_encode(Sheba::validate('ir80-0170-0000-0000-0000-0001-23')->isValid()); // trueچه چیزی بررسی میشود
- نوع و اندازه (
invalid_type،input_too_long). - قالب:
IRو بعد دقیقاً ۲۴ رقم، وگرنهinvalid_format. - چکسام ISO 7064 mod-97-10: چهار نویسهٔ اول به آخر میروند،
IوRبه ۱۸ و ۲۷ تبدیل میشوند و عدد بهدستآمده بر ۹۷ باید باقیمانده ۱ بدهد. وگرنهinvalid_checksum.
پیدا کردن بانک پیش از چکسام انجام میشود. برای همین حتی اگر رقم کنترل غلط باشد، کد بانک در details() هست:
$r = Sheba::validate('IR060170000000000000000123');
var_dump($r->isValid()); // bool(false)
print_r($r->errors()); // Array ( [0] => invalid_checksum )
echo $r->details()['bank_name']; // بانک ملی ایران
$ok = Sheba::validate('IR800170000000000000000123');
echo json_encode($ok->details(), JSON_UNESCAPED_UNICODE);
// {"normalized":"IR800170000000000000000123","bank_code":"017","bank_name":"بانک ملی ایران"}
$unknown = Sheba::validate('IR049990000000000000000123');
var_dump($unknown->isValid(), $unknown->details()['bank_name']); // bool(true) NULLکلیدهای جزئیات: normalized، bank_code (رشتهٔ سهرقمی، یا null اگر قالب رد شده باشد) و bank_name (یا null وقتی کد در جدول نیست). شبایی که چکسامش درست است و کد بانکش ناشناخته است معتبر است و فقط نام ندارد.
نام بانکها. نامها همان نام بانک صادرکننده در زمان تخصیص کد هستند. کد بانکهایی که بعداً ادغام شدهاند، نام اولشان را نگه میدارد.
شمارهٔ کارت بانکی
قالب و بررسیها
کارت بانکی ایران ۱۶ رقم دارد. BankCard::normalize() بعد از تبدیل رقمهای فارسی و عربی، فقط رقمها را نگه میدارد. پس فاصله و خط تیره و هر جداکنندهٔ دیگر مشکلی ندارد. بررسیها به این ترتیباند:
- نوع و اندازه.
- دقیقاً ۱۶ رقم، وگرنه
invalid_format. - اگر هر ۱۶ رقم یکی باشد (مثل
0000000000000000)،repeated_digits. - چکسام Luhn، وگرنه
invalid_checksum. از راست، هر رقم دوم دو برابر میشود (اگر از ۹ بیشتر شد، ۹ کم میشود) و جمع رقمها باید بر ۱۰ بخشپذیر باشد.
$ok = BankCard::validate('6037-9912 3456 7893');
echo json_encode($ok->details(), JSON_UNESCAPED_UNICODE);
// {"normalized":"6037991234567893","bin":"603799","bank_name":"بانک ملی ایران"}
print_r(BankCard::validate('6037991234567890')->errors()); // [invalid_checksum]
print_r(BankCard::validate('0000000000000000')->errors()); // [repeated_digits]
print_r(BankCard::validate('1234')->errors()); // [invalid_format]
$x = BankCard::validate('9999991234567893'); // چکسام درست، BIN در جدول نیست
var_dump($x->isValid(), $x->details()['bank_name']); // bool(true) NULLکلیدهای جزئیات: normalized، bin (شش رقم اول، یا null اگر قالب رد شده باشد) و bank_name. مثل شبا، پیدا کردن BIN پیش از بررسی تکرار رقمها و چکسام انجام میشود.
BankCard::getBankName() و Sheba::getBankName() میانبر هستند. فقط برای شمارهٔ معتبر نام را میدهند و در غیر این صورت null:
var_dump(BankCard::getBankName('6037991234567890')); // NULL، چون چکسام رد میشود
var_dump(BankCard::getBankName('6037991234567893')); // string(26) "بانک ملی ایران"دادههای تشخیص بانک
| جدول | کلید | تعداد |
|---|---|---|
| BIN کارت | شش رقم اول کارت | ۳۹ |
| کد بانک شبا | سه رقم بعد از IRkk | ۳۸ |
هر مورد وقتی وارد جدول شده که دستکم دو منبع (جدولهای عمومی پیششمارهٔ بانکها و مجموعهدادهٔ جامعهٔ توسعهدهندگان) دربارهٔ آن همنظر بودهاند. موردی که فقط یک منبع داشته یا منبعها دربارهٔ آن اختلاف داشتهاند، وارد نشده است. ۱۹ کد بانک شبا را با مشخصات رسمی IBAN بانک مرکزی (که روی سایت بانک ملی ایران منتشر شده) هم مقایسه کردهایم و همه برابر بودند.
خوب است بدانید. جدولها کوچکاند. بسیاری از کارتهای معتبر مال بانکی هستند که در فهرست نیست و برای آنها bank_name برابر null است. بانکها ادغام میشوند، نامشان عوض میشود و بازهها را دوباره میدهند. پس نام بانک را به شکل «اشاره» نشان دهید و تصمیم مالی یا حقوقی را روی آن بنا نکنید. فهرست رسمی BIN در دسترس نبود. جدولها در 2026-10-08 با چند صفحهٔ عمومی دوباره سنجیده شدند. جزئیات در دقت و داده است.
معتبر بودن هیچوقت به این جدولها بستگی ندارد. شمارهای که چکسامش درست باشد معتبر است، چه بانکش شناخته شود چه نه.
نکتههای کاربردی
- چکسام اشتباه تایپی را میگیرد، نه شمارهٔ جعلی را. نمیتواند بگوید کارتی وجود دارد یا حسابی مال کسی است.
- شمارهٔ کارت را فقط برای قالب بررسی کنید. شمارهٔ کامل کارت را لاگ نکنید و CVV2 یا رمز دوم را ذخیره نکنید.
- مقدار یکسانشده را ذخیره کنید تا
6037-9912-3456-7893و6037991234567893یک رکورد باشند. - شمارهٔ کارت و شبا را رشته نگه دارید. عدد ۱۶ رقمی ممکن است از دقت عدد JSON یا عدد اعشاری بیشتر باشد.
سقف اندازه و قاعدهٔ نوع ورودی مثل بقیهٔ اعتبارسنجهاست. ورودی چطور پردازش میشود را ببینید.
این صفحه مفید بود؟