Skip to main content
POST /v1/actions/subscription-product/create-product
Authentication: API Key

Request Body

FieldTypeRequiredDescription
storeIdstringYesStore ID (STO_xxx format)
namestringYesProduct name (max 64 chars)
billingPeriodstringYesweekly, monthly, quarterly, or yearly
pricesobjectYesMulti-currency pricing (see Price Format)
descriptionstring | nullNoProduct description (supports Markdown; pass null or "" to clear)
mediaarrayNoProduct images/videos (see Media Format)
successUrlstring | nullNoRedirect URL after successful subscription (max 512 chars, must be a valid http(s) URL; pass null or "" to clear)
metadataobjectNoCustom key-value data. May include trialDays (integer, 1-365) to offer a free trial period

Example Request

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 },
});

Success Response (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"
    }
  }
}

Response Fields

The response is wrapped in data.product. The product object is a flattened detail view combining product and version fields.
FieldTypeDescription
idstringProduct ID (PROD_xxx)
storeIdstringStore ID (STO_xxx)
namestringProduct name (from current version)
descriptionstring | nullProduct description (from current version)
billingPeriodstringBilling period: weekly, monthly, quarterly, or yearly
pricesobjectMulti-currency pricing map (see below)
mediaarrayMedia items (from current version)
successUrlstring | nullSuccess redirect URL (from current version)
metadataobjectCustom metadata (from current version, may include trialDays)
statusstringStatus in the current environment: active or inactive
createdAtstringProduct creation timestamp (ISO 8601)
updatedAtstringProduct last update timestamp (ISO 8601)
Response price object (per currency):
FieldTypeDescription
amountstringPrice as a display format string (e.g., “29.00”)
taxCategorystringTax category for tax calculation

Errors

Retry policy: Never retry 4xx — fix the request and resubmit. Retry 5xx with exponential backoff (start 5s, max 3 attempts).
Statuserrors[0].messageWhat it meansRecommended handling
400Missing header: x-context-merchant-idThe merchant context header was not forwardedFix your SDK configuration
400Missing or invalid header: x-context-environmentEnvironment header is missing or not test / prodSet X-Environment to test or prod
400Missing required field: storeId / Missing required field: name / Missing required field: prices (must have at least one currency)A required body field was omittedAdd the missing field, resubmit
400Expected format: STO_xxx, got "X"storeId is not a valid Short IDUse a STO_ prefixed Short ID
400Invalid or missing billingPeriodbillingPeriod is not one of weekly / monthly / quarterly / yearlyUse one of the four allowed values
400Invalid currency code: "X". Must be 3 uppercase letters (e.g., "USD", "EUR", "JPY")A key in prices is not a valid ISO 4217 codeUse 3 uppercase letters
400Invalid amount for X: "Y". Must be a positive number string (e.g., "9.99", "1000")Amount string couldn’t be parsedUse a positive decimal string
401UnauthorizedAuthentication failedVerify API key, timestamp, and signature
404Store not foundThe decoded storeId does not exist (foreign key violation)Verify the store belongs to your merchant account
500Internal server errorTransient downstream failureRetry with exponential backoff (start 5s, max 3 attempts)