前回に引き続きクレジットカードがテーマです。今回は決済画面などで入力されたクレジットカード番号がどの国際ブランであるかを調べるコードです。
ブランドを検出するロジックは前回と同じですので、ここではユーザーの入力と検出部分のつなぎ込みがメインテーマとなります。
クレジットカード番号の仕様
開始番号と桁数
前回と同じ表です。カード番号の冒頭数桁でカード会社を判定できるようになっています。例えば「4」でカード番号が始まっていればVISAであることがわかります。
国際ブランド | 開始番号 | 桁数 | セキュリティコード |
---|---|---|---|
VISA | 4 | 13, 16 | CVV(3桁) |
MASTER Card | 510000〜559999, 222100〜272099 | 16 | CVC(3桁) |
JCB | 3528〜3589 | 16 | CVV(3桁) |
American Express | 34, 37 | 15 | CID(4桁) |
Diners Club | 300〜303574, 3095, 36, 38〜39 | 14 | CVV(3桁) |
- この情報は主にWikipediaを参考にしています。誤りや古くなっている箇所などあればご指摘ください。
ブランドの検出方法
では前述のロジックを利用してブランドを検出してみます。単純にカード番号の先頭を取り出して比較するだけですね。
ちょっとだけ厄介なのは「aからbの間」の判定です。正規表現を利用しても良いのですが少し複雑になるのでここではbetween()
という関数を用意しました。
const n = '4111111111111111' const between = (value, min, max) => ((min <= Number(value)) && (Number(value) <= max)) if( n.substr(0,1) === '4' ){ console.log('Visa') } else if( n.match(/^5[1-5]/) || between(n.substr(0,6), 222100, 272099) ){ console.log('Master') } else if( between(n.substr(0,4), 3528, 3589) ){ console.log('JCB') } else if( n.match(/^3[47]/) ){ console.log('AMEX') } else if( between(n.substr(0,6), 300000, 303574) || n.substr(0,4) === '3095' || n.match(/^3[689]/) ){ console.log('Diners Club') }
ライブラリを利用して判定
手前味噌ですが先ほどのロジックをそのまま利用したライブラリ「creditcard-checkerjs」を使うともっとシンプルに記述できます。
Webブラウザ上で動かしたい場合はcreditcard-checker.min.jsをダウンロードして保存しておきます。あとは先ほどのライブラリをscriptタグで読み込んでおきcreditcard.cardtype()
で判定するだけです。
<script src="creditcard-checker.min.js"></script> <script> const number = '4111111111111111' switch( creditcard.cardtype(number) ){ case creditcard.type.VISA: console.log('Visa') break case creditcard.type.MASTER: console.log('Master Card') break case creditcard.type.JCB: console.log('JCB') break case creditcard.type.AMEX: console.log('American Express') break case creditcard.type.DINERS: console.log('Diners Club') break case creditcard.type.UNKNOWN: default: console.log('?????') break } </script>
サンプル「ほぼリアルタイムに国際ブランドを判定する」
動作サンプル
最初の表を参考にしながらカード番号を入力してみてください。特定できた時点でテキストボックスの右側にアイコンが表示されます。
コード
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>creditcard-checker.js example</title> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous"> <style> #brand{ font-size: 20pt; } #number{ width:200px; padding:5px; } </style> </html> <body> <form> <span id="brand"></span> <input type="text" id="number" placeholder="XXXX-XXXX-XXXX-XXXX"> </form> <script src="creditcard-checker.min.js"></script> <script> //--------------------------------------- // ブランドを特定する //--------------------------------------- document.querySelector('#number').addEventListener('keyup', (e)=>{ const number = document.querySelector('#number').value const brand = document.querySelector('#brand') switch( creditcard.cardtype(number) ){ case creditcard.type.VISA: brand.innerHTML = '<i class="fab fa-cc-visa"></i>' break case creditcard.type.MASTER: brand.innerHTML = '<i class="fab fa-cc-mastercard"></i>' break case creditcard.type.JCB: brand.innerHTML = '<i class="fab fa-cc-jcb"></i>' break case creditcard.type.AMEX: brand.innerHTML = '<i class="fab fa-cc-amex"></i>' break case creditcard.type.DINERS: brand.innerHTML = '<i class="fab fa-cc-diners-club"></i>' break case creditcard.type.UNKNOWN: default: brand.innerHTML = '' break } }) //--------------------------------------- // submitイベントをキャンセル //--------------------------------------- document.querySelector('form').addEventListener('submit', (e)=>{ e.preventDefault() }) </script> </body> </html>