Skip to main content
商品バージョン、価格、通貨を固定するチェックアウトセッションを作成します。これは単発商品とサブスクリプション商品の両方のチェックアウトフローの最初のステップです。 一般的なフローは以下の通りです。
  1. マーチャントがチェックアウトセッションを作成(サーバーサイド)
  2. フロントエンドに checkoutUrl を返す
  3. customer がリンクをクリックしてホスティングされたチェックアウトページに移動
  4. customer が請求情報を入力し、税額をプレビューし、注文を完了
認証: API Key または Store Slug

リクエストボディ(API Key)

リクエストボディ(Store Slug)

Store Slug 認証では、クライアントサイドからの価格改ざんやセッション操作を防止するため、priceSnapshotexpiresInSecondsmetadataorderMerchantExternalIdwithTrialchangeAmountchangeCreditAmountincludePaymentMethodsexcludePaymentMethods はサポートされません(黙って無視されます)。決済手段は加盟店側の商業判断(チャネル手数料・精算サイクル)であり、ブラウザからの絞り込み・拡大は認められません——Store Slug で作成された session は常にその通貨がサポートする全手段を提供します。
ID 命名規約:同じフラット双キー名(checkout 側の orderMerchantExternalId、返金チケット側の refundTicketMerchantExternalId)が、リクエストボディ、webhook ペイロード、そしてその値を保持する全ての GraphQL 型を通じて使用されます — checkout 作成時に書き込んだ値は OrderPaymentRefund、webhook ペイロードのいずれからも同じフィールド名で読み戻せます。
cancelUrl はありません。 購入者がチェックアウトを閉じたり支払いを中断した場合、あなたのサイトへ戻すリダイレクトは発生しません。セッションは期限切れ(デフォルト 45 分)となり、注文は課金なしで canceled で終了し、webhook も送信されません —— 対応は不要です。cancelUrlreturnUrl などのフィールドを送信しても黙って無視されます。チェックアウトを開いたページ側に「ストアに戻る」リンクを用意しておいてください。

Price Snapshot オブジェクト

単発商品では amount が商品価格をそのまま置き換えます。サブスクリプション商品では通常周期の価格のみを置き換え、トライアル期間の価格はセッションにロックされた商品バージョンから取得されるため、ここでは上書きできません。

Billing Detail オブジェクト

billingDetail はチェックアウトの事前入力にしか使われません。送信した国は編集可能な国セレクターの初期値になり(加盟店の値は IP 判定より優先)、購入者は変更でき、注文に記録されるのは購入者が最終的に選んだ国です。請求フィールドをロックしたり非表示にするセッションパラメータや URL パラメータはありません。決済手段は国では決まりません。商品タイプ × 通貨と includePaymentMethods / excludePaymentMethods から解決され、国は税額プレビューと表示する住所フィールドの決定にのみ使われます。

プラン変更モード

originOrderId を指定すると、このエンドポイントはプラン変更モードに切り替わります。返される checkoutUrl は新規購入リンクではなく、既存サブスクリプションの変更確認ページを指します —— ストア slug の後のパスセグメントが checkout ではなく change になります(…/store/{storeSlug}/change/{sessionId})。プラン変更は 2 ステップです —— このエンドポイントがリンクを発行し、customer がそのページで確認します。 プラン変更は 1 回の解約と 1 回の新規作成としてモデル化されます。変更元の注文は解約の終端状態に入り、新しい注文は通常の作成ライフサイクルを進みます。既存サブスクリプションをその場で書き換えるものではありません。 誰がリンクを発行できるか:API Key(あなたのサーバーサイド)または customer のセッショントークン。Store Slug は匿名であり、変更を帰属させられるサブスクリプションを持たないため、Store Slug 認証で originOrderId を指定すると必ず 403 を返します。

SDK でリンクを発行する

どの SDK もプラン変更に専用メソッドを用意しており、originOrderId は必須です。そのため上記の「originOrderId と同時にのみ有効」という拒否は SDK 上では表現できません:
上記の 3 つは API Key で署名するため、2 つの価格フィールドと withTrial は有効です。checkout.authenticated.createPlanChange()(TypeScript / Next.js は authenticatedPlanChange)または Checkout.Authenticated.CreatePlanChange(Go)を使うと、customer セッショントークンの付加を SDK に任せられます —— それが次節で説明する確認ページに必要なトークンです。 顧客が自分で発行する側は customer.createPlanChangeSession() を customer セッション上で呼び出します(TypeScript は client.customer(token)、Go は client.Customer(token)、Next.js は customerAction(token, "createPlanChangeSession", …))。顧客自身の資格情報で実行されるため上記 3 つの 403 判定がすべて適用され、API Key 専用フィールドはその入力型に存在しません —— プラットフォームはそれらを通知なく破棄するためです。

買い手が開くリンクの組み立て

返される checkoutUrl には買い手の資格情報も環境フラグも含まれません —— セッションはサーバーサイドの資格情報で作成されるため、その時点でプラットフォームは買い手を保証できません。素の URL を開くとプラン比較ページは表示されますが、確認ステップで「認可情報がありません」というエラーになります。両方を自分で付加してください:
クエリパラメータが先、fragment が後です。本番環境では ?test=true を外します。 トークンなしの場合、ページは買い手のメール認証にフォールバックします —— 動作はしますが遅い経路です。環境が誤っているリンクは、以前は確認ステップで Environment mismatch between request and session エラーになっていました。
changeAmountchangeCreditAmountwithTrialAPI Key のみです。他の資格情報で指定した場合、新規購入時の priceSnapshot と同じ扱いで黙って無視されます —— 破棄されたことを知らせるエラーは返りません。

