Corteksa
GuidesBilling

Troubleshooting

Billing — Troubleshooting

The most common failures, and the one-line fix.

400 "No workspace selected"

Every user billing endpoint needs an active workspace on the user. Select a workspace (so the JWT/user carries workspaceId) before calling billing. See Getting started.

402 on a write that isn't a metered action

The workspace is read-only — its subscription is past_due/suspended (read_only_since set). Writes are blocked by WorkspaceReadOnlyGuard; reads and billing/payment endpoints stay open. Fix: pay via POST /checkout to recover; the webhook lifts read-only.

402 PLAN_LIMIT_EXCEEDED

A metered resource (workflow_executions, ai_credits, storage) hit its effective limit. The body carries { metric, limit, used }. Fix: upgrade the plan or buy an add-on / one-time pack, then retry. Counters are keyed by month, so they reset on the 1st (UTC); packs top up the balance immediately.

/change-plan rejected with PAYMENT_METHOD_REQUIRED

You tried to change the plan on a lapsed/canceled subscription (past_due/suspended/canceled). A paid plan is never handed out for free outside the trial. Fix: add a card via POST /checkout first (which reactivates), then change the plan.

/change-plan didn't return a redirect

By design — POST /change-plan never opens Paymob. Only POST /checkout returns a redirect_url. A trial swap and a downgrade apply immediately; an active upgrade returns charged:true and applies on the webhook (poll /usage).

The charge "succeeded" but the plan/state didn't change

The Paymob redirect and the immediate HTTP response are not proof of success. The real state lands on the async webhook. Fix: confirm with GET /payment-status?payment_id=… and poll GET /usage for a few seconds until it reflects the change.

Subscribing to Enterprise returns 400

Enterprise is provisioned by the team, not self-serve — 400 "The Enterprise plan is set up by our team. Please contact support." Choose a shared-tier plan or contact sales.

Add-on purchase returns 400

Add-ons need an active subscription with a saved card (status:"active" and has_payment_method:true). Check /usage and gate the buy button on those two fields.

Paymob webhook returns 401

The HMAC signature did not verify. Confirm PAYMOB_HMAC_SECRET matches the Paymob merchant account and that Paymob posts to /api/v1/webhooks/paymob with the raw body intact. See Webhooks.

The usage bar doesn't update live

usage:updated rides the /data/events socket (records module), not a billing namespace. Confirm the socket is connected with the user JWT. It covers only ai_credits / workflow_executions — plan/card changes still need /usage polling. See Events.

More error codes: Errors.

On this page