Skip to content

Billing and Stripe

SREDSimplify uses Stripe for both recurring subscription billing and one-time expert review checkout flows.

Public catalog

The public pricing surface is:

  • GET /api/v1/subscription-plans

It returns:

  • available subscription plans
  • the current one-time expert review offering

Authenticated billing endpoints

EndpointPurpose
GET /api/v1/billing/meCurrent user billing profile
POST /api/v1/billing/checkout/subscriptionCreate Stripe Checkout session for a subscription
POST /api/v1/billing/checkout/expert-reviewCreate Stripe Checkout session for one-time expert review
POST /api/v1/billing/checkout/confirmConfirm a completed checkout session
POST /api/v1/billing/portal-sessionCreate Stripe customer portal session
GET /api/v1/billing/expert-review/ordersList current user expert review orders
GET /api/v1/billing/expert-review/orders/{orderId}Read one expert review order
GET /api/v1/billing/expert-review/orders/by-checkout-sessionResolve an expert review order from a Stripe checkout session ID

Subscription checkout

Request body:

json
{
  "tier": "PROFESSIONAL"
}

Important behavior:

  • FREE cannot be purchased
  • the selected plan must be active and purchasable
  • a configured Stripe price ID is required
  • existing Stripe customers are reused when available

Expert review checkout

Request body:

json
{
  "projectId": "uuid",
  "notes": "Optional notes"
}

Important behavior:

  • the project must belong to the current user
  • expert review must be active and have a configured Stripe price ID
  • the checkout metadata stores userId, projectId, and notes

Checkout confirmation

Confirmation body:

json
{
  "sessionId": "cs_..."
}

The backend retrieves the Stripe session directly and checks:

  • the session belongs to the current user
  • checkout status is complete
  • payment status is paid or no_payment_required

If confirmed:

  • subscription state is synchronized for subscription checkouts
  • expert review orders are marked paid for expert review checkouts
  • payment records are updated accordingly

Membership tiers

Current membership tiers:

  • FREE
  • STARTER
  • PROFESSIONAL
  • ENTERPRISE

The billing system is one of the mechanisms that moves a user between those tiers.

Subscription status values

Current normalized subscription statuses:

  • INCOMPLETE
  • INCOMPLETE_EXPIRED
  • TRIALING
  • ACTIVE
  • PAST_DUE
  • CANCELED
  • UNPAID
  • UNKNOWN

When Stripe subscription state becomes inactive enough, the backend can downgrade the user back to FREE.

Expert review order lifecycle

Current expert review order statuses:

  • PENDING_PAYMENT
  • PAID
  • IN_REVIEW
  • COMPLETED
  • CANCELED

Typical path:

  1. create checkout
  2. order is stored as PENDING_PAYMENT
  3. successful Stripe completion marks it PAID
  4. internal review flow advances it to IN_REVIEW and then COMPLETED

Stripe webhook endpoint

The Stripe callback endpoint is:

  • POST /api/v1/billing/stripe/webhook

Important behavior:

  • it requires the Stripe-Signature header
  • webhook signatures are verified against the configured Stripe webhook secret
  • duplicate events are ignored based on Stripe event ID persistence

Current event handling covers:

  • checkout.session.completed
  • checkout.session.async_payment_succeeded
  • checkout.session.expired
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted

If a checkout session expires, pending expert review orders and payments are marked canceled where appropriate.