Create Subscription Product
Create a subscription product with a billing period and multi-currency pricing.
POST /v1/actions/subscription-product/create-product
Authentication: API Key
Request Body
| Field | Type | Required | Description |
|---|
storeId | string | Yes | UUID of the store |
name | string | Yes | Product name |
billingPeriod | string | Yes | weekly, monthly, quarterly, or yearly |
prices | object | Yes | Multi-currency pricing (see Price Format) |
description | string | No | Product description |
media | array | No | Product images/videos |
successUrl | string | No | Redirect URL after subscription |
metadata | object | No | Custom key-value data |
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: "store-uuid",
name: "Pro Plan",
billingPeriod: BillingPeriod.Monthly,
prices: {
USD: { amount: 2900, taxIncluded: false, taxCategory: TaxCategory.SaaS },
EUR: { amount: 2700, taxIncluded: false, taxCategory: TaxCategory.SaaS },
},
});
Success Response
{
"data": {
"id": "product-uuid",
"storeId": "store-uuid",
"prodVersionId": null,
"testVersionId": "version-uuid",
"prodStatus": "inactive",
"testStatus": "active",
"createdAt": "2026-01-15T10:30:00.000Z",
"updatedAt": "2026-01-15T10:30:00.000Z",
"version": {
"id": "version-uuid",
"productId": "product-uuid",
"versionNumber": 1,
"name": "Pro Plan",
"description": null,
"prices": {
"USD": { "amount": 2900, "taxIncluded": false, "taxCategory": "saas" },
"EUR": { "amount": 2700, "taxIncluded": false, "taxCategory": "saas" }
},
"media": [],
"successUrl": null,
"metadata": null,
"createdAt": "2026-01-15T10:30:00.000Z"
}
}
}
Billing Periods
| Period | Frequency |
|---|
weekly | Every 7 days |
monthly | Every calendar month |
quarterly | Every 3 months |
yearly | Every 12 months |
Update Subscription Product
Update a subscription product’s content. Creates a new immutable version if content has changed.
POST /v1/actions/subscription-product/update-product
Authentication: API Key
Request Body
| Field | Type | Required | Description |
|---|
id | string | Yes | Product UUID |
name | string | Yes | Updated product name |
billingPeriod | string | Yes | weekly, monthly, quarterly, or yearly |
prices | object | Yes | Updated multi-currency pricing |
description | string | No | Updated description |
media | array | No | Updated media |
successUrl | string | No | Updated redirect URL |
metadata | object | No | Updated metadata |
Update Status
Activate or deactivate a subscription product.
POST /v1/actions/subscription-product/update-status
Authentication: API Key
Request Body
| Field | Type | Required | Description |
|---|
id | string | Yes | Product UUID |
status | string | Yes | active or inactive |
Deactivating a subscription product prevents new signups but does not cancel existing active subscriptions.
Publish Product
Publish a subscription product from test to production environment. This is a one-way operation.
POST /v1/actions/subscription-product/publish-product
Authentication: API Key
Request Body
| Field | Type | Required | Description |
|---|
id | string | Yes | Product UUID |
Publishing copies the current test version to production. This action is only available for the first publish. Subsequent version updates in test require re-publishing.
Subscription Product Groups
Product groups organize related subscription products (e.g., Free, Pro, Enterprise plans) and enable shared trial management.
Create Group
POST /v1/actions/subscription-product-group/create-group
Authentication: API Key
Request Body
| Field | Type | Required | Description |
|---|
storeId | string | Yes | UUID of the store |
name | string | Yes | Group name (e.g., “Pricing Plans”) |
description | string | No | Group description |
rules | object | No | Group rules (see below) |
productIds | array | No | Array of subscription product UUIDs to include |
Rules
| Field | Type | Default | Description |
|---|
sharedTrial | boolean | false | When true, trial usage is shared across all products in the group |
Example Request
const { group } = await client.subscriptionProductGroups.create({
storeId: "store-uuid",
name: "Pricing Plans",
description: "Free, Pro, and Enterprise tiers",
rules: { sharedTrial: true },
productIds: ["product-uuid-1", "product-uuid-2", "product-uuid-3"],
});
Success Response
{
"data": {
"group": {
"id": "group-uuid",
"storeId": "store-uuid",
"name": "Pricing Plans",
"description": "Free, Pro, and Enterprise tiers",
"rules": { "sharedTrial": true },
"productIds": ["product-uuid-1", "product-uuid-2", "product-uuid-3"],
"environment": "test",
"createdAt": "2026-01-15T10:30:00.000Z",
"updatedAt": "2026-01-15T10:30:00.000Z"
}
}
}
Update Group
POST /v1/actions/subscription-product-group/update-group
Authentication: API Key
Request Body
| Field | Type | Required | Description |
|---|
id | string | Yes | Group UUID |
name | string | No | Updated group name |
description | string | No | Updated description |
rules | object | No | Updated rules |
productIds | array | No | Updated product list (replaces entire list) |
The productIds field replaces the entire product list. To add a product, include all existing product IDs plus the new one.
Delete Group
POST /v1/actions/subscription-product-group/delete-group
Authentication: API Key
Request Body
| Field | Type | Required | Description |
|---|
id | string | Yes | Group UUID |
This is a permanent deletion (not soft delete). The products within the group are not deleted — only the grouping is removed.
Publish Group
POST /v1/actions/subscription-product-group/publish-group
Authentication: API Key
Request Body
| Field | Type | Required | Description |
|---|
id | string | Yes | Group UUID |
Unlike product publishing, group publishing supports repeated UPSERT operations. You can re-publish a group after making changes.