Billing
All billing is scoped to organizations and processed through Stripe.
Billing Modes
| Mode | Description |
|---|---|
| Subscription | Monthly/yearly, auto-renewing |
| Credits | One-time credit package purchase |
| Lifetime | One-time payment, permanent access |
| Free | Granted on signup, has expiration |
Stripe Webhook
Endpoint URL: https://api.yourdomain.com/v1/webhook/stripe
The backend receives Stripe events through this endpoint. Configure it in the Stripe Dashboard.
Events to Listen For
| Event | Action |
|---|---|
checkout.session.completed | Credit purchase, lifetime deal completed |
customer.subscription.created | Create subscription record |
customer.subscription.updated | Upgrade/downgrade, cancel renewal |
customer.subscription.deleted | Subscription canceled |
invoice.payment_succeeded | Invoice payment succeeded |
invoice.payment_failed | Payment failed, mark as past_due |
invoice.paid | Invoice paid, grant credits |
price.created | Sync new price locally |
price.updated | Sync price changes |
price.deleted | Sync price deletion |
Setup Steps
- Go to Stripe Dashboard → Webhooks
- Click “Add endpoint”
- Enter endpoint URL:
https://api.yourdomain.com/v1/webhook/stripe - Select the 10 events listed above
- Copy the Webhook signing secret and add it to
.envasSTRIPE_WEBHOOK_SECRET_KEY
Payment Config
api/src/config/website/payment.{suffix}.ts:
import type { PaymentConfig } from "@readystart/api-core"
import { PlanMode } from "@readystart/api-core"
export const getPaymentConfig = (): PaymentConfig => ({
payment: {
credit: {
enabled: true,
currency: "usd",
unit_price: 0.01, // 1 credit = $0.01
min_credits: 1000, // Minimum purchase 1000 credits
interval: "lifetime", // Credit validity period
packages: [
{
mode: PlanMode.ONE_TIME_CREDITS,
plan_id: "credits_1000",
name: "1000 Credits",
credits: 1000,
amount: 1000, // $10.00 (in cents)
interval: "month",
interval_count: 1,
},
],
},
subscription: {
enabled: true,
packages: [
{
mode: PlanMode.FREE, // Plan mode
plan_id: "free", // Plan ID
name: "Free", // Display name
credits: 50, // Granted credits
amount: 0, // Price (0 for free)
interval: "month", // Interval unit
interval_count: 1, // Interval count
interval_type: "recurring", // Interval type
},
{
mode: PlanMode.SUBSCRIPTION,
plan_id: "pro_monthly",
name: "Pro Monthly",
credits: 500,
amount: 1900, // $19.00
interval: "month",
interval_count: 1,
},
],
},
},
})
Free Credit Package
A free credit package is automatically created when a user signs up, configured as the mode: PlanMode.FREE plan.
Frontend Pages
| Page | Description |
|---|---|
/subscription | Subscription management |
/credits | Credit list |
/credits?tab=usage | Usage history (with user email) |
/credits/packages | Credit package purchase |
/invoices | Invoice list |
Dashboard Credits Display
The Credits card on the Dashboard shows the member’s actual available quota:
- Has limit:
limit - used - No limit: org total credits
- Exhausted: shown in red as “Exhausted”