Skip to content

fix(billing): surface checkout failures and stop silent start-trial 500s - #2776

Merged
tyler-dane merged 4 commits into
mainfrom
fix/billing-checkout-session
Aug 13, 2026
Merged

fix(billing): surface checkout failures and stop silent start-trial 500s#2776
tyler-dane merged 4 commits into
mainfrom
fix/billing-checkout-session

Conversation

@tyler-dane

Copy link
Copy Markdown
Contributor

Summary

  • Staging Start trial hit POST /billing/checkout/session with a 500 and the billing gate never caught it, so the UI looked dead (unhandled ApiError in PostHog).
  • Checkout now pins card collection, uses a new Stripe idempotency key (compass-checkout-v2-…), maps Stripe errors to 400/502 with a safe client message, trims Stripe config values, and toasts failures instead of failing silently.
  • The API trusts one proxy hop (same as Sync) so checkout rate-limit keys are not collapsed behind Caddy. Billing status is only used while the user is actually signed in, including ignoring a cached read-only status after session loss.

Simplicity

  • Dropped an unused getApiErrorData export and a dead BillingHttpError branch in the Stripe wrap helper.
  • Retained BillingGateModal useEffect / useRef / useState that already owned focus, analytics-once, export, and redirect busy state. No new hooks were added beyond SessionContext for the live-session gate.

Automated validation

  • Focused backend-fast: billing controller, config trim, trust proxy — 22 pass.
  • Mongo-backed stripe.service.db.test.ts — 7 pass (checkout params, Stripe error mapping).
  • Focused web: BillingGateModal toast/redirect, useAppAccess (including cached status after sign-out), api.util — 46 then 9 pass after the review fix.
  • bun run type-check — pass.
  • Did not exercise incognito signup against staging or local SuperTokens (AGENTS: no login flows without required backend setup; staging still runs the previous release until this deploys).

Independent review

  • First pass (Review): P2 — cached /billing/status could keep BillingGateModal up after authenticated became false. Fixed in aa50080a0.
  • Re-review of that follow-up (Review): no findings.

Test plan

  • bun packages/scripts/src/testing/test-parallel.ts backend-fast -- packages/backend/src/billing/controllers/billing.controller.test.ts packages/backend/src/common/constants/config.constants.test.ts packages/backend/src/servers/express/express.server.test.ts
  • bun packages/scripts/src/testing/test-mongo-env.ts backend -- packages/backend/src/billing/services/stripe.service.db.test.ts
  • bun packages/scripts/src/testing/test-parallel.ts web -- packages/web/src/billing/BillingGateModal.test.tsx packages/web/src/billing/useAppAccess.test.tsx packages/web/src/api/util/api.util.test.ts
  • bun run type-check

@tyler-dane
tyler-dane merged commit 1d30b13 into main Aug 13, 2026
20 checks passed
@tyler-dane
tyler-dane deleted the fix/billing-checkout-session branch August 13, 2026 03:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant