ネットで買い物をして、カードで決済する機能を実装した。
買った商品の代金を払うだけなので、1度きりの支払で、サブスクなどの複雑な機能は必要ない。
stripeではそういう機能を実装するのに、3種類用意されている。
1.Link、2.Checkout、3.Elements (名称は正確でないかも)
LinkはStripeにリンクを貼るだけで、すぐに用意できるらしい。(試していない)
Stripeのサイトに飛んで決済する。
Stripeのサイトに商品マスターを用意する。画像なども登録できる。
すると、見栄えの良いデザインで、商品の画像を確認しながら、決済金額をチェックして決済して終わり。
Checkoutは多少コーディングが必要。多少カスタマイズ可能であるが、Stripeで用意された画面がポップアップして表示される。
新しいバージョンだと、Link同様に、商品マスターをStripeに整備することで、美しい決済画面が表示できるらしい。
やってみたら、簡単に実装できたが、新バージョンの説明はわかりにくかったため、やめた。
自分のサイトの中に、決済画面を取り込むならelementsを使うことになる。
elementsの中に、カード番号、期限、CSV(確認コード:3桁)がある。
海外だと郵便番号も必須になるところもあるらしい。
ところで、stripeにはAPIがいくつかある。
対象になるのは、Charge.APIとPaymentIntent.API。
ネットで詳しく紹介されているのは、Charge.APIの方。
言葉になじみがないし、とっつきにくいが、できてしまえば簡単。
オーソリにも容易に対応できた。
ところが、Charge.APIでは3Dセキュアに対応できないとのこと。
できるだけ、PaymentIntent.APIを使うようにと、stripeの営業から情報があった。
ならば、PaymentIntent.APIでの構築に変更。
これが難物。参考になるものがあまりない。
stripe.docでstripe-sample-code.zipをダウンロードして展開してみてみると、
PHPでのサンプルとしてはバッチリだけど、Laravelに移植すると、すぐにはうまくいかなかった。
Charge.APIではviewにフォームを用意して、カード番号とか、期限とかの各elementを貼り付けて、JSでマウントしていくところから始まるので、わかりやすい。
しかも、決済時に作られるChargeのIDを保持しておけば、オーソリのキャプチャーもキャンセルも簡単。
これはPaymentIntentでも同様だが、少しわかりにくかった。(本当のやり方はわかっていない)
顧客というオブジェクトも作成される。Customerだけど、要するにカード情報のこと。
これを自分のDBの会員テーブルに保持すれば、次回からはカード情報入力の省略ができることになる。
カード情報はStripeにtokenで保持されているらしいが、自分では全く保持していないのでセキュリティガイドライン上も問題ない。
システム的には、$customer = Customer::retrieve($id)のように、Createせずに呼べばよい。
PaymentIntentは全く違うので苦労した。まともな説明がない。
Stripeのサポートに質問しても、質問に質問で返してくる。
「お困りのことは、PaymentIntentでカードの保持と決済ということでよかったでしょうか?」
そう書いてありますよね、と言いたい。
それの繰り返し。 ワラフヂナルオ?
で、結局1行も参考になるコードを提示してくれるわけではない。
何度も読んだstripe.docのリンクを、書いてくれるだけ。読んだことあるのかな、って思った。
データの受け渡しも難題だったが、特に、カードの保持は苦労した。
カードの保持(customerの作成)の説明はあったが、保持したカードを使った決済については、情報がほぼない状態だった。
結論から言えば、保持したカードの決済は、Laravelのコントローラーだけで終わる。
新規の時のjsは全くいらない。(Script側のjsではない)
新規の時は、viewに組み込んだscriptで、裏側のPHPのControllerを動作させて、amountや支払方法でpaymentintentを作成させる。そこからclient_secretなるおそらくtokenを作成して、表側のjsに渡し、formにelementsを配置。
入力されたelementの内容とclient_secretからstripe側のjsでconfirmする。裏で秘密裏に枠を作って表側からscriptへ渡して完結させる感じ。
完結時に、returnで使うURLににpaymentintentとclient_secretのquerystringが含まれる。
そのURLを、ルーティングでControllerを通すように設定して、paymentintentを取得して、cutomer_idやpayment_methodを保持可能。
2回目以降でカードを保持していたら、、裏側のPHPのControllerで処理できる。
confirm = true;
が必要。
POSTすれば良いだけだが、POSTが重なるのでとりあえず、別のコントローラーに飛ばして確認した。
customerのIDと支払方法:payment_methodが必要になる。
なので、payment_methodは会員の情報ではないけれど、前回の買い物のpayment_methodを会員のテーブルに保持しておくと処理が簡単になる。
保持していなくても、customerのIDからpaymentintentsを探すことができるので、そこから得ることも可能。