Day 01 Foundations

Accepting Payments with Stripe Checkout

Stripe Checkout is the fastest path from zero to a working payment flow. Today you wire up API keys, create a Product and Price in the dashboard, launch a hosted Checkout Session, and handle the success and cancel redirects — all in under 60 lines of server code.

~1 hour Intermediate Hands-on Precision AI Academy

Today's Objective

By the end of this lesson you will have a working Stripe Checkout flow that accepts a test payment, redirects on success, and handles the cancel case cleanly.

Every SaaS product, marketplace, and digital store eventually needs to take money. Stripe is the dominant infrastructure layer for that job, and Checkout is its highest-leverage entry point. Instead of building your own payment form, handling card tokenization, and worrying about PCI compliance, you hand a user off to a Stripe-hosted page and receive a webhook when the money moves.

01

API Keys and Environment Setup

Stripe gives every account two key pairs: publishable and secret, each in test and live variants. The publishable key is safe to expose in client-side JavaScript. The secret key must never leave your server.

Retrieve both from the Stripe Dashboard → Developers → API Keys. Store the secret key in an environment variable — never hard-code it in source.

.env
Shell
STRIPE_SECRET_KEY=sk_test_51...
STRIPE_PUBLISHABLE_KEY=pk_test_51...
STRIPE_WEBHOOK_SECRET=whsec_...

Install the SDK:

terminal
Shell
npm install stripe   # Node.js
pip install stripe   # Python
Use test keys during development. Test-mode keys start with sk_test_. Real card numbers are rejected; use Stripe's test card 4242 4242 4242 4242 with any future expiry and any CVC.
02

Creating a Checkout Session

A Checkout Session is a server-side object that represents a pending payment. You create it with the items, amounts, currency, and redirect URLs, then redirect the user to session.url. Stripe handles everything from there — card entry, 3D Secure, error messages.

checkout.js (Node)
JavaScript
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const session = await stripe.checkout.sessions.create({
  payment_method_types: ['card'],
  line_items: [{
    price_data: {
      currency: 'usd',
      product_data: { name: 'Pro Plan' },
      unit_amount: 4900,        // cents
    },
    quantity: 1,
  }],
  mode: 'payment',
  success_url: `\${YOUR_DOMAIN}/success?session_id={CHECKOUT_SESSION_ID}`,
  cancel_url:  `\${YOUR_DOMAIN}/cancel`,
});

res.redirect(303, session.url);
03

Success, Cancel, and the Session Object

After payment, Stripe redirects back to your success_url with a session_id query parameter. Retrieve the session on your success page to confirm the payment status before granting access.

success.js
JavaScript
const sessionId = req.query.session_id;
const session = await stripe.checkout.sessions.retrieve(sessionId);

if (session.payment_status === 'paid') {
  // provision access, send receipt email, update DB
}
× Common Mistake

Trust the Redirect Alone

Redirecting to /success only means the user finished the Checkout flow — not that payment succeeded. Always retrieve the session and check payment_status === 'paid'.

✓ Correct Pattern

Retrieve and Verify

Fetch the session server-side by ID and inspect the payment status before granting any access or sending confirmation emails.

Never grant access based on the URL alone. A user could manually navigate to your /success page. Always verify server-side.

Supporting Videos & Reading

Go deeper with these external references.

Day 1 Checkpoint

Before moving on, you should be able to answer these without looking:

Continue To Day 2
Subscriptions & the Customer Portal