Billing

All billing is scoped to organizations and processed through Stripe.

Billing Modes

ModeDescription
SubscriptionMonthly/yearly, auto-renewing
CreditsOne-time credit package purchase
LifetimeOne-time payment, permanent access
FreeGranted 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

EventAction
checkout.session.completedCredit purchase, lifetime deal completed
customer.subscription.createdCreate subscription record
customer.subscription.updatedUpgrade/downgrade, cancel renewal
customer.subscription.deletedSubscription canceled
invoice.payment_succeededInvoice payment succeeded
invoice.payment_failedPayment failed, mark as past_due
invoice.paidInvoice paid, grant credits
price.createdSync new price locally
price.updatedSync price changes
price.deletedSync price deletion

Setup Steps

  1. Go to Stripe Dashboard → Webhooks
  2. Click “Add endpoint”
  3. Enter endpoint URL: https://api.yourdomain.com/v1/webhook/stripe
  4. Select the 10 events listed above
  5. Copy the Webhook signing secret and add it to .env as STRIPE_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

PageDescription
/subscriptionSubscription management
/creditsCredit list
/credits?tab=usageUsage history (with user email)
/credits/packagesCredit package purchase
/invoicesInvoice list

Dashboard Credits Display

The Credits card on the Dashboard shows the member’s actual available quota: