Skip to main content

Subscriptions

Recurring billing — plans, stored payment methods, and the subscription lifecycle. Access via zenpays.subscriptions.

JavaScript only

The Python SDK does not yet expose a subscriptions namespace. Call the REST endpoints directly from Python.

Plans

A plan defines what is charged and how often. Subscriptions attach a customer to a plan.

createPlan

const plan = await zenpays.subscriptions.createPlan({
name: 'Pro Monthly',
amount: 2999,
currency: 'USD',
interval: 'month',
description: 'Pro tier, billed monthly',
intervalCount: 1, // 3 + 'month' would be quarterly
trialDays: 14,
})
ParameterTypeRequiredDescription
namestringYesPlan name shown to customers
amountnumberYesAmount charged each interval, in the currency's minor unit
currencystringYesISO 4217 currency code
interval'day' | 'week' | 'month' | 'year'YesBilling interval
descriptionstringNoLonger plan description
intervalCountnumberNoIntervals between charges. Defaults to 1
trialDaysnumberNoFree trial length in days
metadataRecord<string, unknown>NoArbitrary key/value data

Returns a SubscriptionPlan.

listPlans

const plans = await zenpays.subscriptions.listPlans()

Returns SubscriptionPlan[] for the authenticated merchant.

archivePlan

Stops new subscriptions on the plan. Existing subscriptions continue to bill.

const plan = await zenpays.subscriptions.archivePlan('plan_xxx')

getPublicPlan

Unauthenticated plan details, safe to render on a hosted subscribe page.

const plan = await zenpays.subscriptions.getPublicPlan('plan_xxx')

Payment methods

To charge a subscription automatically you need a stored payment method. Collect one on the client with a setup token, then store the resulting provider token.

createSetupToken

const setupToken = await zenpays.subscriptions.createSetupToken({
customerId: 'cust_xxx',
customerEmail: 'customer@example.com',
currency: 'USD',
})
ParameterTypeRequiredDescription
customerIdstringYesCustomer the method will belong to
customerEmailstringYesCustomer email
currencystringNoCurrency the method will be charged in
tspProviderstringNoForce a specific payment provider

storePaymentMethod

const method = await zenpays.subscriptions.storePaymentMethod({
customerId: 'cust_xxx',
customerEmail: 'customer@example.com',
tspToken: 'tok_from_provider',
tspProvider: 'stripe',
type: 'card',
last4: '4242',
brand: 'visa',
expiryMonth: 12,
expiryYear: 2028,
})

tspToken is the provider token representing the instrument the customer entered. Raw card details never reach ZenPays.

listPaymentMethods

const methods = await zenpays.subscriptions.listPaymentMethods('cust_xxx')

revokePaymentMethod

await zenpays.subscriptions.revokePaymentMethod('spm_xxx')

Subscription lifecycle

create

const subscription = await zenpays.subscriptions.create({
customerId: 'cust_xxx',
customerEmail: 'customer@example.com',
planId: 'plan_xxx',
storedPaymentMethodId: 'spm_xxx',
})
ParameterTypeRequiredDescription
customerIdstringYesCustomer to subscribe
customerEmailstringYesCustomer email
planIdstringYesPlan to subscribe them to
storedPaymentMethodIdstringNoMethod to charge. Omit to require setup first
tspProviderstringNoForce a specific payment provider
metadataRecord<string, unknown>NoArbitrary key/value data

list

const all = await zenpays.subscriptions.list()
const active = await zenpays.subscriptions.list('active')

Optionally filtered by SubscriptionStatus.

get

const subscription = await zenpays.subscriptions.get('sub_xxx')

cancel

Cancels at the end of the current billing period by default.

// At period end — the customer keeps access until currentPeriodEnd
await zenpays.subscriptions.cancel('sub_xxx')

// Immediately
await zenpays.subscriptions.cancel('sub_xxx', { immediately: true })

pause

const subscription = await zenpays.subscriptions.pause('sub_xxx')

resume

const subscription = await zenpays.subscriptions.resume('sub_xxx')

Types

SubscriptionStatus

'trialing' · 'active' · 'past_due' · 'paused' · 'cancelled'

SubscriptionPlan

FieldTypeDescription
planIdstringPlan identifier
merchantIdstringOwning merchant
namestringPlan name
descriptionstring?Plan description
amountnumberAmount per interval
currencystringISO 4217 currency code
intervalBillingInterval'day' | 'week' | 'month' | 'year'
intervalCountnumberIntervals between charges
trialDaysnumberFree trial length in days
status'active' | 'archived'Plan status
metadataRecord<string, unknown>?Arbitrary data

Subscription

FieldTypeDescription
subscriptionIdstringSubscription identifier
merchantIdstringOwning merchant
customerIdstringSubscribed customer
customerEmailstringCustomer email
planIdstringPlan being billed
statusSubscriptionStatusCurrent status
collectionMethod'auto_charge' | 'send_invoice'How each period is collected
storedPaymentMethodIdstring?Method charged automatically
tspProviderstring?Payment provider
currentPeriodStartstringISO 8601 timestamp
currentPeriodEndstringISO 8601 timestamp
nextBillingAtstringISO 8601 timestamp of the next charge
trialEndstring?ISO 8601 timestamp the trial ends
cancelAtPeriodEndbooleanWhether cancellation is pending
cancelledAtstring?ISO 8601 timestamp of cancellation
pausedAtstring?ISO 8601 timestamp of pause

StoredPaymentMethod

FieldTypeDescription
storedPaymentMethodIdstringMethod identifier
merchantIdstringOwning merchant
customerIdstringOwning customer
customerEmailstringCustomer email
tspProviderstringPayment provider
typestringInstrument type, e.g. card
brandstring?Card brand
expiryMonthnumber?Card expiry month
expiryYearnumber?Card expiry year
isActivebooleanWhether the method can still be charged
metadataRecord<string, unknown>?Arbitrary data