Files
cfw-autumn/apps/docs/mintlify/documentation/modelling-pricing/one-off-purchases.mdx
Ayush Rodrigues 6ce82d15c5 docs wip pricing
2026-03-12 15:57:06 +00:00

135 lines
3.3 KiB
Plaintext

---
title: One-Off Purchases
description: Configure one-time purchases and lifetime plans
---
One-off purchases are single-charge plans that don't recur. They're used for one-time top-ups, lifetime access plans, or any plan where the customer pays once.
> **Example** <br />
> An AI platform lets users buy 500 credits for $10 as a one-time purchase. The credits never expire and can be used at any pace.
## Setting up
<Tabs>
<Tab title="CLI">
Set the plan's `price.interval` to `one_off`, or omit `interval` on the item price for a one-time charge:
```ts autumn.config.ts
import { feature, item, plan } from 'atmn';
export const credits = feature({
id: 'credits',
name: 'Credits',
type: 'metered',
consumable: true,
});
export const creditTopUp = plan({
id: 'credit_top_up',
name: 'Credit Top-Up',
items: [
item({
featureId: credits.id,
price: {
amount: 10,
billingUnits: 500,
billingMethod: 'prepaid',
interval: 'one_off',
},
}),
],
});
```
Push changes with `atmn push`.
</Tab>
<Tab title="Dashboard">
1. Navigate to **Plans** and click **Create Plan**
2. Set the plan name and ID
3. Under **Price**, select **One-off** as the interval — or leave no base price if pricing is purely feature-based
4. Add a feature with a **prepaid** price. The customer will select a quantity at checkout
5. Toggle **Add-on** if this should be purchasable alongside other plans
6. Click **Create**
</Tab>
</Tabs>
## How it works
When a customer purchases a one-off plan:
- Autumn creates a Stripe invoice (not a subscription) and charges it immediately
- The feature balance is provisioned with the purchased quantity
- The balance has a `one_off` interval — it never resets or expires
<Note>
One-off purchases don't create Stripe subscriptions. They generate a one-time invoice instead.
</Note>
## Purchasing a one-off plan
For prepaid one-off plans, pass the desired `quantity` via the `options` array:
<CodeGroup>
```typescript TypeScript
import { Autumn } from "autumn-js";
const autumn = new Autumn({ secretKey: "am_sk_..." });
const { data } = await autumn.checkout({
customer_id: "user_123",
plan_id: "credit_top_up",
options: [{
feature_id: "credits",
quantity: 1000,
}],
});
```
```python Python
from autumn_sdk import Autumn
autumn = Autumn("am_sk_...")
response = await autumn.checkout(
customer_id="user_123",
plan_id="credit_top_up",
options=[{
"feature_id": "credits",
"quantity": 1000,
}],
)
```
```bash cURL
curl -X POST "https://api.useautumn.com/v1/checkout" \
-H "Authorization: Bearer am_sk_..." \
-H "Content-Type: application/json" \
-d '{
"customer_id": "user_123",
"plan_id": "credit_top_up",
"options": [{
"feature_id": "credits",
"quantity": 1000
}]
}'
```
</CodeGroup>
## Balance stacking
One-off balances stack with existing balances from subscriptions. Autumn uses [deduction order](/documentation/concepts/balances#deduction-order) to ensure shorter-interval balances (e.g., monthly) are used before one-off (lifetime) balances.
## Use cases
| Use case | Configuration |
|----------|---------------|
| Credit top-up | Prepaid price, add-on, no base price |
| Lifetime plan | One-off base price, features with no reset |
| One-time fee | One-off base price, no features |