Auth and protected routes
Supabase email/password, Google OAuth, session-aware redirects, and server-enforced route protection.
Echo is not just a polished landing page with fake app screenshots behind it. This demo is the working starter surface: public marketing pages, Supabase auth, protected routes, Creem billing, webhook-driven sync, credits, and admin billing ops all connected inside one Next.js App Router project.
Demo at a glance
Live site
https://echo-psskad326-team-effie.vercel.app
Auth callback
https://echo-psskad326-team-effie.vercel.app/auth/callback
Webhook route
https://echo-psskad326-team-effie.vercel.app/api/webhooks/creem
Core stack
Next.js + Supabase + Creem + Tailwind
Supabase email/password, Google OAuth, session-aware redirects, and server-enforced route protection.
Creem checkout, customer portal access, plan switching, cancel-at-period-end, and top-up purchases.
Subscription status and credit grants reconcile from verified webhooks instead of client guesses.
Users, subscriptions, balances, ledger entries, and webhook events live in Supabase with RLS.
How it works
The landing and pricing pages route into sign-up or billing instead of dead-end demo CTAs.
Customers can sign up with email/password or Google and are synced into local user records.
The billing page launches Creem checkout for subscriptions or one-off credit top-up packs.
Successful subscription and payment events post to the webhook route and are signature-verified.
Webhook handlers update entitlement, period dates, cancellation flags, and credit grants.
Entitled users can access dashboard and credits pages while inactive users are redirected cleanly.
Security model
Auth checks happen server-side in layouts, server actions, and route handlers.
Creem subscription and credit truth is owned by server-side reconciliation, not by browser state.
Webhook processing is idempotent through stored event records to prevent duplicate grants.
Supabase Row Level Security restricts reads to the current user's rows.
Credit grants and debits use SQL functions so balance changes stay atomic.
Admin billing tools are restricted by the configured ADMIN_EMAILS allowlist.
Routes to try
/pricing
Public plan surface that routes into sign-up and billing-aware flows.
/signup?next=%2Fbilling
Fastest way to test auth and land directly on the billing screen after account creation.
/billing
Core demo route for plan purchase, plan changes, portal access, and cancellation.
/credits
Shows wallet balances, recent ledger entries, and the sample debit flow.
/dashboard
Protected customer area unlocked by entitled subscription state.
/admin/billing
Admin-only operational view for recent webhook events and manual credit adjustments.
Spin it up locally
Use the same production concepts locally: Supabase callback URL, Creem product IDs, and webhook route. The starter is already structured for App Router SSR auth, protected app routes, and billing lifecycle updates.
Start by copying .env.example to.env.local, run the Supabase migration, create the Creem products usingcreem-products.txt, then boot the app.
Add http://localhost:4000/auth/callback
Enable email/password and Google in Supabase Auth.
Set Creem's webhook to your local tunnel or deployed webhook URL.
Use test-mode product IDs first so plan purchases are safe to validate.
npm install
npm run lint
npm run build
npm run devNEXT_PUBLIC_SITE_URL=http://localhost:4000
NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
CREEM_API_KEY=creem_test_your_api_key
CREEM_WEBHOOK_SECRET=your_creem_webhook_secret
NEXT_PUBLIC_CREEM_TEST_MODE=true
NEXT_PUBLIC_CREEM_ECHO_STARTER_MONTHLY_PRODUCT_ID=prod_echo_starter_monthly
NEXT_PUBLIC_CREEM_ECHO_STARTER_YEARLY_PRODUCT_ID=prod_echo_starter_yearly
NEXT_PUBLIC_CREEM_ECHO_PRO_MONTHLY_PRODUCT_ID=prod_echo_pro_monthly
NEXT_PUBLIC_CREEM_ECHO_PRO_YEARLY_PRODUCT_ID=prod_echo_pro_yearly
NEXT_PUBLIC_CREEM_ECHO_SCALE_MONTHLY_PRODUCT_ID=prod_echo_scale_monthly
NEXT_PUBLIC_CREEM_ECHO_SCALE_YEARLY_PRODUCT_ID=prod_echo_scale_yearly
NEXT_PUBLIC_CREEM_ECHO_SMALL_TOPUP_PRODUCT_ID=prod_echo_small_topup
NEXT_PUBLIC_CREEM_ECHO_GROWTH_TOPUP_PRODUCT_ID=prod_echo_growth_topup
NEXT_PUBLIC_CREEM_ECHO_SCALE_TOPUP_PRODUCT_ID=prod_echo_scale_topup
ADMIN_EMAILS=founder@example.com,ops@example.comWhat to customize first
Paste your real Creem product IDs first so the plan cards and top-up packs become live checkout actions.
Run the Supabase SQL migration before testing webhooks, credits, or protected routes.
Replace the placeholder social/contact values like hello@echobills.space and @echobills once your final brand handles are ready.
Edit plan copy, prices, and features in the billing catalog if you want to reposition the offer before publishing.
Use this page as a checklist
Create an account and land on /billing.
Buy a plan or a top-up pack in Creem test mode.
Watch the webhook insert into webhook_events and update subscriptions.
Confirm /dashboard and /credits unlock for an entitled user.
Try a plan change, portal jump, and cancel-at-period-end flow.