Skip to content
supastack
Browse documentation
WebNext.js

For AI agents: fetch the complete documentation index at /llms.txt, the full documentation corpus at /llms-full.txt, the agent skill at /skill.md, or this page as Markdown at /docs/web/stripe-payments.md (or send Accept: text/markdown).

Add Stripe payments

Create a free Stripe account, a product with a recurring price, a secret key, and the signed webhook that grants entitlements after checkout.

Beginner walkthrough

Prerequisites: the app running locally (Ship in 5 minutes) and a migrated database for real accounts (Set up database). You need an email address for the Stripe account — no card and no charges. Everything in this guide happens in test mode: fake money, test card numbers, unlimited retries before going live.

Quick terms: test mode is Stripe's sandbox — the dashboard's Test mode toggle keeps every key, product, and payment fake until you switch it off. A secret key (sk_test_…) is your server's password to Stripe. A product with a price is what customers buy; a price id (price_…) names it in code. A webhook is Stripe calling your server when a payment succeeds or a subscription changes, and the signing secret (whsec_…) proves the call really comes from Stripe.

What you create: a Stripe account, one product with a recurring price, a secret API key, and a webhook endpoint — about twenty minutes. Stripe hosts the checkout page itself; the kit creates the session server-side and redirects, so no publishable browser key is needed.

Keep scope in mind: this guide sells web subscriptions only. Purchases inside the iOS/Android app must go through Apple and Google billing — never Stripe Checkout — which is why mobile uses RevenueCat instead.

Create the Stripe account

1. Open stripe.com → Start now and sign up with your email.

2. The onboarding asks about your business — for test mode you can skip every question and still use the full sandbox; complete activation only before taking real payments.

Expected: you land on the dashboard with the Test mode toggle visible in the header. Keep it on for everything below — live keys belong in your production secret store later, never in a laptop env file.

Copy the API keys

1. In the dashboard open Developers → API keys.

2. You see two test keys: a Publishable key pk_test_… and a masked Secret key. Click Reveal test key next to the secret and copy the sk_test_… value.

The kit only needs the secret key: checkout sessions are created on the server and the user is redirected to Stripe's hosted page, so no publishable key lands in env vars. If a product you build later adds Stripe.js you would use the publishable key client-side; the kit's billing flow does not.

The sk_test_… key is a full credential for the sandbox account: it lives in apps/web/.env.local or a secret store, never in NEXT_PUBLIC_/EXPO_PUBLIC_ variables and never in Git.

Create the product and price

1. Open Product catalog → Add product.

2. Name it after your plan — Pro matches the kit's shipped plan — give it a price, and choose Recurring (monthly, for example): the kit's checkout creates subscription-mode sessions, which require a recurring price, not a one-time one.

3. Save, open the product, and copy the price id — it starts price_… (not prod_…, which is the product id).

The shipped pro plan already shows a Monthly/Yearly toggle: monthly checks out with STRIPE_PRICE_ID, and the yearly option needs a second recurring price in STRIPE_PRICE_ID_PRO_YEARLY — without it, a yearly checkout fails price-unconfigured. Change plan names, amounts, and what a purchase grants in apps/web/src/product-plans.ts — Stripe stores the money side, the plan file stores the entitlement side.

Add the webhook endpoint

The webhook is what actually grants access: the kit flips the entitlement only after a signed Stripe event arrives, so a checkout redirect alone proves nothing.

1. Open Developers → Webhooks → Add endpoint.

2. Endpoint URL: your public URL plus /api/billing/webhook — for example https://yourdomain.com/api/billing/webhook. The other billing providers get their own path under that directory; Stripe's receiver lives at the root.

3. Under Select events choose the events the kit handles: checkout.session.completed, checkout.session.async_payment_succeeded, checkout.session.async_payment_failed, invoice.paid, invoice.payment_failed, customer.subscription.created, customer.subscription.updated, and customer.subscription.deleted.

4. Create the endpoint, open its page, click Reveal under Signing secret, and copy the whsec_… value — each endpoint has its own secret.

Local development cannot receive Stripe's servers, so use the Stripe CLI instead: stripe login once, then stripe listen --forward-to localhost:3000/api/billing/webhook in a second terminal. It prints a temporary whsec_… — that value, not the dashboard one, goes in .env.local while stripe listen runs.

Add the values to the app

Set the lines below in apps/web/.env.local. BILLING_PROVIDER=stripe selects the adapter; the other three are the key, the price, and the signing secret. Enabling the provider with any of them missing fails startup and names the variable.

