セッション
CheckoutSession はバイヤーが操作するものです — TTL 付きで 1 回限り、 ホスト型チェックアウト URL を所有するオブジェクトです。3 つのコア エンティティの中で最も薄く、重い処理は Orders と Payment Intents (下記) で行われます。
3 エンティティのデータモデル
CheckoutSession ← 1:1 → Order ← 1:N → PaymentIntent
(buyer) (catalog) (each pay attempt)| エンティティ | 目的 | 寿命 |
|---|---|---|
| CheckoutSession | バイヤー向け — session_key、checkout_url、TTL を持つ | 分単位 (デフォルト 30) |
| Order | あなたのカタログ状態 — 行明細、合計、返金 | 永続レコード |
| PaymentIntent | 1 つのチェーン / アセットでの 1 回の支払い試行 | 時間単位; 精算または期限切れ |
セッションと注文は (POST /b2b/v1/checkout-sessions/quick 経由で)
一緒に作成します。チェックアウトページでバイヤーがアセットを選ぶたびに、
新しい PaymentIntent が該当チェーンに対して開かれます。途中で
アセットを切り替えると、前のインテントは EXPIRED に移り、新しい
ものが始まります。
識別子
セッションは session_key で識別されます:
cst_G-SO92J7HNWkwMHEHjD4oO1ZURL セーフで、プレフィックス後は約 24 文字 (18 バイトのランダム値を
base64url エンコード、パディングなし)。ホスト型チェックアウトページは
https://checkout.infraio.xyz/<session_key> です — セッションキーを
そのチェックアウト用のベアラ資格情報として扱ってください。
ライフサイクル — CheckoutSession
| 状態 | 意味 |
|---|---|
ACTIVE | セッションが作成されオープン。チェックアウト URL は使用可能。 |
COMPLETED | このセッション上の PaymentIntent が精算。Order は PAID (または過少支払いなら PARTIAL_PAID)。 |
EXPIRED | 精算なしに expires_at が経過。クリーンアップワーカーが状態を遷移させ、オープンな Order をキャンセル。 |
CANCELED | 明示的キャンセル — バイヤーが “cancel” を押したか、キャンセルエンドポイントを呼び出した。 |
3 つの終端状態は相互排他的かつ最終的です。同じ Order に対する新しい CheckoutSession は、リトライしたい場合 (例: 過少支払い後) に作成 できます。
TTL
- デフォルト: 30 分 (作成時の
expires_inフィールドで秒単位で設定可能)。 - 境界: サーバー側で強制される min/max はありません。妥当な値を 使ってください — 60 秒未満では正当なバイヤーがタイムアウトする リスクがあり、7 日超ではほぼ確実に放棄されたトークンに容量を 保持してしまいます。バイヤーの想定意思決定ウィンドウに合った 数値を選んでください。
- マーチャント別デフォルト: ダッシュボードで設定可能ですが、
これを尊重するのは レガシーの
POST /b2b/v1/checkout-sessions(2 ステップ) パスのみ です。POST /b2b/v1/checkout-sessions/quickパスはexpires_inが省略された場合、マーチャント別設定にかかわらず 常に 30 分 にフォールバックします。quick パスで異なるデフォルトが 必要な場合、毎回expires_inを明示的に送ってください。 - 強制: 読み取り時の遅延適用 + 定期的なクリーンアップワーカー。
expires_atを過ぎたセッションは、状態フィールドがまだ書き込まれて いなくてもEXPIREDとして扱われるので、期限切れの正確な瞬間に API 経由で状態を読むことに依存しないでください。
過少支払い
バイヤーがセッション額より少なく送ると、PaymentIntent は部分額で
精算し、Order は PARTIAL_PAID に遷移します。CheckoutSession は
COMPLETED に移ります (PaymentIntent が 1 つ精算した) ので、もはや
再利用できません。
不足分を全額支払いとして受け入れて Order を PAID に解決するには —
コンセプト → 注文 を参照 (現状公開の resolve API は
ありません; セルフサーブフローでは代わりに残額を回収してください)。
残額を回収するには、同じ Order に対して残額の 新しい CheckoutSession
を作成してください。
過剰支払い
バイヤーがセッション額より多く送ると (レアですが、手動送金で発生)、 オンチェーンスキャナが 24 時間以内に過剰支払いを捕捉し、マーチャント アラートを発火します。自動返金はありません — 返金 API または ダッシュボードから手動で発行してください。
誤アセット支払い
デポジットアドレスは (session, chain, asset) のタプルごとに生成
されます。バイヤーがアドレスに誤ったアセットを送ると、オンチェーン
マッチャーは認識せず、PaymentIntent は TTL 切れまでオープンのままです。
資金を回収することは可能ですが、サポートフローで自動ではありません —
バイヤーにはチェックアウトページに表示されている正確なアセットを
送るよう案内してください。
作成時の冪等性
POST /b2b/v1/checkout-sessions/quick はリクエストボディに
idempotency_key フィールドを受け付けます (注意: ボディフィールドで、
HTTP ヘッダーではありません)。クライアントに自然キーがない場合は、
フィールドに UUID を自動生成してください — SDK はデフォルトでこれを
行います。
このキーは CheckoutSession ではなく Order を重複排除します。同じ
キーでリトライすると、/quick は 元の Order を返し (order_id は
安定)、新しい CheckoutSession を発行します — 毎回新しい
session_key と checkout_url です。これは意図的です:1 つの Order は
複数のチェックアウト試行を背負えるため (Orders
を参照)、リトライされた /quick は Order を重複させずにバイヤーへ
クリーンなセッションを渡します。
2 つの挙動が Stripe 風の冪等性レイヤと異なります — 引っかからないように 注意してください:
- ボディはハッシュも比較もされません。 異なる ボディでキーを
再利用しても
409は 返りません — サーバーはそのキーで既に 保存された Order を黙って返し、新しいボディを無視します。したがってidempotency_keyは 1 つの論理的な Order に対する使い切りトークン として扱い、異なるカートをまたいで使い回さないでください。 - 重複排除されるのは Order だけで、セッションではありません。
同じ チェックアウト URL が必要な場合は、最初のレスポンスから
session_key/checkout_urlを永続化してください —/quickを 再度呼んでも古いものは返りません。ある Order に対して発行された全 セッションを列挙するには、GET /b2b/v1/checkout-sessions/by-order/:order_idを使ってください。
API エンドポイント
| メソッド | パス | 備考 |
|---|---|---|
POST | /b2b/v1/checkout-sessions/quick | 1 回の呼び出しで Order + セッションを作成 |
POST | /b2b/v1/checkout-sessions | 既存の注文に対してセッションを作成 |
GET | /b2b/v1/checkout-sessions/by-order/:order_id | 注文に対する全セッションを一覧表示 (リトライ履歴用) |
GET | /checkout/:session_key | 公開 — バイヤーのブラウザが叩く |
作成リクエストの完全なボディと署名は クイックスタート を参照してください。
次に
- コンセプト → 注文 — Order エンティティ (フルフィルメントの真実のソースとして扱うもの)。
- コンセプト → チェーン & アセット — サポート ネットワークとチェーンごとのファイナリティ仮定。
- Webhook → 概要 — 各セッション状態遷移で 発火するイベント。