DocslothBilling
checking session

Billing

Billing displays real server state with a next action, not placeholder statistics.

Surface contract

Primary object: the subscription row and the invoices the payment processor actually sent; a free plan is a real row, not a placeholder.

Actions

  • Starts the payment processor’s own checkout for the configured plan price (POST /v1/billing/checkout). The charge, currency and renewal terms are the processor’s; owner/admin only, and nothing is charged until checkout completes.
  • Adds the 100-job/month intelligence add-on as a second line item of the same processor checkout (POST /v1/billing/checkout with addon: intelligence). The catalog offers it on free and pro only; the server refuses an unknown or ineligible add-on, and the subscription row’s Add-ons column shows whether it is active.
  • Opens the processor’s billing portal (POST /v1/billing/portal) for invoices, payment methods and cancellation. When no billing customer is linked the server answers 422 with that fact instead of opening a fake portal.
  • CancelProvider credentialsCancellation is completed in the processor’s billing portal so the effective date and refund rules are the processor’s own; this build has no local cancel endpoint, so it sends you to the portal rather than pretending to cancel.
  • View invoiceEach invoice row links to the processor-hosted invoice URL recorded by the verified webhook; the page never builds an invoice document itself.
Required states and how this surface reaches them
loading
the session probe and each list show Loading… until the control plane answers.
ready
the server’s own records render as returned; the primary object is named before its details.
empty
no invoice exists until a verified webhook records one; the subscription endpoint records a real free row for an unprovisioned organization.
error
the control plane’s status and detail are shown; no placeholder row replaces them.
offline
no control plane is reachable; nothing is rendered rather than invented.
permission_denied
a 401 returns to sign-in with this path; a 403 states that the role cannot read this surface.
not_configured
without STRIPE_SECRET_KEY (or the configured plan/add-on price) checkout and portal answer 503 naming the missing secret; the page shows setup, never a fake checkout.
budget_paused
a subscription in a dunning grace or suspended state is reported by the server as it is; usage caps are shown on the usage surface.
requires_approval
mutations the server reserves for an explicit human owner/admin are refused with its own detail and never auto-approved here.

Scope: workspace membership (owner/admin for changes). Plan and invoice state come from verified Stripe webhooks; this page never fabricates a receipt, a price or a subscription state.

Subscription

checking

Loading…

Invoices

checking

Loading…

Rows come from the authenticated control plane; this page never renders placeholder records. Actions report the server's own response, including refusals.