おはこんばんにちは、みなとです。
少し空き時間ができたので、近頃よくある「Webサイトからスマホのブラウザ上で直接決済」というのを試してみました。
作ったもの
例によってGitHubで公開しています。
Demo
決済が完了すると、Stripeに明細が入ります。

全体の流れ
StripeのAPIを使いました。サンプルアプリで、独自ドメインを使って公開するほどのものではなかったので、ngrokというツールで自宅PCに立てたWebサーバを一時的に公開して動かしました。
下記はClaudeポン出しのシーケンスです。基本的には Stripe.js の中でiOS Apple PayのSDKを呼び出しているようで、細かい動きまでは追えていないところではありますが、思ったよりはお手軽な実装かなと思います。
sequenceDiagram
actor U as ユーザー
participant B as ブラウザ<br/>(app.js / checkout.js)
participant SJ as Stripe.js
participant OS as iOS Apple Pay
participant S as Express<br/>(server.js)
participant ST as Stripe API
Note over ST: 事前: ngrokのドメインをStripeに登録<br/>(Stripe→Appleで検証)
U->>B: URLを開く
B->>S: GET /config, GET /products
S-->>B: 公開可能キー・通貨 / 商品一覧
U->>B: カートに入れる(localStorageに保存)
U->>B: レジに進む(/checkout)
B->>SJ: elements({mode:'payment', amount, currency})<br/>expressCheckout.mount()
SJ-->>B: ready(Apple Pay利用可否)
U->>SJ: Apple Payボタンを押す
SJ->>OS: 支払いシートを起動
U->>OS: Face IDで承認
OS-->>SJ: 承認結果
SJ-->>B: confirmイベント
B->>SJ: elements.submit()
B->>S: POST /create-payment-intent {items:[{id,qty}]}
S->>S: 商品IDと数量から金額を再計算・検証
S->>ST: paymentIntents.create(amount, jpy)
ST-->>S: client_secret
S-->>B: client_secret
B->>SJ: confirmPayment(elements, client_secret)
SJ->>ST: 決済確定(Apple Payのトークン)
ST-->>SJ: succeeded
SJ-->>B: paymentIntent
B->>B: カートを空にして /complete へ