Manage Plans
Create Stripe products, configure plan limits in code, and add new billing tiers to Nebutra.
Prerequisites
- Stripe account with API access
- Environment variables configured (see Payments Overview)
- Stripe CLI installed:
npm install -g stripe
Step 1: Create products in Stripe
Each billing tier maps to a Stripe product with one or more prices. Run the Stripe CLI to create them, or use the Dashboard UI.
# Create the PRO product
stripe products create \
--name="Nebutra PRO" \
--description="100,000 API calls/month, 10 members, email support"
# Create a monthly recurring price for PRO ($49/month)
stripe prices create \
--product=prod_REPLACE_WITH_PRO_ID \
--unit-amount=4900 \
--currency=usd \
--recurring[interval]=month \
--nickname="PRO Monthly"
# Create the ENTERPRISE product (custom pricing — set price manually)
stripe products create \
--name="Nebutra ENTERPRISE" \
--description="Unlimited, SSO, SLA, custom contract"- Go to Stripe Dashboard → Products → Add product.
- Set the name, description, and pricing for each tier.
- Copy the Price ID (
price_...) for each tier into your.envfile.
Step 2: Set price ID environment variables
After creating prices in Stripe, record their IDs:
STRIPE_PRO_PRICE_ID=price_xxxxxxxxxxxxxxxxxxxx
STRIPE_ENTERPRISE_PRICE_ID=price_xxxxxxxxxxxxxxxxxxxxStep 3: Configure plan limits in code
Plan limits are defined in packages/commerce/billing/src/plans.ts. Each entry maps a plan name to its resource quotas.
export const PLANS = {
free: {
id: "free",
name: "FREE",
stripePriceId: null,
limits: {
apiCallsPerMonth: 1_000,
orgMembers: 1,
},
features: {
emailSupport: false,
sso: false,
},
},
pro: {
id: "pro",
name: "PRO",
stripePriceId: process.env.STRIPE_PRO_PRICE_ID!,
limits: {
apiCallsPerMonth: 100_000,
orgMembers: 10,
},
features: {
emailSupport: true,
sso: false,
},
},
enterprise: {
id: "enterprise",
name: "ENTERPRISE",
stripePriceId: process.env.STRIPE_ENTERPRISE_PRICE_ID!,
limits: {
apiCallsPerMonth: Infinity,
orgMembers: Infinity,
},
features: {
emailSupport: true,
sso: true,
},
},
} as const;
export type PlanId = keyof typeof PLANS;
export type Plan = (typeof PLANS)[PlanId];Step 4: Retrieve a plan by ID
Use the getPlan helper anywhere in your backend code:
import { getPlan } from "@nebutra/billing";
const plan = getPlan("pro");
// → { id: "pro", name: "PRO", limits: { apiCallsPerMonth: 100000, ... }, ... }
const limit = plan.limits.apiCallsPerMonth;
// → 100000Adding a new plan tier
Use the Stripe CLI or Dashboard to create a new product and price. Copy the Price ID.
STRIPE_TEAMS_PRICE_ID=price_xxxxxxxxxxxxxxxxxxxxteams: {
id: "teams",
name: "TEAMS",
stripePriceId: process.env.STRIPE_TEAMS_PRICE_ID!,
limits: {
apiCallsPerMonth: 500_000,
orgMembers: 50,
},
features: {
emailSupport: true,
sso: false,
},
},If you use requirePlan('pro') checks, update them to also accept the new tier where appropriate (see Paywall).
Updating plan limits
Edit the limits object for the relevant plan in packages/commerce/billing/src/plans.ts. Changes take effect immediately after the next deployment — no database migration required, since limits are resolved at request time.
Plan changes in the database take effect as soon as the Stripe webhook is received and processed. There is no polling delay. Quota enforcement uses the latest plan record on every request.
Related
How is this guide?
Last updated on