Classes 10–12 (F): Stripe, in test mode

Part of the task-app setup for Classes 10–12. Work through the parts in order, doing every step yourself; Start here has the worksheet, the screenshot log, how to ask Claude when you’re stuck, and the list of all parts.

Time: about 10–20 minutes.

As of Oct 22, 2026 · Official docs: Stripe · Stripe sandboxes · Stripe API keys · Stripe subscriptions · Stripe customer portal · Supabase Vault · Supabase: Edge Function secrets

Stripe handles the app’s monthly “Premium” subscription. Everything here is in test mode (Stripe calls it a sandbox): no real money moves, and you pay with test card numbers.

  1. Get a Stripe account, with its sandbox. A sandbox is a practice copy of a Stripe account, with pretend money. While you’re in one, a dark bar across the top says “You’re testing in a sandbox”. Each Stripe account comes with one sandbox, and you do every Stripe step in it.

    Go to dashboard.stripe.com/register and sign up with your email, your name, your country and a password, then confirm your email address. If Stripe asks for a business or account name, type the name of your other projects, for example task-app-2026-maria.

    Make a new account for this app, so that it starts empty. Sign in at dashboard.stripe.com, click your account’s name at the top left, point at Create, and click Create account. Click Create a separate account, then Next. Type the Account name, for example task-app-2026-maria, choose your Country of operation, and click Create.

    Your account’s name › Create › Create account

    Your account’s name › Create › Create account

    Create a separate account, then Next

    Create a separate account, then Next

    The account’s name and country

    The account’s name and country

    Stripe then asks a few setup questions. This app needs none of them:

    • Welcome to Stripe (business name and location): your account’s name is filled in. Click Continue.
    • Describe your business and What do you need to get started?: click Skip.
    • Choose how to set up Stripe: keep Set up in the Dashboard and click Continue.
    • Get started in your sandbox: click Go to sandbox.
    • A purple box, Next, verify your account: click Got it.

    You’re now in the sandbox: the dark Sandbox bar is at the top, and your account’s name is at the top left. Stripe keeps offering to verify your business or activate payments, which asks for your Social Security number and bank details. Skip it: that’s only needed to take real money.

    Everything in a sandbox is pretend: you pay with test card numbers such as 4242 4242 4242 4242, and its Balances can’t be paid out. Your live account is the real one, for real customers and real money (the purple Switch to live account button at the top right). This project never uses it.

    Why a new account, if you already have one? A Stripe account that isn’t verified can have only one sandbox: to create a second one, Stripe asks you to verify your business first. A new account brings its own empty sandbox, needs no verification, and keeps this app’s products and keys apart from anything else you’ve done in Stripe.

    Get started in your sandbox: click Go to sandbox

    Get started in your sandbox: click Go to sandbox
  2. Copy the API keys. On the sandbox’s Home page, the API keys box at the right shows a Secret key (sk_test_...) and a Publishable key (pk_test_...). Each shows only its start and end, but the copy icon next to it copies the whole key. Paste each one into the worksheet’s My Info sheet: Publishable key (test mode) and Secret key (test mode). (Go to API keys, in the same box, opens the full API keys page, with the same copy icons.)

    The secret key can do anything in your Stripe account, so it only ever goes to servers (here, Supabase), never into the app’s web pages or into Claude’s chat. The publishable key is made to be seen, in web pages; this app doesn’t use it, because it sends users to Stripe’s own checkout page.

    When a user clicks Upgrade, the browser doesn’t talk to Stripe itself. It asks the Edge Function create-stripe-session, which checks who the user is and asks Stripe, with the secret key, for a checkout page for that user at your price. Only a server may make that request: anything in the browser can be changed by its user, who could otherwise pick their own price. More in Publishable and Secret Keys: why the server holds the secret keys, what Stripe’s publishable key is for, and a table of all eight keys and secrets the app uses.

    The API keys box, with a copy icon next to each key. In this picture the keys are blurred.

    The API keys box, with a copy icon next to each key. In this picture the keys are blurred.
  3. Create the product. Click Product catalog in the left menu, then + Create product at the top right. In the Add a product panel:

    • Name: TaskMaster Premium
    • Under Pricing, Recurring and the Billing period Monthly are already selected.
    • Amount: 10.00 (USD).

    Click Add product. Then copy the price’s ID: in the list, click TaskMaster Premium, and in its Pricing section, click the price ($10.00 USD). The page Price for TaskMaster Premium shows the ID (price_...) at the top right, with a copy icon. Paste it into the worksheet’s Price ID of the monthly price, and type TaskMaster Premium as the Product name.

    A product is what you sell; a price says how much and how often. One product can have several prices (for example, monthly and yearly). When a user upgrades, the app asks Stripe for a subscription to one price, by its ID, which is why the app needs the price ID and not the product’s ID (prod_...). A price ID isn’t secret: nobody can charge or change anything with it.

    Add a product, filled in

    Add a product, filled in

    The product’s page: click the price

    The product’s page: click the price

    The price’s page: its ID at the top right, with a copy icon

    The price’s page: its ID at the top right, with a copy icon
  4. Set up the customer portal. The customer portal is a Stripe page where subscribers manage or cancel their subscription; the app’s Manage Subscription button opens it. Click the gear icon (Settings) at the top right. Under Product settings, click Billing, then Customer portal. Click Cancellations to open it, choose Cancel immediately (leave Prorate canceled subscriptions on), and click Save changes. A Portal configuration box showing Default appears at the top: the portal is ready.

    Until you save these settings once, the sandbox has no portal, and the app’s Manage Subscription button gets an error from Stripe. Cancel immediately is for class demos: a cancelled subscription then switches the app back to the free plan right away, not at the end of the month. Prorate gives the customer credit for the unused days of the month (pretend money, in a sandbox).

    Cancellations: Cancel immediately

    Cancellations: Cancel immediately

    After Save changes: Portal configuration, Default

    After Save changes: Portal configuration, Default
  5. Store the secret key in Supabase Vault. Supabase Vault is an encrypted store for secrets inside your database. The database uses the Stripe secret key from there to create a Stripe customer for each new user.

    In the Supabase dashboard, open your project and click SQL Editor in the left menu (point at the icons to see their names). Paste the Vault line from the worksheet’s Commands sheet and click Run. Under Results, one row appears under create_secret: a long ID such as 1b11a542-d269-..., the stored secret’s ID. You don’t need to keep it.

    Then close the query’s tab: click the × next to Untitled query. A box Unsaved changes asks whether to keep editing. Click Discard changes: you lose nothing you need. Run already stored your key in Vault; “discard” only throws away the text in the editor, so that the line with your key isn’t kept in Supabase’s list of saved queries.

    The Vault line is SQL, the language of databases, not a terminal command: select vault.create_secret('sk_test_...', 'stripe'); calls the function create_secret in Supabase’s vault, with two values in quotes: your secret key, and the name to store it under (stripe).

    The Vault line after Run: one row, the new secret’s ID. In this picture the key is blurred.

    The Vault line after Run: one row, the new secret’s ID. In this picture the key is blurred.

    Closing the query’s tab: click Discard changes. Your key is already stored in Vault; this only clears the editor.

    Closing the query’s tab: click Discard changes. Your key is already stored in Vault; this only clears the editor.
  6. Give the Edge Functions the Stripe key and the price ID. In VS Code’s terminal, first go into the app’s folder. It’s harmless if you’re already there; this just makes sure:

    cd ~/projects/full-stack-demo-app/task-app

    Then copy the STRIPE_SECRET_KEY line from the worksheet’s Commands sheet, paste it into the terminal, and press Enter. It prints Finished supabase secrets set. Do the same with the STRIPE_PRICE_ID line. (If it prints something else, see the box “Why? Why the cd first” in (E) step 6.)

The webhook comes in Step H, once the functions are deployed.

Corrections to the older Stripe chapter

Step 8: Set Up Stripe puts the price ID in .env.local, but the app never reads it from there. The price ID must be a Supabase secret named STRIPE_PRICE_ID (step 6 above), and the Vault step (step 5) is missing from that chapter.

© 2025-2026 Y. Rosenthal. All rights reserved.