Billing And Trial
Hosted Compass uses Stripe Checkout (subscription mode, 7-day trial, $7.99/month) and the Stripe Billing Portal. There is no Stripe.js and no publishable key in the web bundle.
Self-host installs omit the stripe: config block. /api/config then reports
billing.isConfigured: false, the web never shows a paid gate, and event
writes stay open.
What users see
- Never signed up: the existing 7-day anonymous
localStoragetrial andTrialGateModal. Unchanged. - Signed up, no card yet:
awaiting_checkout, read-only,BillingGateModalwith Subscribe (Stripe Checkout). - Trialing / active / past_due: writable.
past_duealso shows a banner. - Expired / canceled: read-only until they subscribe again. A later Checkout does not grant another trial.
There is no POST /api/billing/trial/start. A trial only begins through
Stripe Checkout (trial_period_days on the first subscription).
Existing accounts are not grandfathered. bun run cli backfill-billing places
rows without billing.subscriptionStatus onto a 7-day trial. The default
BACKFILL_CUTOFF is far in the future so every such row is included; set it
to a past instant to grandfather newer signups. Those rows have no Stripe
subscription id, so they self-expire locally when trialEndsAt passes.
Staging
Set STRIPE_SECRET_KEY (sk_test_... is fine), STRIPE_WEBHOOK_SECRET,
and STRIPE_PRICE_ID on the staging-cloud GitHub Environment, then
re-run Deploy staging so ~/compass/compass.yaml is rewritten. A restart
on old yaml will not pick up new secrets. Confirm /api/config shows
billing.isConfigured: true.
The webhook endpoint (https://staging.compasscalendar.com/api/billing/webhook/stripe)
must subscribe to Checkout and Subscriptions snapshot events, not Accounts v2:
checkout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
staging-selfhosted must not get those secrets — it is the live regression
that self-host stays writable.
Sales tax (automatic_tax) is a Stripe Dashboard decision, not a code one,
and should be settled before production keys.
Key files
- Plan/price copy:
packages/core/src/constants/billing.constants.ts - Status derivation:
packages/backend/src/billing/services/billing.service.ts - Checkout / portal:
packages/backend/src/billing/services/stripe.service.ts - Webhook:
packages/backend/src/billing/services/billing.webhook.service.ts - Write guard:
packages/backend/src/billing/billing.guard.ts - Web access:
packages/web/src/billing/useAppAccess.ts