All three STRIPE_* values are server-only — never NEXT_PUBLIC_/EXPO_PUBLIC_, never committed; production gets them through the host's secret manager (the deploy guide covers Secret Manager). Restart the dev server after editing.

# apps/web/.env.local
BILLING_PROVIDER=stripe
STRIPE_SECRET_KEY=sk_test_…
STRIPE_PRICE_ID=price_…
STRIPE_WEBHOOK_SECRET=whsec_…   # `stripe listen` value locally; endpoint signing secret in production
# STRIPE_PRICE_ID_PRO_YEARLY=price_…   # required for the shipped Yearly toggle

Verify and troubleshoot

Start stripe listen --forward-to localhost:3000/api/billing/webhook and leave it running, restart the dev server, then open /billing, choose the Pro plan, and finish Stripe's hosted checkout with the test card 4242 4242 4242 4242, any future expiry, and any CVC.

Expected: the app returns to /billing?checkout=success and the workspace's entitlement flips active — the listen terminal logs the delivered events, and Developers → Webhooks → your endpoint on the dashboard shows green deliveries.

To exercise the receiver without clicking through checkout, stripe trigger checkout.session.completed sends a synthetic event through the listen forwarder.

Common failures: a 400 on every delivery means the signing secret does not match that endpoint — recopy whsec_… for the right endpoint and update env; silent no-ops mean BILLING_PROVIDER is still local; and sk_live_ keys mixed into a test setup mean you copied the wrong-mode keys — keep test and live strictly separate.

The kit ships the same one-contract adapter for Lemon Squeezy, Creem, Polar, Whop, Paddle, Dodo, and PayPal — same flow, different console and env names — and mobile purchases stay on RevenueCat, not Stripe.

If you want to continue setup, read Add Resend email.

Frequently asked questions

14 questions

What is supastack?

supastack is a modular foundation for building AI-powered SaaS products. It brings together common infrastructure so you can focus on product-specific features.

Does it support web and mobile?

Yes. supastack includes Next.js and Expo apps as starting points for web and mobile experiences.

What authentication is included?

Better Auth covers email OTP, magic-link, and social sign-in; email/password stays available at the API layer and through the Auth.js credentials engine for products that need it. Personal workspaces are provisioned with the account so product records stay scoped from day one.

How does it support AI?

supastack includes configurable multi-provider AI, usage tracking, budgets, and encrypted bring-your-own-key support.

How are subscriptions handled?

For products built on the kit, Stripe billing, subscriptions, and entitlements form the paid-access foundation. Provider secrets stay server-only.

Where does my product-specific code live?

Product-specific features remain in a separate codebase while the product configures and integrates supastack’s foundation modules.

How does supastack pricing work?

The kit is a one-time purchase with lifetime updates: One Platform at $249 (temporary launch price, $100 off the regular $349) — your pick of Next.js (Web), Expo (iOS & Android), or Tauri (macOS & Windows Desktop) — or the All Platforms Bundle at $499 (temporary launch price, $100 off the regular $599) with every platform and the full monorepo, plus $75 per extra developer seat. No kit subscription. Checkout on this site delivers your license key by email, with repository access via GitHub invite.

How do workspaces scope my data?

User-owned records are scoped by workspaceId. Identity, entitlements, AI usage, billing events, and audit entries stay inside the personal workspace boundary.

How do background jobs work?

Trigger.dev is the explicit job runtime. The JobRunner contract only promises enqueue, status, and cancel—workflow semantics stay Trigger.dev-specific and explicit.

How is email different from outreach?

Transactional email covers product workflows such as completion notices. Cold outreach and campaigns are product concerns outside this kit’s email module.

How do mobile purchases work?

Mobile includes native purchases and restore through RevenueCat, with access verified by your server. Configure the store accounts and complete device testing before release. Web billing remains separate.

Where do AI provider keys live?

Bring-your-own-key credentials are encrypted and stay server-only. Keys are redacted from logs; usage and budgets remain visible at the workspace level.

Which payment methods does checkout accept?

The Stripe-hosted checkout accepts cards and can also offer Alipay and WeChat Pay once those wallets are enabled on the Stripe account — handy for buyers in China. Wallet authorizations confirm asynchronously, so the license page updates as soon as the payment clears.

Can I get a refund?

After you've got access to the repository, supastack is yours forever, so it cannot be refunded. But rest assured, you get the complete source code with lifetime updates to build and ship unlimited products for yourself or clients. You just cannot resell the code or redistribute the repository as a starter kit or template.

EN
Theme