Leyla открывает заказ №42 и нажимает «Оплатить». Что должен сделать ваш сервер? Не принимать карту (мы выяснили почему в уроке 038), а создать в Stripe Checkout Session и отправить клиента на готовую страницу оплаты. В этом уроке мы подключим Stripe к магазину из проекта с событиями: подготовим ключи, опишем товар и цену, создадим сессию, научимся не доверять цене от клиента и поймём, почему страница «Спасибо» ничего не доказывает.
Как работает Checkout
Stripe Checkout — готовая платёжная страница на стороне Stripe: она принимает карты и другие способы оплаты, сама показывает 3-D Secure, переводится на языки покупателей и удобна на телефоне. Вам остаётся создать Checkout Session — объект с описанием того, что платит клиент (товары, сумма, валюта, адреса возврата), и отправить клиента по session.url.
Аналогия: официант (ваш сервер) оформляет счёт и ведёт гостя к кассе Stripe. Гость платит и возвращается с чеком в руках, но чек в руках гостя ещё не значит, что деньги дошли.
Шаги 1–4: кнопка вызывает ваш маршрут, сервер создаёт сессию в Stripe и получает url. Шаги 5–6: браузер переходит на страницу Stripe, клиент платит, и Stripe возвращает его на success_url. Шаг 7 идёт отдельно от браузера: Stripe вызывает ваш вебхук (урок 040).
Ключи и подготовка
В Dashboard (песочница) откройте Developers → API keys. Там два ключа: publishable pk_test_… (его безопасно показывать в браузере; для редиректа на Checkout он не нужен) и secret sk_test_… (только для сервера). В продакшене Stripe советует restricted-ключи rk_… с минимальными правами. Сохраните ключ в .env:
# .env (never commit this file)
STRIPE_SECRET_KEY=sk_test_51...
APP_URL=http://localhost:3000Установите SDK командой npm install stripe (нужен Node.js 20+). Начиная с 22-й версии Stripe — класс, и объект создают только через new:
// src/stripe.js
import Stripe from 'stripe';
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);Products и Prices
В Stripe товар описывают двумя объектами. Product — что вы продаёте (название, описание, картинка). Price — сколько и как часто: сумма в минимальных единицах, валюта, разовый или регулярный платёж. У одного товара может быть несколько цен. Цену не редактируют: для новой суммы создают новую цену, а старую архивируют, ведь она остаётся записью о прошлых платежах.
Создать их можно в Dashboard (раздел Product catalog) или через API:
// scripts/create-price.js (run once)
import { stripe } from '../src/stripe.js';
const product = await stripe.products.create({ name: 'Node.js Handbook' });
await stripe.prices.create({
product: product.id,
currency: 'azn',
unit_amount: 2500, // 25.00 AZN in minor units
});Идентификаторы prod_… и price_… потом подставляют в line_items: { price: 'price_…', quantity: 2 }.