変更元サブスクリプションから引き継がれる値

プラン変更モードでは、以下の値はリクエストボディではなく変更対象のサブスクリプションから取得されます。 通貨も変更元サブスクリプションと一致する必要があります —— 通貨をまたぐプラン変更は拒否されます。

この変更の価格の決め方

同じ変更の価格を決める方法が 2 つあり、両者は排他です —— 同時に指定すると 400 を返します。 どちらも表示フォーマットの文字列で、単位も税基準(税込)も同じです。結果が負にならないことも共通で、対象プランの当期請求額を超える請求額は拒否され、それを超えるクレジットも拒否されます。2 つの拒否メッセージは別々なので、どちらのフィールドを下げるべきか分かります。 同じ数値でも 2 つのフィールドでは意味が逆になるため、プラットフォームが一方を選ぶことはありません。価格の決め方に合う方を選んでください:最終金額が分かっているなら changeAmount、割引額が分かっているなら changeCreditAmount です。以下のタイミング規則にとっては、どちらを指定しても「加盟店がこの変更の価格を決めた」と扱われます。 セッション内部で保持するのは当期の請求額という 1 つの基準だけなので、指定したクレジットは発行時点の対象プランの請求額を用いて請求額に換算されます。

新プランが適用されるタイミング

changeTimingimmediate または next_period を受け付けます。省略するとプラットフォームが変更方向から導出し、方向は税抜価格の比較で判定されます。アップグレードは immediate、ダウングレードと同額切り替えは next_period がデフォルトです。
アップグレードは残り 24 時間を切っても自動で翌期に繰り下がりません。 アップグレードのデフォルトは immediate のため、次回請求まで 24 時間未満の状態で changeTiming を省略すると 400 になります —— changeTiming: "next_period" を明示的に指定してください。ダウングレードは元々 next_period がデフォルトなので、同じ条件でも影響を受けません。

確定済みの変更は同時に 1 件のみ

customer が迷っている間は、同じサブスクリプションに対して複数の変更候補を発行・提出できます。いずれかの変更が決済チャネルによって確定した時点でそのサブスクリプションは 1 件に固定され、それ以降の発行は 409 を返します。

レスポンス

レスポンスボディは新規購入モードと完全に同一です —— sessionIdcheckoutUrlexpiresAt のみで、追加フィールドはありません。変更方向、導出されたタイミング、日割りクレジットのプレビューは確認ページが読むためにセッションへ書き込まれるだけで、レスポンスには返りません。結果として 2 点に注意が必要です。
  • changeTiming を省略した場合、プラットフォームがどちらを導出したかは分かりません。確実にしたい場合は明示的に指定してください。
  • 日割りクレジットは発行時点の見積りであり、提出時に実際の残日数で再計算されます。最終金額として customer に提示しないでください。
  • next_period の変更ではカード確認のため $0 の支払いレコードが作成されます。Dashboard の取引一覧ではその行にプラン価格が表示され、その下に Charged $0.00 と示されます。サブスクリプションの課金回数には含まれません。
変更が確定した後に届くものは subscription.plan_changed と 2 つのプラン変更イベント を参照してください。アップグレード・ダウングレードの customer 向けの挙動は サブスクリプション を参照してください。

セッションロック

チェックアウトセッション作成時に以下の値がロックされ、セッションの有効期間中は変更できません。 productVersionIdproductNamepriceInfostoreNamebillingPeriodwithTrialthemebuyerEmailbillingDetail プラン変更モードでは、セッションは変更コンテキストも追加でロックします。変更元サブスクリプションのスナップショット、変更方向、導出されたタイミングと適用時刻、日割りクレジットのプレビュー、および指定した金額(changeCreditAmount を指定した場合は換算後の請求額)です。確認ページはすべてをセッションから読むため、提出時にこれらを上書きすることはできません —— 対象プラン、タイミング、金額はリンクを発行した時点で確定します。 メールアドレスの正規化:すべてのメールフィールド(email / buyerEmail / contactEmail)はサーバー側で trim().toLowerCase() により正規化されてから保存・キャッシュ・下流呼び出しに使用されます。Foo@Bar.COMfoo@bar.com は同一アカウントとして扱われます。

リクエスト例

成功レスポンス (200)

レスポンスフィールド

エラー

リトライポリシー:4xx は一切リトライしない — リクエストを修正してから再送信。以下の 409 は種類としての例外であり、ポリシーの例外ではありません:ボディの不備ではなくサブスクリプションの状態を報告しているため、同じリクエストを再送信してもその状態が変わるまで失敗し続けます。5xx は指数バックオフでリトライ(5s 開始、最大 3 回)。
入金受付スイッチと本番承認は互いに独立した 2 つの条件です:前者はプラットフォーム側が制御する入金受付スイッチ(ストア全体の停止も、個別の決済手段のみの停止も可能)、後者は本番承認(KYB)のゲートです。prod 環境では、いずれか一方が満たされないだけで 403 になります。どちらも test 環境には適用されません。
デフォルトのセッション TTL は 45 分(2700 秒)です。API Key 認証を使用する場合、expiresInSeconds でカスタマイズできます(上限は検証されません)。セッションは作成時に商品バージョンと価格をロックするため、価格変更は既存のセッションに影響しません。