##はじめに
先日、クレジットカードをiPhonのカメラで読みとり、入力フォームに自動で入力される機能の実装を行なったので記事を書きます!
この機能の実装自体は難しくなかったですが、httpsで接続していないとこの機能は動かないみたいで、動作を検証する際に悩みました。。
##やりたいこと
以下画像のように、クレカ読み取り機能で、クレカを枠内に入れたらフォームにクレカ情報が自動的に入力されるようにしたい。
※注意
・読み取れる項目は、カードナンバーと有効期限とカードのタイプのみのようです。名前とCVVは手動で入力する必要があります。 (今回は、カードナンバーと有効期限のみ)
・iOS8以上でないと、読み取り機能は正常に機能しないみたいなので注意が必要です!
・Angularのアプリケーション内で実装したのですが、Angular Materialの mat-selectタグを使用すると上手く行かなかったので、通常のselectタグを使用しました。→ mat-selectタグでも実装できた人教えてください!笑
##環境
環境はこんな感じです。
$ ng version
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 11.0.7
Node: 14.15.1
OS: darwin x64
Angular: 11.0.9
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1100.7
@angular-devkit/build-angular 0.1100.7
@angular-devkit/core 11.0.7
@angular-devkit/schematics 11.0.7
@angular/cli 11.0.7
@schematics/angular 11.0.7
@schematics/update 0.1100.7
rxjs 6.6.7
typescript 4.0.7
##実装
View側
特別な実装は以下の3点かと思います。
・カードナンバーフォームのname属性として、「"cardNumber"」を指定する。
・有効期限(月)フォームのname属性として、「"cardExpirationMonth"」を指定する。
・有効期限(年)フォームのname属性として、「"cardExpirationYear"」を指定する。
<form [formGroup]="paymentForm" (ngSubmit)="onSubmit()">
<div>
<input id="cardNumber" name="cardNumber" formControlName="cardNumber"><br><br>
</div>
<div>
<select formControlName="expiration_month" name="cardExpirationMonth">
<option *ngFor="let m of monthList">
{{ m + '月'}}
</option>
</select>
<select formControlName="expiration_year" name="cardExpirationYear">
<option *ngFor="let key of yearList">{{ key }}</option>
</select>
</div>
<button type="submit">決定</button>
</form>
コンポーネント側
通常のReactvieFormを作成するのと特に変わっていることはありません。
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-counter',
templateUrl: './counter.component.html',
styleUrls: ['./counter.component.scss']
})
export class CounterComponent implements OnInit {
// セレクトタグのフォームの部品となる「月」の配列
public monthList = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ];
// セレクトタグのフォームの部品となる「年」の配列
public yearList = [2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031];
public paymentForm: FormGroup;
constructor(
private fb: FormBuilder
) { }
ngOnInit(): void {
this.paymentForm = this.fb.group({
'cardNumber': ['', [Validators.required]],
'expiration_month': ['', [Validators.required]],
'expiration_year' : ['', [Validators.required]]
})
}
// 一旦入力された値をコンソールログに出力する。
public onSubmit(): void {
console.log(this.paymentForm.get('cardNumber').value);
console.log(this.paymentForm.get('expiration_month').value);
console.log(this.paymentForm.get('expiration_year').value);
}
}
##ローカル環境での動作確認
これでフォームとしては、機能しますがhttpsで接続していないと機能しません。なので、ローカル環境での検証をどうしようかなと調べました。どうにかして、ローカル環境にhttps接続したい。。。
調べた結果...
ngrokというライブラリを使用すると、ローカル環境にhttpsで接続することができます!
※ローカル環境にどこからでもアクセスできるようになってしまう為、セキュリティー的には危険です。その辺りを意識しながら使用してください。
さっそくインストール!
$ brew install ngrok --cask
バージョンが確認できればインストール完了です。
$ ngrok -v
$ ngrok version 2.3.39
ローカル環境にhttps接続する為には以下のコマンドを実行します。
# ポート番号は自分が立ち上げているアプリケーションのポート番号を指定
$ ngrok http 4200 -host-header="localhost:4200"
上記コマンドを実行したら、下記のように表示されます。
スマホでSafariを開き、ForwardingのURLをアレスバーに入力すると、ページが表示されるはずです。
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Session Expires 1 hour, 59 minutes
Version 2.3.39
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://acf3da528cdc.ngrok.io -> http://localhost:4200
Forwarding https://acf3da528cdc.ngrok.io -> http://localhost:4200
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
httpsで接続して、inputフォームをクリックする、以下の画像のように入力欄が表示され、「クレジットカードを読み取る」という項目が表示されます。
この項目をクリックするとカメラが起動して、以下の画像のような表示になります。
枠内にクレジットカードを入れるとフォームに自動的に、カード番号、有効期限が入力されます。
これで実装とローカルでの動作確認は終わりです!
##まとめ
クレジットカードの読み取り機能は、もう少し難しい実装になると思いましたが、案外簡単にできました。
ローカル環境にhttps接続する方法もついでに学べたので、よかったです。
ngrokではなく、serveoというサービスを使用してもできるようですので、今度はそちらを触ってみようかと思っています。
何か間違えている部分やこうしたほうが良いってところがあれば、コメント等で教えて頂ければ嬉しいです!
##参考##
クレカ読み取りについて
https://qiita.com/okumura_daiki/items/c5c28117b999252e22ca
ngrokについて
https://qiita.com/T-Com/items/7f1468167f80df00a87d
https://qiita.com/kitaro0729/items/44214f9f81d3ebda58bd
https://www.mathkuro.com/mac/brew-cask-command-error/
serveoについて
https://qiita.com/kaba/items/53b297e2bfb5b4f20a48