Guides
Packages, plans & customer subscriptions
Sell subscriptions from a catalogue of packages and plans: trials, renewals, dunning and collection by gateway, debit order or invoice.
On this page
- Overview
- Requirements
- Packages and plans
- Starting a subscription
- Collection methods
- Gateway (card)
- Debit order
- Invoice
- Statuses and lifecycle
- Trials
- Renewals and billing periods
- Quantity, setup fees and coupons
- Failed payments and dunning
- Pausing, cancelling and changing plan
- Subscription settings
- Emails, webhooks and notifications
- How this relates to gateway subscriptions
Overview#
Customer subscriptions let you sell recurring services from a catalogue. A package is the product you sell (for example "Acme Cloud"); each package has one or more plans, which are its price points (Starter monthly, Pro monthly, Pro annually…). A customer subscription links one of your customers to a plan and CentraPoint takes care of trials, billing periods, renewals, failed payments and cancellations. You manage them in the dashboard under Subscriptions, through the Customer subscriptions API, on hosted checkout pages, and customers can manage their own in the customer portal.
Requirements#
- A plan that includes Recurring billing (Growth and higher by default). The API endpoints also need the REST API; without Recurring billing they return
403 plan_restricted. - The
invoicecollection method also needs Invoicing, anddebit_orderneeds Debit orders (Business and higher by default) and a Netcash debit order provider. - Coupons on subscriptions need Coupons in your plan (see Coupons).
Packages and plans#
Create packages under Subscriptions → Packages or with POST /api/v1/packages. A package has a name, description, sort order, an enabled flag and an optional default gateway used for card subscriptions. Each plan has:
| Setting | Notes |
|---|---|
| Name, description, features | Features are bullet points shown on checkout pages and in the customer portal (up to 50). |
| Frequency | daily, weekly, biweekly, monthly, quarterly, biannually or annually. Gateways and debit orders can only collect monthly, quarterly, biannual and annual plans. |
| Amount and currency | Price per period per unit; ISO currency (default ZAR). A price of 0 makes a free plan that activates without payment. |
| Setup fee | One-off amount added to the first charge. |
| Trial days | Free trial for new subscriptions (0–730 days). |
| Billing cycles | Fixed number of paid periods (e.g. 12), after which the subscription expires. Empty = until cancelled. |
| Allowed gateways | Restrict which payment providers can collect the plan; empty = any enabled gateway. |
| Call to action / Contact us | Show the plan with a button to your own URL, or a contact option, instead of making it purchasable. |
| Enabled, sort order | Disabled plans can't be subscribed to; existing subscriptions keep billing. |
Starting a subscription#
A subscription can be started from four places, recorded as its source:
dashboard: Subscriptions → New subscription or the customer's page.api: POST /api/v1/customer-subscriptions. Send your ownexternalReferenceto make the call safe to repeat: the same reference returns the existing subscription.checkout: a customer signs up on a hosted checkout page or checkout session.portal: a signed-in customer subscribes in the customer portal.
The customer must be active and the plan and its package enabled. With a trial the subscription starts trialing; otherwise it starts incomplete and the first charge (setup fee plus the first period) is issued straight away. The API response's payment object tells you what is due and where the customer pays (payUrl).
Collection methods#
Every subscription has one collection method, chosen when it starts:
Gateway (card)#
collectionMethod: "gateway". The first payment is a CentraPoint payment link (emailed to the customer as a payment request unless sendEmail: false), created as a recurring link so that gateways with their own subscriptions (PayFast, Netcash Pay Now) set up a card subscription at checkout. From then on:
- Gateway-managed billing (PayFast, Netcash Pay Now): the gateway charges the card on its own schedule and CentraPoint tracks each renewal. If no renewal arrives within the gateway grace days after the billing date, the payment counts as failed. The amount and frequency of such a subscription can't be changed; cancel it and start a new one.
- Otherwise (gateways without their own subscriptions): each later period is an invoice with a pay link.
The gateway defaults to the package's default gateway; pass providerId to choose another allowed one.
Debit order#
collectionMethod: "debit_order". A Netcash debit order mandate collects each period on its debit day; ZAR monthly, quarterly, biannual or annual plans only. Pass an existing mandate of the customer with the same frequency as mandateId, or link one later from the subscription page (you can also create a mandate with subscriptionId through the Mandates API). The mandate amount follows the subscription amount; a setup fee is invoiced separately, because a mandate collects a fixed amount. With First invoice is pro forma on, the subscription's first invoice (normally that setup fee invoice) is issued as a pro forma (PRO FORMA INVOICE). During a trial the mandate's first debit moves to after the trial. Unpaid debits count as failed payments and can be re-presented by the debit order run.
Invoice#
collectionMethod: "invoice". CentraPoint creates and emails an invoice with a pay link for every period. An invoice unpaid after its due date (the invoice due days setting) counts as a failed payment. Invoices paid offline (recorded EFT or cash) still activate or renew the subscription.
Statuses and lifecycle#
| Status | Meaning |
|---|---|
incomplete | Waiting for the first payment. Expires after the incomplete expiry days (default 30) if nothing is paid. |
trialing | In its free trial; the first charge is issued when the trial ends. |
active | Paid up and billing normally. |
past_due | A payment failed; dunning is running. |
paused | Billing stopped until resumed. |
cancelled | Cancelled by you, the customer or dunning. Final. |
expired | Ended on its own: fixed term completed, first payment never arrived, or dunning set to expire. Final. |
Every change is recorded on the subscription's timeline (GET /api/v1/customer-subscriptions/{id}?include=events), for example created, trial_started, activated, charge_issued, renewed, payment_failed, dunning, plan_changed and cancelled.
Trials#
- The plan's trial days apply by default. The API can skip the trial (
trial: false) or set its length (trialDays). - On checkout pages and in the customer portal a customer gets a trial only once per package: a customer who has had a trial on any plan of the package subscribes without one.
- When the trial ends, the subscription becomes
active, the first period starts and the first charge is issued (a debit order subscription simply waits for the mandate's next debit). Asubscription.trial_endedwebhook is sent. - You can move the trial end with
PATCHnextBillingAt(not for debit order or gateway-billed subscriptions).
Renewals and billing periods#
The subscription billing job runs every hour at a quarter past the hour (cron 15 * * * *, South African time). For each subscription whose nextBillingAt has passed it starts the next period and issues the charge by the collection method. Month-based periods keep the day of the month, clamped to the end of shorter months (31 Jan → 28 Feb → 31 Mar). When the plan has a fixed number of billing cycles, the last paid cycle sets endsAt, stops the gateway or debit order from collecting again and the subscription expires at the end of that period. Successful renewals send subscription.renewed.
Quantity, setup fees and coupons#
amounton the subscription is the plan price ×quantity(1–10 000).- The setup fee is added to the first charge only (for debit orders it is a separate invoice).
- A coupon (by code) is validated for the plan and customer when the subscription starts. A
forevercoupon reduces the subscription amount itself;onceandrepeatingcoupons discount the first charge or the first N charges. See Coupons.
Failed payments and dunning#
A payment fails when a card charge is declined, a debit order is returned unpaid, a subscription invoice or payment request is still unpaid after its due date, or a gateway renewal doesn't arrive in time. An active or trialing subscription then becomes past_due and dunning starts:
- The customer is emailed (
subscription_past_due) with a link to pay the overdue amount, using the open invoice or a recovery invoice CentraPoint creates. No recovery invoice is created while an unpaid debit order will still be re-presented, or for gateway-billed subscriptions. - Every dunning interval days another attempt is made and another notice sent, up to dunning max attempts.
- When the overdue amount is paid, the subscription is
activeagain (subscription.renewedwithrecovered: true). - When the attempts are used up, the final action cancels or expires the subscription and your team is notified.
A failed first payment of an incomplete subscription doesn't start dunning: the customer can simply pay again. Staff can also Retry payment from the subscription page, which re-sends the open invoice or payment request.
Pausing, cancelling and changing plan#
| Action | Rules |
|---|---|
| Pause | From active or past_due. Linked debit order mandates are paused too. Gateway-billed subscriptions are paused at the gateway first; gateways that can't pause (Netcash Pay Now) refuse it. |
| Resume | From paused. Billing restarts at the end of the period already paid for, or now if it has passed. |
| Cancel now | Stops gateway billing first (if the gateway refuses, nothing changes), cancels linked mandates and deactivates open payment requests. Unpaid first invoices of incomplete or trialing subscriptions are cancelled. Payments already made are not refunded. |
| Cancel at period end | The subscription stays active until the paid period (or trial) ends, then is cancelled. Gateway billing is stopped straight away because the current period is already paid. Can be undone from the dashboard while it hasn't taken effect. |
| Change plan | Another plan in the same currency, optionally with a new quantity. The new price applies from the next billing date; there is no proration. Not possible for gateway-billed subscriptions if the amount or frequency would change, and debit order subscriptions can't change frequency. |
Subscription settings#
Under Subscriptions → Settings:
| Setting | Default | Meaning |
|---|---|---|
| Dunning max attempts | 4 | Notices/retries after a failed payment (1–10). |
| Dunning interval days | 3 | Days between dunning attempts (1–30). |
| Dunning final action | cancel | cancel or expire when attempts are used up. |
| Invoice due days | 7 | Days a subscription invoice or payment request stays open before the payment counts as failed (0–90). |
| Gateway grace days | 3 | Days after the billing date to wait for a gateway-managed renewal (0–30). |
| Incomplete expiry days | 30 | Subscriptions still waiting for their first payment expire after this (1–365). |
| Renewal reminder days | 3 | Email the customer this many days before a renewal (0 = off). |
| Trial reminder days | 3 | Email before a trial ends (0 = off). |
| Expiry reminder days | 7 | Email before a subscription ends (0 = off). |
| Invoice reminder before / interval / max | 2 / 3 / 3 | Unpaid invoice reminders: first one N days before the due date, then every N days while unpaid, at most N times. |
Renewal, trial, expiry and unpaid invoice reminders are sent by a daily job at 08:00 South African time (cron 0 8 * * *).
Emails, webhooks and notifications#
- Customer emails use the
subscription_*templates (activated, trial ending, renewing soon, renewed, payment request, past due, paused, resumed, upgraded, downgraded, expiring, cancelled, expired). Edit them under Email & templates. They go to the customer's billing email when one is set. - Webhooks:
subscription.created,.activated,.renewed,.trial_ended,.payment_failed,.past_due,.paused,.resumed,.plan_changed,.updated,.cancelledand.expired, with the customer subscription asdata(object: "customer_subscription"). See Webhooks. - Your team gets in-app notifications for new subscriptions, failed and recovered payments, changes made by customers or the API, and anything that needs manual action (for example a gateway that couldn't be told to stop billing).
How this relates to gateway subscriptions#
The older Subscriptions API (/api/v1/subscriptions) lists the card subscriptions a gateway created when a payer completed a recurring payment link. Those remain available and unchanged (dashboard: Subscriptions → Gateway). A customer subscription with the gateway collection method usually has one of these underneath: its paymentTokenId is the ID of the gateway subscription, and cancelling or pausing the customer subscription does the same at the gateway.
| Gateway subscriptions | Customer subscriptions | |
|---|---|---|
| Started by | A recurring payment link | Dashboard, API, checkout pages or the customer portal |
| Catalogue | None: amount and frequency come from the link | Packages and plans |
| Collected by | The gateway only | Gateway, debit order or invoice |
| Trials, dunning, plan changes | No | Yes |
| API | /api/v1/subscriptions | /api/v1/customer-subscriptions |
| Webhook data | Gateway subscription object | object: "customer_subscription" |