• Pricing
  • Blog
Log inBook a demo
Introduction

Quickstart

Learn

Manage PlansConfigure FeaturesConsumption ModelsAdd-onsCredit PacksPlan GroupsOne-Time Payments

Resources

SDK ReferenceAPI VersioningError HandlingTestingCLI

Plugins

Better Auth
System status
DocumentationKnowledge BaseBuild with AIAPI ReferenceWebhooks

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.

This page covers one-time charges billed as a plan. To charge a customer once with no subscription or plan — a standalone invoice with tax and receipt — use Accept One-Time Payments instead.

One-time plans behave like any other plan — they support trials, intro offers, add-ons, and all consumption models. The only differences are:

AspectBehavior
BillingPlan base charged once at checkout. Overage billed at each billing cycle.
CancellationNot allowed — the subscription stays active permanently
Interval changesNot 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 subscription = await commet.subscriptions.create({
  customerId: 'user_123',
  planCode: 'pro',
  billingInterval: 'one_time',
})

if (!subscription.checkoutUrl) {
  throw new Error('Commet did not return a checkout URL')
}

redirect(subscription.checkoutUrl)
subscription = commet.subscriptions.create(
    customer_id='user_123',
    plan_code='pro',
    billing_interval='one_time',
)

if not subscription.checkout_url:
    raise RuntimeError('Commet did not return a checkout URL')

redirect(subscription.checkout_url)
planCode := "pro"
billingInterval := "one_time"
subscription, err := client.Subscriptions.Create(ctx, &commet.CreateSubscriptionParams{
    CustomerID:      "user_123",
    PlanCode:        &planCode,
    BillingInterval: &billingInterval,
})
if err != nil {
    log.Fatal(err)
}
if subscription.CheckoutURL == nil {
    log.Fatal("Commet did not return a checkout URL")
}
http.Redirect(w, r, *subscription.CheckoutURL, http.StatusSeeOther)
CreateSubscriptionParams params = CreateSubscriptionParams.builder()
    .customerId("user_123")
    .planCode("pro")
    .billingInterval("one_time")
    .build();
var subscription = commet.subscriptions().create(params);
if (subscription.checkoutUrl() == null) {
    throw new IllegalStateException("Commet did not return a checkout URL");
}
redirect(subscription.checkoutUrl());
$result = $commet->subscriptions->create(
    customerId: 'user_123',
    planCode: 'pro',
    billingInterval: 'one_time',
);

if ($result->checkoutUrl === null) {
    throw new RuntimeException('Commet did not return a checkout URL');
}
redirect($result->checkoutUrl);
curl -X POST https://commet.co/api/v1/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.

InvoiceWhat's included
Initialplan_base (once) + any applicable intro offer discount
Subsequent cyclesfeature_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?

Plan Groups

Group plans together to enable self-service upgrades and downgrades in the Commet Customer Portal.

Offers

Define reusable trials and temporary pricing terms independently from plans and distribution.

On this page

Configure in the dashboard
Create a one-time subscription
Invoicing
Customer portal
Related