Проект · Урок 72

Проект: магазин с оплатой

Главное отличие сильного портфолио — «взрослость»: не статичный лендинг, а продукт с реальными деньгами. Принимаем платежи через Stripe/ЮKassa и понимаем, откуда приходит подтверждение.

Как устроены платежи

Ваш сервер не видит и не хранит карту. Клиент её вводит на странице провайдера; провайдер возвращает код успеха/платёж другой стороне, а ваш бэкенд получает результат по webhook — сервер считает заказ оплаченным.

// Сервер: создать платёж и вернуть клиенту ссылку/сессию
const session = await stripe.checkout.sessions.create({
  mode: "payment",
  line_items: [{ price: product.priceId, quantity: 1 }],
  success_url: "https://myshop.ru/success"
});
res.json({ url: session.url });

Webhook: статусы платежа

app.post("/webhooks/stripe", express.raw({ type: "application/json" }), async (req) => {
  const sig = req.headers["stripe-signature"];
  const event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
  if (event.type === "checkout.session.completed") {
    await db.query("UPDATE orders SET paid=TRUE WHERE sid=$1", [event.data.object.id]);
  }
  res.json({ received: true });
});
💡
Обрабатывайте webhook идемпотентно: уведомления могут дублироваться. «paid=TRUE» повторно — просто строка не изменится, но для переданных сумм считайте «уже было» флагом.

Какие карты для тестов

Провайдер даёт тестовые карты: Stripe — 4242 4242 4242 4242 (любая будущая дата, CVV любые). Реальные деньги не списываются — только «среда sandbox».

ℹ️
Безопасность из урока 61 здесь в прямом смысле: никогда не пишите карту в код, держите ключи в env (урок 62), проверяйте подпись webhook. Это продукт, который (не) ломают — и это видно в резюме.
💡
Уроки пройдены: от тегов HTML до оплат и оркестрации. Теперь портфолио из уроков 10, 18, 19, 34, 36, 71 и 72 — это убедительное «могу под ключ». Вы справились!

Следующая ступень — уроки с 73 по 90: веб-компоненты, системный дизайн, кроссплатформа и новые проекты.