かつて自分が使うために作ったものですが、誰かの役にたてばと公開しておきます。

関数(TypeScript / JavaScript)

TypeScript で記載しています。型定義があるのは引数部分のみですので、JavaScript として使いたい場合は引数部分の型を削除してください。

本体は getCardBrand 関数です。それが内部的に rangeAsString および range を使用しています。

/** 指定された開始点から終了点までの数値の配列を生成する。開始点と終了点はいずれも配列に含まれる。 */
const range = (start: number, end: number) => {
  const amount = end - start + 1;
  return Array(amount)
    .fill(null)
    .map((_, i) => i + start);
};

/** 指定された開始点から終了点までの数値文字列の配列を生成する。開始点と終了点はいずれも配列に含まれる。 */
const rangeAsString = (start: number, end: number) => {
  const numbers = range(start, end);
  return numbers.map(String);
};

/** クレジットカード番号からカードブランドを取得する。 */
const getCardBrand = (cardNumber: string) => {
  const first1 = cardNumber.slice(0, 1);
  const first2 = cardNumber.slice(0, 2);
  const first3 = cardNumber.slice(0, 3);
  const first4 = cardNumber.slice(0, 4);

  const visaIds = ['4'];
  const amexIds = ['34', '37'];
  const dinersIds = ['36'];
  const unionpayIds = ['62'];
  const jcbIds = rangeAsString(3528, 3589);
  const mastercardIds = [...rangeAsString(51, 55), ...rangeAsString(2221, 2720)];
  const discoverIds = ['65', ...rangeAsString(644, 649), '6011'];

  if (visaIds.includes(first1)) {
    return 'visa';
  }
  if (amexIds.includes(first2)) {
    return 'amex';
  }
  if (dinersIds.includes(first2)) {
    return 'diners';
  }
  if (unionpayIds.includes(first2)) {
    return 'unionpay';
  }
  if (jcbIds.includes(first4)) {
    return 'jcb';
  }
  if (mastercardIds.includes(first2) || mastercardIds.includes(first4)) {
    return 'mastercard';
  }
  if (
    discoverIds.includes(first2) ||
    discoverIds.includes(first3) ||
    discoverIds.includes(first4)
  ) {
    return 'discover';
  }
  return 'unknown';
};

説明

以下のメジャーなカードブランドのみを対象にしています。

  • American Express: amex
  • Diners Club: diners
  • Discover: discover
  • JCB: jcb
  • MasterCard: mastercard
  • UnionPay: unionpay
  • Visa: visa

上記に該当しなければ unknown を返します。

クレジットカード番号とブランドの対応は以下を参考にしました。

https://en.wikipedia.org/wiki/Payment_card_number

実行結果

以下を実施したところ期待通りの結果となりました。

getCardBrand('4242424242424242'); // 'visa'
getCardBrand('4000056655665556'); // 'visa'
getCardBrand('5555555555554444'); // 'mastercard'
getCardBrand('2223003122003222'); // 'mastercard'
getCardBrand('5200828282828210'); // 'mastercard'
getCardBrand('5105105105105100'); // 'mastercard'
getCardBrand('378282246310005'); // 'amex'
getCardBrand('371449635398431'); // 'amex'
getCardBrand('6011111111111117'); // 'discover'
getCardBrand('6011000990139424'); // 'discover'
getCardBrand('36227206271667'); // 'diners'
getCardBrand('3566002020360505'); // 'jcb'
getCardBrand('6200000000000005'); // 'unionpay'
getCardBrand('9999999999999999'); // 'unknown'