Photo by chansu shin on Unsplash

On this page

Selling online means moving money and state across three places: the browser where someone pays, your server where you enforce business rules, and Stripe where card networks and banks are orchestrated. Stripe is a payments platform: you create and update objects through its HTTP API (or Dashboard), Stripe handles compliance-sensitive steps such as card data collection, and your app reacts to webhooks when money actually moves.

This series walks through an Express app in JavaScript (ES modules). Examples keep your own user records in an in-memory Map so the focus stays on Stripe, not on picking a database.

What Stripe provides in a web stack

Your application still owns accounts, entitlements, and fulfillment. Stripe owns payment instruments, charge attempts, subscription billing cycles, and the ledger events that go with them.

Layer Your code Stripe
Browser Product pages, “Buy” buttons, optional custom forms Stripe.js, Checkout hosted page, Payment Element
Server Auth, carts, mapping userId → customerId REST API: Customers, Prices, Checkout Sessions, PaymentIntents, Subscriptions
After payment Grant access, send email, update inventory Webhooks: signed Event payloads

Card numbers never touch your server when you use Checkout or the Payment Element with Stripe.js. That keeps you out of the heaviest PCI scope; you still must protect API keys and webhook endpoints.

Core API objects at a glance

Most integrations revolve around a small graph of objects. One-time sales usually flow through a Checkout Session or PaymentIntent; recurring revenue adds Subscription and Invoice.

Diagram 1
flowchart TB
  Customer --> PaymentMethod
  Product --> Price
  Price --> CheckoutSession
  Customer --> CheckoutSession
  CheckoutSession --> PaymentIntent
  PaymentIntent --> PaymentMethod
  Customer --> Subscription
  Price --> Subscription
  Subscription --> Invoice
  StripeAPI[Stripe API] --> Event
  Event --> WebhookEndpoint[Your webhook handler]
  • Customer — Identity in Stripe for a person or business; holds default payment methods and metadata you sync from your app.
  • Product and Price — What you sell and how much it costs (one-time or recurring). Prices are versioned; you replace a price instead of editing amount in place.
  • Checkout Session — Hosted or embedded checkout flow; recommended starting point for many web apps.
  • PaymentIntent — Tracks a single payment attempt, including authentication (3D Secure) and status transitions.
  • PaymentMethod — A saved card, wallet, or other instrument attached to a Customer.
  • Subscription — Recurring billing for one or more Prices; generates Invoices on a schedule.
  • Event — Something that happened in Stripe; delivered to your server as a webhook.

Later chapters go deep on each piece. For marketplaces and tax, Stripe also offers Connect, Tax, and other products—a short tour appears in Stripe beyond payments.

Test mode, live mode, and sandboxes

Every Stripe account has test mode and live mode keys. Test mode uses fake money and test card numbers; live mode moves real funds.

For new work, Stripe recommends sandboxes: isolated test environments with their own settings and data, separate from the account-wide test mode sandbox. Use different sandboxes for local development and CI when you can. Existing teams on the shared test mode sandbox can keep using it until migration makes sense.

Never mix keys: a test secret key against live objects (or the reverse) fails or creates confusing errors. The Dashboard and API keys page show which mode you are in.

Money amounts and currencies

Stripe amounts are integers in the smallest currency unit—cents for USD/EUR, whole yen for JPY (zero-decimal currencies). Sending 10.99 as a float is a common bug; send 1099 with currency: 'usd'.

Multi-currency catalogs use one Price per currency or separate Prices per market. Tax and presentment rules are product-specific; Stripe Tax can calculate tax when you enable it with proper registrations.

Where payments fit in the request flow

A typical one-time purchase looks like this:

  1. The user clicks Pay in your app.
  2. Your server creates a Checkout Session (or PaymentIntent for a custom form) and returns a URL or client_secret.
  3. The user completes payment on Stripe’s UI or your embedded form.
  4. Stripe sends a webhook (for example checkout.session.completed) to your server.
  5. Your webhook handler marks the order paid and unlocks the product.

The browser redirect to a “success” page is for UX only. Fulfillment belongs in the webhook handler, not in the success route, because the user can close the tab before your server runs or payment can complete asynchronously.

Next: Stripe API keys and the Node.js SDK.

Check your understanding

Question 1 of 5

0 of 5 checked

  1. 1. According to the overview, where do card numbers go when you use Checkout or the Payment Element with Stripe.js?

Search articles

Type a word to search published articles.

Open the search page