既存の checkout session からワンタイム購入注文を作成し、ホスト型 PSP 決済 URL を返します。
POST /v1/actions/onetime-order/create-order
認証: Session Token — Customer Endpoints を参照(customer または shopper ロール)
チェックアウトフロー
- マーチャントがまず Checkout Session の作成 を呼び出して製品バージョン、価格、通貨をロックし、
sessionId を取得
- 買い手はホスト型チェックアウトページ(または独自 UI)で請求情報を確認
- このエンドポイントを呼び出して注文を確定 — サーバが価格をスナップショットし、
billingDetail を基に税額を計算、注文を書き込み、PSP checkout を作成
- 買い手は返された
checkoutUrl にリダイレクトされ決済を完了
- 価格スナップショット:注文作成時に価格を固定。以降の製品価格変更はこの注文に影響しません
- 税額計算:
billingDetail(国、US/CA の州、EU の事業者 VAT)から税額を計算
- PSP フォールトトレランス:PSP 呼び出しが失敗した場合、注文は自動的にロールバックされ、安全にリトライできます
- メール正規化:サーバは税額計算、注文保存、Session 書き戻し、PSP 呼び出しの前に
buyerEmail を trim().toLowerCase() で正規化。Foo@Bar.COM と foo@bar.com は同一買い手として扱います
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|
checkoutSessionId | string | Yes | Checkout Session 作成で返された session ID |
billingDetail | object | 条件付き | 買い手の請求情報(下記参照)。Session に事前入力がない場合は必須 |
buyerEmail | string | 条件付き | 買い手のメールアドレス。Session に事前入力がない場合は必須。Session token が買い手の身元を保持する場合は無視されます |
buyerIp | string | No | 買い手の IP アドレス(税額計算の精度向上に使用) |
successUrl | string | No | Session に設定された成功時リダイレクト URL を上書き |
storeId、productId、currency は checkout session にロック済みです。ボディで渡しても無視されます。
Billing Detail オブジェクト
| フィールド | 型 | 必須 | 説明 |
|---|
country | string | Yes | ISO 3166-1 alpha-2 国コード |
isBusiness | boolean | Yes | 事業者購入かどうか |
postcode | string | No | 郵便番号 |
state | string | 条件付き | US および CA の場合は必須 |
businessName | string | 条件付き | isBusiness が true の場合は必須 |
taxId | string | 条件付き | EU 国 + isBusiness が true の場合は必須(VAT 番号) |
リクエスト例
import { WaffoPancake } from "@waffo/pancake-ts";
const client = new WaffoPancake({
sessionToken: window.WAFFO_SESSION_TOKEN, // マーチャントのポータルから注入
environment: "prod",
});
const result = await client.orders.createOnetime({
checkoutSessionId: "cs_550e8400-e29b-41d4-a716-446655440000",
buyerEmail: "customer@example.com",
billingDetail: {
country: "US",
isBusiness: false,
state: "CA",
},
successUrl: "https://example.com/thank-you",
});
console.log(result.checkoutUrl); // "https://checkout.stripe.com/c/pay/cs_xxx"
成功レスポンス (200)
{
"data": {
"checkoutUrl": "https://checkout.stripe.com/c/pay/cs_xxx"
}
}
レスポンスフィールド
| フィールド | 型 | 説明 |
|---|
checkoutUrl | string | ホスト型 PSP 決済 URL — 買い手をここにリダイレクトして決済を完了 |
エラー
リトライポリシー:4xx は一切リトライしない — リクエストを修正してから再送信。5xx は指数バックオフでリトライ(5s 開始、最大 3 回)。
| ステータス | errors[0].message | 意味 | 推奨処理 |
|---|
| 400 | Invalid JSON body | リクエストボディが有効な JSON ではない | ボディを修正してから再送信 |
| 400 | Missing required field: checkoutSessionId | checkoutSessionId が提供されていない | ボディを修正してから再送信 |
| 400 | Session product type mismatch: expected onetime | Session がサブスクリプション製品で作成されている | 新しいワンタイム session を作成してリトライ |
| 400 | Environment mismatch between request and session | X-Environment が session の環境と一致しない | 一致する環境を使用して再送信 |
| 400 | Missing billingDetail: provide in request body or pre-fill in checkout session | リクエストにも session にも billingDetail がない | billingDetail を提供してから再送信 |
| 400 | State is required for US/CA | billingDetail バリデーション失敗 | billingDetail を修正してから再送信 |
| 400 | Missing buyerEmail: provide in request body or pre-fill in checkout session | リクエストにも session にも買い手メールがない | buyerEmail を提供してから再送信 |
| 401 | Authentication failed | Session token が無効、期限切れ、または不正な形式 | Issue Session Token で再発行 |
| 403 | Session does not belong to this store | Session が別のストアのもの | 呼び出し元のストアに属する session を使用 |
| 409 | Checkout session invalid, please re-enter checkout | Session が存在しないか期限切れ | 新しい checkout session を作成してフローを再開 |
| 500 | Internal server error | サーバ側の予期しない障害 | 指数バックオフでリトライ(5s 開始、最大 3 回) |