Course B · Module B1 Production · Lesson 8 of 18

Payments with Stripe

Take money online without ever touching a credit-card number yourself.

~14 min · Have your app open · Prereq: B5 API Keys & Secrets, B6 Auth

Nothing makes a prototype real faster than charging for it. But handling card payments yourself means touching sensitive financial data, staying compliant with PCI security standards, and building fraud protection from scratch. Stripe exists so you never do any of that. Your single win here: by the end you'll understand how Stripe sits between your app and the card networks, how to test without real money, and exactly how your app learns that someone has paid — so you can unlock the right thing at the right moment.

The golden rule: you never touch card data

Think of Stripe as an armored cash courier. When a customer pays, they hand their card details directly to the courier — the card number never passes through your hands at all. The courier confirms the payment is good and hands you a receipt. You act on the receipt; you never see the card.

That's not just a convenience — it's the architecture. Because the card data goes straight to Stripe's servers, you're never responsible for storing or securing it. Stripe carries PCI compliance so you don't have to.

One-time checkout vs subscriptions

Stripe handles both main billing shapes cleanly. Know which one you're building before you start:

One-time payment

Customer pays once and gets access. Use Stripe Checkout — a pre-built, hosted payment page. You redirect the customer there, Stripe takes the payment, and redirects them back to your app when done. The least code you can possibly write for a real payment.

Subscription

Customer pays a recurring amount (monthly, annually). Stripe handles the billing schedule, failed payment retries, and pro-rated upgrades. You define the price plans in the Stripe dashboard; your code just creates a subscription and Stripe takes it from there.

Both flows start the same way: you get a Stripe API key (see B5), add Stripe's library, and your AI assistant can generate the integration from the Stripe quickstart docs. Paste the URL and ask — it's among the best-documented APIs in the world.

Test mode: fake cards before real money

Stripe gives every account two completely separate modes: test and live. In test mode, nothing is real. You use Stripe's published fake card numbers to simulate every scenario — successful payment, declined card, expired card, 3D Secure challenge — and no actual charges ever occur.

4242 4242 4242 4242Stripe's standard test card. Any future expiry, any CVC. Always succeeds.
4000 0000 0000 0002Always declined. Use this to test how your app handles a failed payment.
4000 0025 0000 3155Triggers a 3D Secure authentication challenge — simulates the extra "confirm in your banking app" step.

Work entirely in test mode until everything behaves exactly as expected. Flipping to live mode is a one-line environment-variable change (B5). Your test API key and live API key are different values — keep them in separate environment variables and never mix them up.

The test-mode dashboard is your best debugging tool. Every test payment shows up in your Stripe dashboard under test mode — you can see exactly what happened, why a payment succeeded or failed, and replay webhook events. Open it alongside your app while you're building.

Webhooks: how your app learns "they paid"

Here's the moment most first-time builders get confused. After a customer pays, Stripe needs to tell your app about it. It does this with a webhook: Stripe sends an HTTP request to a URL you specify, carrying a payload that says "payment_intent.succeeded for customer Maya, $49."

Your app listens at that URL, reads the event, and acts on it: unlock the premium tier, create the order in the database, send a confirmation email (B7). Without the webhook, your app has no reliable way to know payment happened — it's the single most important connection in the whole flow.

  1. Create a webhook endpoint in your app — a URL like /api/stripe-webhook that accepts POST requests from Stripe.
  2. Register the URL in your Stripe dashboard under Webhooks, and choose which events to listen for (start with payment_intent.succeeded and customer.subscription.deleted).
  3. Verify the signature. Stripe signs every webhook with your webhook secret (another key to store in environment variables). Always verify it before trusting the payload — this prevents anyone from faking a "they paid" event.
  4. Act on the event — update the database, send the email, unlock the feature. Then respond with a 200 OK so Stripe knows you received it.
  5. Test locally with the Stripe CLI — it can forward live webhook events to your laptop during development without deploying.

Check yourself

Answer before opening — recalling it is what makes it stick.

Why does using Stripe Checkout mean you're not responsible for PCI compliance?

Because the card details go directly to Stripe's servers — they never pass through or get stored on yours. Stripe is the one handling sensitive card data and maintaining PCI compliance. You only ever receive a confirmation that payment succeeded.

You charge a customer and want your app to immediately upgrade their account. What's the right way to trigger that?

A webhook. After payment, Stripe sends a payment_intent.succeeded event to your webhook URL. Your app handles that event and upgrades the account. Don't rely on a redirect URL alone — the customer might close the browser before it fires.

You're testing checkout and want to simulate a declined card. What do you do?

Use Stripe's test card number 4000 0000 0000 0002 (always declines) in test mode. No real money involved, but your app sees exactly the same declined response it would in production — so you can build and test the failure path properly.

Read this next (primary source)

Stripe Payments Documentation — the quickstart guides walk from zero to a working checkout in under thirty minutes, with clear explanations for every step. Start with "Build a payments page" for a one-time payment, or "Set up a subscription" if that's your model. See RESOURCES.md for more.

I'm your teacher — bring me your billing model. One-time product? Monthly subscription with a free tier? Usage-based pricing? Describe how your app should charge and I'll sketch the exact Stripe flow and the two or three events your webhook needs to handle.

New terms this lesson — payment gateway, webhook, PCI compliance, test mode, subscription — are in the course glossary. Keep it open.