Accounts & billing
How the website handles accounts with Supabase and subscriptions with Stripe.
Beyond marketing, the website hosts the account area (/conta) and the billing
flows. Both share the same Supabase backend as the mobile app, so a subscription bought
on the web is reflected in the app and vice-versa.
Accounts (Supabase)
src/pages/conta.astro is the account page. It talks to Supabase through
src/lib/supabase.js. The page is a single route that renders one of several states
depending on configuration and session:
| State | When it shows |
|---|---|
| Loading | While the session is being resolved. |
| Not configured | When the Supabase keys are missing — prompts you to finish setup. |
| Logged out | A split sign-in / create-account panel (email + password, with a “forgot password” link). |
| Logged in | The subscription dashboard: current plan, status, renewal date and billing actions. |
Because the website uses the same Supabase project as the app, identities and subscription state are shared. Signed-in users can:
- View their plan, status and renewal date.
- Open the Stripe billing portal to change, update or cancel.
- Request a password reset (a secure link is emailed to them).
- Request account deletion, which calls the app's
delete-accountEdge Function.
Billing (Stripe)
Subscriptions are handled by Stripe. The website ships three serverless functions
under api/:
| Function | Purpose |
|---|---|
api/create-checkout-session.js | Starts a Stripe Checkout session to subscribe to Premium. |
api/create-portal-session.js | Opens the Stripe customer portal to update or cancel a plan. |
api/stripe-webhook.js | Receives Stripe events and syncs subscription status into Supabase. |
The flow
- The user picks a plan and the site creates a Checkout session.
- Stripe collects payment and redirects back.
- Stripe calls the webhook, which updates the user's subscription columns in
Supabase (added by migration
012_stripe_columns). - Both the website and the app read that state and unlock Premium.
- To change or cancel, the user opens the billing portal from their account.
The app mirrors this with its own Supabase Edge Functions (stripe-checkout,
stripe-webhook) — see Backend & Supabase.
The plans and prices are documented in Plans & pricing.
Store subscriptions
A subscription started inside the app through the App Store or Google Play is managed in that store's subscription settings, not in the Stripe portal. The account page notes this so users don't look for a cancel button that lives in the store instead. Refunds follow the policy of whichever store or platform processed the payment; for web subscriptions, users can contact support.
Configuration
The billing and account functions need secrets (Stripe keys, Supabase URL and service
role, price IDs). These are provided as environment variables — see .env.example and
the repo's SETUP-CONTA.md for the exact list and setup steps. Until they're set, the
account page shows the Not configured state instead of failing.