One-Time Payments
Sell lifetime access or one-time purchases with a single charge and no recurring billing.
A one-time payment plan charges the customer once at checkout and never bills again for the plan base. Use it for lifetime deals, one-off purchases, or any plan where recurring billing doesn't apply.
One-time plans behave like any other plan — they support trials, intro offers, add-ons, and all consumption models. The only differences are:
| Aspect | Behavior |
|---|---|
| Billing | Plan base charged once at checkout. Overage billed at each billing cycle. |
| Cancellation | Not allowed — the subscription stays active permanently |
| Interval changes | Not allowed — cannot switch from one-time to a recurring interval |
Configure in the dashboard
In the dashboard, go to Plans, edit a plan, and add a price with interval One-time (lifetime). You can combine one-time prices with recurring intervals on the same plan — each price has its own interval.
Create a one-time subscription
const { data } = await commet.subscriptions.create({
customerId: 'user_123',
planCode: 'pro',
billingInterval: 'one_time',
})
redirect(data.checkoutUrl)response = commet.subscriptions.create(
customer_id='user_123',
plan_code='pro',
billing_interval='one_time',
)
redirect(response.data['checkout_url'])result, err := client.Subscriptions.Create(ctx, &commet.CreateSubscriptionParams{
CustomerID: "user_123",
PlanCode: "pro",
BillingInterval: "one_time",
})
// redirect(result.Data.CheckoutURL)CreateSubscriptionParams params = CreateSubscriptionParams.builder()
.customerId("user_123")
.planCode("pro")
.billingInterval("one_time")
.build();
ApiResponse<Subscription> result = commet.subscriptions().create(params);
// redirect(result.getData().getCheckoutUrl())$result = $commet->subscriptions->create(
customerId: 'user_123',
planCode: 'pro',
billingInterval: 'one_time',
);
redirect($result->data['checkout_url']);curl -X POST https://commet.co/api/subscriptions \
-H "x-api-key: $COMMET_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerId": "user_123",
"planCode": "pro",
"billingInterval": "one_time"
}'The billingInterval must be one_time and the plan must have a one-time price configured. If the plan's default price is already one-time, you can omit the billingInterval parameter.
Invoicing
The initial invoice includes the plan base price as a one-time charge. After that, subsequent billing cycles only generate invoices for overage — the plan base is never charged again.
| Invoice | What's included |
|---|---|
| Initial | plan_base (once) + any applicable intro offer discount |
| Subsequent cycles | feature_overage, feature_seats, addon_base — only if charges exist |
If there's no overage or additional charges at a billing cycle, no invoice is generated.
Customer portal
In the Customer Portal, one-time subscriptions display the interval as Lifetime. The cancel button is hidden since cancellation is not allowed. Customers can still change plans if the plan belongs to a Plan Group.
Related
- Manage Plans — Create and configure plans
- Manage Subscriptions — Full subscription lifecycle
- Invoices and Billing Cycles — How invoicing works
- Consumption Models — Metered, Credits, and Balance explained
How is this guide?