cardSchemeFromNumber function
Detects card scheme from the first digits of cardNumber.
cardNumber can contain spaces; only digits are used.
Implementation
CardScheme cardSchemeFromNumber(String cardNumber) {
final digits = cardNumber.replaceAll(RegExp(r'\D'), '');
if (digits.isEmpty) return CardScheme.unknown;
if (digits.length < 2) {
if (digits == '4') return CardScheme.visa;
if (digits == '5' || digits == '6' || digits == '3') return CardScheme.unknown;
return CardScheme.unknown;
}
final first = digits[0];
final firstTwo = digits.length >= 2 ? digits.substring(0, 2) : '';
final firstFour = digits.length >= 4 ? digits.substring(0, 4) : '';
final firstSix = digits.length >= 6 ? int.tryParse(digits.substring(0, 6)) : null;
// Visa: starts with 4
if (first == '4') return CardScheme.visa;
// American Express: 34 or 37
if (firstTwo == '34' || firstTwo == '37') return CardScheme.amex;
// Mastercard: 51-55, 2221-2720
if (first == '5') {
final two = int.tryParse(firstTwo);
if (two != null && two >= 51 && two <= 55) return CardScheme.mastercard;
}
if (firstFour.isNotEmpty && digits.length >= 4) {
final n = int.tryParse(firstFour);
if (n != null && n >= 2221 && n <= 2720) return CardScheme.mastercard;
}
// Discover: 6011, 644-649, 65
if (firstFour == '6011') return CardScheme.discover;
if (digits.length >= 3) {
final n = int.tryParse(digits.substring(0, 3));
if (n != null && n >= 644 && n <= 649) return CardScheme.discover;
}
if (firstTwo == '65') return CardScheme.discover;
// JCB: 3528-3589
if (firstSix != null && firstSix >= 3528 && firstSix <= 3589) return CardScheme.jcb;
// Diners Club: 36, 38, 300-305
if (firstTwo == '36' || firstTwo == '38') return CardScheme.diners;
if (digits.length >= 3) {
final n = int.tryParse(digits.substring(0, 3));
if (n != null && n >= 300 && n <= 305) return CardScheme.diners;
}
// Maestro: 5018, 5020, 5038, 5893, 6304, 6759, 6761, 6762, 6763
const maestroPrefixes = ['5018', '5020', '5038', '5893', '6304', '6759', '6761', '6762', '6763'];
if (firstFour.length == 4 && maestroPrefixes.contains(firstFour)) return CardScheme.maestro;
return CardScheme.unknown;
}