POST /v1/actions/subscription-product/create-product
リクエストボディ
| フィールド | 型 | 必須 | 説明 |
|---|---|---|---|
storeId | string | Yes | Store ID(STO_xxx フォーマット) |
name | string | Yes | 商品名(64 文字以下) |
billingPeriod | string | Yes | weekly、monthly、quarterly、または yearly |
prices | object | Yes | マルチ通貨価格(価格フォーマットを参照) |
description | string | null | No | 商品説明(Markdown 対応;null または "" で消去可能) |
media | array | No | 商品画像/動画(メディアフォーマットを参照) |
successUrl | string | null | No | サブスクリプション成功後のリダイレクト URL(512 文字以下、有効な http(s) URL であること;null または "" で消去可能) |
metadata | object | No | カスタムキー値データ。無料トライアル期間を提供するために trialDays(整数、1-365)を含めることができます |
リクエスト例
import { WaffoPancake, BillingPeriod, TaxCategory } from "@waffo/pancake-ts";
const client = new WaffoPancake({
merchantId: process.env.WAFFO_MERCHANT_ID!,
privateKey: process.env.WAFFO_PRIVATE_KEY!,
});
const { product } = await client.subscriptionProducts.create({
storeId: "STO_2D5F8G3H1K4M6N9P",
name: "Pro Plan",
billingPeriod: BillingPeriod.Monthly,
prices: {
USD: { amount: "29.00", taxIncluded: false, taxCategory: TaxCategory.SaaS },
EUR: { amount: "27.00", taxIncluded: false, taxCategory: TaxCategory.SaaS },
},
description: "Full access to all Pro features.",
successUrl: "https://example.com/welcome",
metadata: { trialDays: 14 },
});
curl -X POST https://api.waffo.ai/v1/actions/subscription-product/create-product \
-H "Content-Type: application/json" \
-H "X-Merchant-Id: MER_7K3M9P2R5T8W1Y4Z" \
-H "X-Timestamp: 2026-03-30T10:00:00Z" \
-H "X-Signature: BASE64_RSA_SIGNATURE" \
-d '{
"storeId": "STO_2D5F8G3H1K4M6N9P",
"name": "Pro Plan",
"billingPeriod": "monthly",
"prices": {
"USD": { "amount": "29.00", "taxIncluded": false, "taxCategory": "saas" },
"EUR": { "amount": "27.00", "taxIncluded": false, "taxCategory": "saas" }
},
"description": "Full access to all Pro features.",
"successUrl": "https://example.com/welcome",
"metadata": { "trialDays": 14 }
}'
import requests
# Assumes you have a sign_request() helper for RSA-SHA256 signing
headers = sign_request("POST", "/v1/actions/subscription-product/create-product", body)
body = {
"storeId": "STO_2D5F8G3H1K4M6N9P",
"name": "Pro Plan",
"billingPeriod": "monthly",
"prices": {
"USD": {"amount": "29.00", "taxIncluded": False, "taxCategory": "saas"},
"EUR": {"amount": "27.00", "taxIncluded": False, "taxCategory": "saas"},
},
"description": "Full access to all Pro features.",
"successUrl": "https://example.com/welcome",
"metadata": {"trialDays": 14},
}
response = requests.post(
"https://api.waffo.ai/v1/actions/subscription-product/create-product",
json=body,
headers=headers,
)
data = response.json()
成功レスポンス (200)
{
"data": {
"product": {
"id": "PROD_3F7H2J5L8N1Q4S6U",
"storeId": "STO_2D5F8G3H1K4M6N9P",
"name": "Pro Plan",
"description": "Full access to all Pro features.",
"billingPeriod": "monthly",
"prices": {
"USD": { "amount": "29.00", "taxCategory": "saas" },
"EUR": { "amount": "27.00", "taxCategory": "saas" }
},
"media": [],
"successUrl": "https://example.com/welcome",
"metadata": { "trialDays": 14 },
"status": "active",
"createdAt": "2026-03-30T10:30:00.000Z",
"updatedAt": "2026-03-30T10:30:00.000Z"
}
}
}
レスポンスフィールド
レスポンスはdata.product でラップされます。商品オブジェクトは、商品とバージョンのフィールドを結合したフラット化された詳細ビューです。
| フィールド | 型 | 説明 |
|---|---|---|
id | string | 商品 ID(PROD_xxx) |
storeId | string | Store ID(STO_xxx) |
name | string | 商品名(現在のバージョンから) |
description | string | null | 商品説明(現在のバージョンから) |
billingPeriod | string | 請求サイクル: weekly、monthly、quarterly、または yearly |
prices | object | マルチ通貨価格マップ(以下参照) |
media | array | メディアアイテム(現在のバージョンから) |
successUrl | string | null | 成功時のリダイレクト URL(現在のバージョンから) |
metadata | object | カスタムメタデータ(現在のバージョンから、trialDays を含む場合あり) |
status | string | 現在の環境でのステータス: active または inactive |
createdAt | string | 商品作成タイムスタンプ(ISO 8601) |
updatedAt | string | 商品最終更新タイムスタンプ(ISO 8601) |
| フィールド | 型 | 説明 |
|---|---|---|
amount | string | 表示フォーマット文字列としての価格(例:"29.00") |
taxCategory | string | 税計算用のカテゴリ |
エラー
リトライポリシー:4xx は一切リトライしない — リクエストを修正してから再送信。5xx は指数バックオフでリトライ(5s 開始、最大 3 回)。
| ステータス | errors[0].message | 意味 | 推奨処理 |
|---|---|---|---|
| 400 | Missing header: x-context-merchant-id | マーチャントコンテキスト header が転送されていない | SDK 設定を修正 |
| 400 | Missing or invalid header: x-context-environment | 環境 header が欠落、または test / prod ではない | X-Environment を test または prod に設定 |
| 400 | Missing required field: storeId / Missing required field: name / Missing required field: prices (must have at least one currency) | 必須フィールド欠落 | フィールドを追加して再送信 |
| 400 | Expected format: STO_xxx, got "X" | storeId が正しい Short ID ではない | STO_ 接頭辞付きの Short ID を使用 |
| 400 | Invalid or missing billingPeriod | billingPeriod が weekly / monthly / quarterly / yearly の集合に含まれない | 4 つの許可値のいずれかに変更 |
| 400 | Invalid currency code: "X". Must be 3 uppercase letters (e.g., "USD", "EUR", "JPY") | prices のキーが ISO 4217 コードに準拠していない | 3 文字の大文字を使用 |
| 400 | Invalid amount for X: "Y". Must be a positive number string (e.g., "9.99", "1000") | 金額文字列がパースできない | 正の十進数文字列を使用 |
| 401 | Unauthorized | 認証失敗 | API Key、タイムスタンプ、署名を確認 |
| 404 | Store not found | デコード後の storeId が存在しない(外部キー制約) | ストアが現在のマーチャントに帰属することを確認 |
| 500 | Internal server error | 一時的な下流障害 | 指数バックオフでリトライ(5s 開始、最大 3 回) |