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