* Stripe Checkout と Stripe Elements

[6] 決済情報等を入力させる画面が [[Stripe]] 側のサーバーにある 
[[Stripe Checkout]]
と、自サーバーに置く 
[[Stripe Elements]]
があります。

[7] 
どちらも [[Stripe.js]] という [[Stripe]] 提供の
[[JavaScript]] ライブラリーを自サーバーで読み込む必要があります。
この点ではどちらを使っても大差ありません。

[8] 
[[Stripe Checkout]]
は[[国]]や[[言語]]によっても違う複雑な入力フォームの用意をすべて
[[Stripe]]
側に任せられます。
決済手段の違いも、ある程度までは [[Stripe]]
側で吸収してくれます。
決済情報や[[住所]]入力に関係したトラブルを抱え込まずに済むのでとても便利。

[9] 
[[Stripe Elements]]
は決済情報や[[住所]]の入力を自サーバー上の
[[HTML]]
の[[フォーム]]を使って記述できますが、
[[Stripe.js]]
が複雑な部分をラップしています。
自サーバー上なので自由に設計できる柔軟性と、
複雑なフォームを正確に運用する必要性とのトレードオフをうまいこと処理しようと企てたのでしょうか。
でも [[Stripe.js]] の要求する作法に従って作るしかないので、
自由度はほとんどありません。
結局 [[Stripe Checkout]] が [[Stripe]] のサーバーでやってることを、
わざわざ手間をかけて自サーバーで再現することになっちゃいます。

[10] 
[[Stripe Elements]] でも[[クレジットカード]]の入力部分は
[CODE[iframe]]
で [[Stripe]] サーバーが埋め込まれる形で実現されています。
だから[[セキュリティー]]も大丈夫で安心、ってことなんですが、
[[住所]]とか他の重要度が低い(?)個人情報は自サーバー側なんですよね。
どうせ自サーバー側にあっても大してカスタマイズできるわけでもないので、
全部 [[Stripe]] サーバー側の [CODE[iframe]]
にあったほうが[[セキュリティー]]的にも安心なんですけれども。
でもそうしちゃうと 
[[Stripe Checkout]] に対する優位性が本当に何も無くなってしまう。

* Stripe Checkout

[11] checkout session は24時間で期限切れになるとのこと。

* Payment Request API 対応

[3] [CITE@en[paymentRequest.canMakePayment() is always false · Issue #379 · stripe/react-stripe-elements]]
([TIME[2021-01-21T06:29:30.000Z]])
<https://github.com/stripe/react-stripe-elements/issues/379>

[4] [[Stripe]] の [[Payment Request API]] 
対応は不完全。
その一部は意図的に制限している [SRC[>>3]] とのこと。ひどい。


[5] [[Stripe]] にとっては[[Web標準]]の [[API]] が充実するより自社サービスを使ってもらったほうが得だからかな?

* 利用制限

[2] [CITE@ja[【村八分】トランプ、オンライン決済も停止される - ウォールストリートジャーナル - Togetter]]
([TIME[2021-01-12T06:30:17.000Z]])
<https://togetter.com/li/1651445>

* 配送先住所の取得

[12] 
[[Stripe Checkout]] で[[配送先住所]]を記入させたら、
checkout session
オブジェクトの
[CODE[shipping]]
にその住所データが入ります。

;; [13] Dashboard に checkout session オブジェクトは表示されないので、
これを直接見ることができません。

[14] 
同じ[[住所]]が 
checkout
で作成された
invoice
オブジェクトに対応する支払いページ
(payment intent)
の「Checkout サマリー」
欄に表示されます。

[15] 
checkout session
が
[CODE[mode]] = [CODE[subscription]]
のときこの
invoice
に直接たどり着く方法がありません。
[CODE[payment_intent]] = [CODE[null]]
で変化しません。

[CODE[subscription]]
に
subscription
のID
が入っているので、
それを使って 
subscription
を取得します。
[CODE[latest_invoice]]
に最新の
invoice
のIDが入っています。
最古の
invoice
を取得する方法がないのですが、
新規作成直後なら最新 = 最古のはず。

[CITE@en[Stripe API Reference - List all invoices]], [TIME[2021-06-07T02:06:39.000Z]] <https://stripe.com/docs/api/invoices/list>

これで subscription の invoice を取得できます。
ただし sort order を指定できない。
新規作成直後なら1個しかないはずだけど念の為と
limit をそこそこ大きくしておいて最古の invoice を使うのがいいのだろうか。


invoice から payment intent の ID を取得すれば、
ダッシュボードの URL を作れます。

なおダッシュボードのページには住所が表示されますが、 payment intent 
オブジェクトには住所は入っていません。 [CODE[shipping]]
は [CODE[null]] です。

payment method の [CODE[payment_method]] から
payment method を取得して
[CODE[billing_details]]
を見ると[[請求先住所]]が入っているのですが、
これは[[配送先住所]]とは別です。

[16] 
請求額が0円の時は invoice の [CODE[payment_intent]] が
[CODE[null]]
になります。
その場合 Checkout の住所が表示されるページが存在していません。



* メモ

[1] [CITE[Stripe Billing 101 - Qiita]]
([TIME[2018-08-24 23:17:00 +09:00]])
<https://qiita.com/y_toku/items/235b5e7ee00792edcbbf>

[17] [CITE@en[Stripe外からアプリの支払いを受け取った時の対処手順. カード決済の失敗理由は基本的に分からない/信用コストは自分で払う必要がある/根本… | by Takuya Matsuyama | 週休7日で働きたい]], [[Takuya Matsuyama]], [TIME[2022-02-25T03:44:19.000Z]] <https://blog.craftz.dog/stripe-payment-adjustment-df5e1c996c12>