Plans and Pricing
Three plans are defined inpackages/config/src/billing.ts:
All paid plans offer monthly and yearly billing. Yearly billing saves roughly 17%.
Configuring Plans
Plan configuration lives in a single file. Each plan defines its Stripe price IDs, usage limits, and feature list:STRIPE_PRO_MONTHLY_PRICE_ID, STRIPE_PRO_YEARLY_PRICE_ID, STRIPE_ENTERPRISE_MONTHLY_PRICE_ID, and STRIPE_ENTERPRISE_YEARLY_PRICE_ID environment variables to match the price IDs in your Stripe dashboard.
Checkout Flow
When a user upgrades, BunShip creates a Stripe Checkout Session linked to the organization:1
User selects a plan
Your frontend calls
POST /api/v1/billing/checkout with the desired priceId.2
BunShip creates a Stripe customer
If the organization does not yet have a Stripe customer, one is created automatically and stored
in the
subscriptions table.3
Redirect to Stripe Checkout
The API returns a Checkout Session URL. Redirect the user to complete payment.
4
Stripe webhook confirms subscription
After payment, Stripe sends a
checkout.session.completed webhook. BunShip updates the local
subscription record with the plan ID, status, and billing period.Customer Portal
Stripe’s Customer Portal lets users manage their payment methods, view invoices, and cancel subscriptions without any custom UI:POST /api/v1/billing/portal to generate a portal session URL, then redirect the user.
Usage Tracking and Limits
BunShip tracks resource usage per organization and compares it against the current plan’s limits. ThegetUsage function queries counts in parallel:
-1 means unlimited (Enterprise plan). Use the helper functions from @bunship/config:
Webhook Handling
BunShip automatically processes Stripe webhook events to keep subscription state in sync. The following events are handled:Cancellation
Subscriptions cancel at the end of the current billing period rather than immediately. This gives users access to paid features until their prepaid time expires:Invoices
Retrieve an organization’s invoice history from Stripe:Testing with Stripe Test Mode
During development, BunShip uses Stripe’s test mode. No real charges are made.
1
Set test keys
Use your Stripe test secret key and webhook secret in
.env: bash STRIPE_SECRET_KEY=sk_test_... STRIPE_WEBHOOK_SECRET=whsec_... 2
Use test card numbers
Stripe provides test card numbers for different scenarios: -
4242 4242 4242 4242 — Successful
payment - 4000 0000 0000 3220 — 3D Secure required - 4000 0000 0000 0002 — Declined3
Forward webhooks locally
Use the Stripe CLI to forward webhook events to your local server:
bash stripe listen --forward-to localhost:3000/api/v1/webhooks/stripe 4
Trigger test events
stripe trigger checkout.session.completed stripe trigger customer.subscription.updated

