Files
cfw-autumn/apps/docs/mintlify/documentation/getting-started/setup.mdx
Ayush Rodrigues 2aac9b3a8b docs wip
2026-03-09 16:26:15 +00:00

450 lines
11 KiB
Plaintext

---
title: "Setup and payments"
description: "Implement your app's payments and pricing model"
---
import CreatePlans from '/snippets/create-plans.mdx';
In this example we'll create the pricing for a premium AI chatbot. We're going to have:
- A <Badge color="green">Free</Badge> plan that gives users 5 chat messages per month for free
- A <Badge color="blue">Pro</Badge> plan that gives users 100 chat messages per month for $20 per month.
<Steps>
<Step>
### Create your pricing plans
Create a plan for each pricing tier that your app offers. In our example we'll create a "Free" and "Pro" plan, and assign them features.
<CreatePlans />
</Step>
<Step>
### Installation
[Create an Autumn Secret key](https://app.useautumn.com/sandbox/dev?tab=api_keys), and paste it in your `.env` variables. Then, install the Autumn SDK. If you're using the CLI, this will be done for you.
```bash .env
AUTUMN_SECRET_KEY=am_sk_test_42424242...
```
<CodeGroup>
```bash bun
bun add autumn-js
```
```bash npm
npm install autumn-js
```
```bash pnpm
pnpm add autumn-js
```
```bash yarn
yarn add autumn-js
```
```bash pip
pip install autumn-sdk
```
</CodeGroup>
<Note>
If you're using a separate backend and frontend, make sure to install the
library in both.
</Note>
</Step>
</Steps>
{/* REACT DOCS */}
<View title="React" icon="react">
Autumn's client-side [hooks](/react/hooks/useCustomer) allow you to handle billing directly from your frontend.
<Steps>
<Step>
### Add Endpoints Server-side
Server-side, mount the Autumn handler. This will create endpoints in the `/api/autumn/*` path, which will be called by Autumn's frontend React hooks. These endpoints in turn call Autumn's API.
The handler takes in an `identify` function where you should pass in the user ID or organization ID from your auth provider.
<CodeGroup>
```typescript Next.js
// app/api/autumn/[...all]/route.ts
import { autumnHandler } from "autumn-js/next";
import { auth } from "@/lib/auth";
export const { GET, POST } = autumnHandler({
identify: async (request) => {
// get the user from your auth provider (example: better-auth)
const session = await auth.api.getSession({
headers: request.headers,
});
return {
customerId: session?.user.id, // or org ID
customerData: {
name: session?.user.name,
email: session?.user.email,
},
};
},
});
```
```typescript Hono
// index.ts
import { autumnHandler } from "autumn-js/hono";
app.use(
"/api/autumn/*",
autumnHandler({
identify: async (c: Context) => {
// get the user from your auth provider (example: better-auth)
const session = await auth.api.getSession({
headers: c.req.raw.headers,
});
return {
customerId: session?.user.id,
customerData: {
name: session?.user.name,
email: session?.user.email,
},
};
},
})
);
```
```typescript General (framework-agnostic)
// For any framework not listed above
import { autumnHandler } from "autumn-js/backend";
// Call this from your route handler
const result = await autumnHandler({
request: {
url: request.url, // Full URL or path (e.g., "/api/autumn/customer")
method: request.method,
body: await request.json(),
},
customerId: session?.user.id,
customerData: {
name: session?.user.name,
email: session?.user.email,
},
});
// Return the response
return new Response(JSON.stringify(result.response), {
status: result.statusCode,
headers: { "Content-Type": "application/json" },
});
```
</CodeGroup>
<Check>
Autumn's customer ID is the same as your internal user or org ID generated from your auth provider. No need to store any extra IDs.
</Check>
</Step>
<Step>
### Add Provider Client-side
Client side, wrap your application with the `<AutumnProvider>` component.
```jsx
// layout.tsx
import { AutumnProvider } from "autumn-js/react";
export default function RootLayout({ children }: {
children: React.ReactNode,
}) {
return (
<html>
<body>
<AutumnProvider>
{children}
</AutumnProvider>
</body>
</html>
);
}
```
</Step>
<Step>
### Create an Autumn customer
From a frontend component, use the [`useCustomer()` hook](/react/hooks/useCustomer). This will automatically create an Autumn customer if they're a new user and enable the <Badge color="green">Free</Badge> plan for them, or get the customer's state for existing users.
```jsx React
import { useCustomer } from 'autumn-js/react'
const App = () => {
const { data } = useCustomer();
console.log("Autumn customer:", data)
return <h1>My very profitable app</h1>
}
```
<Expandable title="data object">
```json expandable
{
"id": "user_123",
"createdAt": 1764932560414,
"name": "My First Customer",
"email": null,
"fingerprint": null,
"stripeId": null,
"env": "sandbox",
"metadata": {},
"sendEmailReceipts": false,
"subscriptions": [
{
"planId": "free",
"autoEnable": true,
"addOn": false,
"status": "active",
"pastDue": false,
"canceledAt": null,
"expiresAt": null,
"trialEndsAt": null,
"startedAt": 1764932560519,
"currentPeriodStart": null,
"currentPeriodEnd": null,
"quantity": 1
}
],
"purchases": [],
"balances": {
"messages": {
"featureId": "messages",
"granted": 5,
"remaining": 5,
"usage": 0,
"unlimited": false,
"overageAllowed": false,
"maxPurchase": null,
"nextResetAt": 1767610960519
}
}
}
```
</Expandable>
You will see your user under the [customers](https://app.useautumn.com/customers) page in the Autumn dashboard.
</Step>
<Step>
### Stripe Payment Flow
Call `attach` to attach the <Badge color="blue">Pro</Badge> plan to the customer. The customer is redirected to an Autumn checkout page where they can review prorations and plan changes before confirming. Once they've paid, Autumn will grant access to "100 messages per month" defined in Step 1.
<Note>
Use Stripe's test card `4242 4242 4242 4242` to make a purchase in sandbox. You can enter any Expiry and CVV.
</Note>
```jsx React
import { useCustomer } from "autumn-js/react";
export default function PurchaseButton() {
const { attach } = useCustomer();
return (
<button
onClick={async () => {
await attach({
planId: "pro",
redirectMode: "always",
});
}}
>
Select Pro Plan
</button>
);
}
```
This will handle any plan changes scenario (upgrades, downgrades, one-time topups, renewals, etc).
Upgrades will happen immediately, and downgrades will be scheduled for the next billing cycle.
<Note>
The **`redirectMode: "always"`** flag will always return a payment URL.
New purchases redirect to Stripe Checkout to enter payment details, and subsequent charges redirect to an Autumn hosted, one-click confirmation page.
You can build your own billing confirmation flows by using the `previewAttach` function.
</Note>
</Step>
</Steps>
</View>
{/* SERVER SDK DOCS */}
<View title="Server SDK" icon="server">
<Steps>
<Step>
### Create an Autumn customer
When the customer signs up, create an Autumn customer for them. Autumn will automatically enable the <Badge color="green">Free</Badge> plan, since you marked it with the `auto-enable` flag.
<CodeGroup dropdown>
```typescript
import { Autumn } from "autumn-js";
const autumn = new Autumn({
secretKey: 'am_sk_42424242',
});
const customer = await autumn.customers.getOrCreate({
customerId: "user_or_org_id_from_auth",
name: "John Doe",
email: "john@example.com",
});
```
```python
import asyncio
from autumn_sdk import Autumn
autumn = Autumn('am_sk_42424242')
async def main():
customer = await autumn.customers.get_or_create(
customer_id="user_or_org_id_from_auth",
name="John Doe",
email="john@example.com",
)
asyncio.run(main())
```
```bash cURL
curl --request POST \
--url https://api.useautumn.com/v1/customers \
--header 'Authorization: Bearer am_sk_42424242' \
--header 'Content-Type: application/json' \
--data '{
"customer_id": "user_or_org_id_from_auth",
"name": "John Doe",
"email": "john@example.com"
}'
```
</CodeGroup>
<Check>
Autumn's customer ID is the same as your internal user or org ID generated from your auth provider. No need to store any extra IDs.
</Check>
In the Autumn dashboard, you will see your user under the [customers](https://app.useautumn.com/customers) page.
</Step>
<Step>
### Stripe Payment Flow
Call `billing.attach` to attach the <Badge color="blue">Pro</Badge> plan to the customer. Redirect the customer to the returned `paymentUrl` to complete payment or confirm the plan change.
<CodeGroup dropdown>
```typescript
import { Autumn } from "autumn-js";
const autumn = new Autumn({
secretKey: 'am_sk_42424242'
});
const response = await autumn.billing.attach({
customerId: "user_or_org_id_from_auth",
planId: "pro",
redirectMode: "always",
});
// Redirect customer to complete payment or confirm plan change
redirect(response.paymentUrl);
```
```python
import asyncio
from autumn_sdk import Autumn
autumn = Autumn('am_sk_42424242')
async def main():
response = await autumn.billing.attach(
customer_id='user_or_org_id_from_auth',
plan_id='pro',
redirect_mode='always',
)
asyncio.run(main())
```
```bash cURL
curl -X POST 'https://api.useautumn.com/v1/attach' \
-H 'Authorization: Bearer am_sk_42424242' \
-H 'Content-Type: application/json' \
-d '{
"customer_id": "user_or_org_id_from_auth",
"plan_id": "pro",
"redirect_mode": "always"
}'
```
</CodeGroup>
<Note>
Use Stripe's test card `4242 4242 4242 4242` to make a purchase in sandbox. You can enter any Expiry and CVV.
</Note>
This can be used for any plan changes scenario (upgrades, downgrades, one-time topups, renewals, etc).
Upgrades will happen immediately, and downgrades will be scheduled for the next billing cycle.
<Note>
**`redirectMode: "always"`** (shown above) always returns a `paymentUrl`, redirecting the customer to review and confirm the plan change — whether it's a new subscription, upgrade, or downgrade.
**Build your own UI:** If you want to handle checkout yourself:
1. Call [previewAttach](/api-reference/billing/previewAttach) to get line items and pricing details
2. Call `attach` with `redirectMode: "if_required"` — this only returns a `paymentUrl` when a payment action is needed (e.g., no card on file), otherwise charges automatically
</Note>
</Step>
</Steps>
</View>
**Next: Track and limit usage**
Now that the plan is enabled and you've handled payments, you can now make sure that customers have the access to the right features and limits based on their plan.
<Card
title="Track and limit usage"
href='/documentation/getting-started/gating'
>
Enforce usage limits and feature permissions using Autumn's `check` and `track` functions
</Card>