Skip to main content
POST
Create Plan

Authorizations

Authorization
string
header
required

JWT issued by POST /api/v1.1/access-token/b2b. Send Authorization: Bearer <token>.

X-PARTNER-ID
string
header
required

Merchant API key (Credential.api_key). Required on every request.

Body

application/json

Payload for CreateSubscriptionPlanRequest. Exactly one of amount or items must be present (mutually exclusive). Per-cycle charge (amount-only or sum of quantity * unit_price) must be at least IDR 10,000 when greater than zero (ChannelType::MIN_CARD_AMOUNT_IDR).

name
string
required

Human-readable plan name.

Maximum string length: 255
Example:

"Monthly Pro Subscription"

customer_name
string
required

Full name of the subscribing customer.

Maximum string length: 191
Example:

"John Doe"

customer_email
string<email>
required

Customer email address.

Maximum string length: 191
Example:

"john.doe@example.com"

customer_phone
string
required

Customer contact phone number.

Maximum string length: 50
Example:

"081234567890"

account_id
string
required

Account ULID owned by the authenticated merchant.

Maximum string length: 50
Example:

"01K5G4FZZ18DMK0M5QTR8Y9QY9"

schedule
object
required

Billing schedule that controls how often and how many times the plan charges the customer.

subscription_id
string | null

Stored in sub_plans.reference_id; must be unique on that column when provided.

Maximum string length: 100
Example:

"SUB-2026-0001"

merchant_reff_no
string | null

Optional merchant reference number for reconciliation.

Maximum string length: 255
Example:

"REF-0001"

amount
number

Per-cycle charge in IDR. Use without items for amount-only plans.

Required range: x >= 0
Example:

150000

currency
string | null

ISO 4217 currency code. Defaults to IDR.

Required string length: 3
Example:

"IDR"

items
object[]

Use without amount for itemized plans; per-cycle total = sum of quantity * unit_price.

Minimum array length: 1
customer_id
string | null

Optional merchant-side customer identifier.

Maximum string length: 100
Example:

"CUST-001"

payment_type
enum<string> | null

Preferred payment instrument for the plan.

Available options:
credit_card,
gopay
Example:

"credit_card"

return_url
string<uri> | null

URL the customer is redirected to after completing payment setup.

Maximum string length: 2048
Example:

"https://merchant.example.com/subscription/return"

retry_policy
object | null

Optional retry policy applied to every cycle when a charge fails.

retry_count
integer | null
deprecated

Deprecated — use retry_policy.max_attempts.

Required range: 1 <= x <= 5
Example:

3

retry_interval_days
integer | null
deprecated

Deprecated — use retry_policy.interval_days.

Required range: 1 <= x <= 7
Example:

1

failed_payment_action
enum<string> | null
deprecated

Deprecated — use retry_policy.failed_payment_action.

Available options:
continue_plan,
stop_plan
Example:

"continue_plan"

charge_immediately
boolean | null

Charge the first cycle immediately on creation instead of waiting for start_time.

Example:

false

allow_manual_payment
boolean | null

Allow the customer to pay bills manually via the payment link.

Example:

true

allow_user_notification
boolean | null

Send subscription notifications (reminders, receipts) to the customer.

Example:

true

metadata
object | null

Free-form metadata stored with the plan.

Response

SP000 Successfully — plan created (data is RecurringPlanData).

Merchant v2 envelope returned on a successful plan operation (SP000). Used by create (HTTP 201), show, update, and cancel (HTTP 200). The data.upgrade block is present only on an upgrade/downgrade.

response_code
string
required

SingaPay custom business response code.

Example:

"SP000"

response_message
string
required

Human-readable label paired with response_code.

Example:

"Successfully"

data
object
required

data object shape from SubscriptionPlanResource (success responses).