EMZETT.
Войти

Stripe

Коротко: Платёжный провайдер для онлайн-платежей (оформление заказа, подписки, вебхуки) — известен чётким разделением тестового и боевого режимов.

Подробнее: В тестовом режиме весь процесс оплаты можно пройти технически так же, как в боевой работе (с тестовыми номерами кредитных карт), без полной проверки бизнеса. Лишь переход в боевой режим (настоящие деньги) требует подтверждений, например регистрации бизнеса/записи в торговом реестре.

Наш контекст: В Emzett он пока продолжает работать в тестовом режиме, потому что бизнес ещё не зарегистрирован — логика оплаты остаётся в коде, так что потом нужно будет лишь заменить ключи.

Подробности

Stripe основан в 2010 году из наблюдения братьев Коллисон, что онлайн-платежи для разработчиков непропорционально сложны — соответствие PCI, банковские подключения и проверки на мошенничество приходилось решать заново практически каждой компании самостоятельно. Основная идея — платёжная интеграция, добавляемая несколькими строками кода, при этом всю регуляторную и защитную сложность Stripe скрывает внутри. Это стало отраслевым стандартом: многие SaaS-продукты, маркетплейсы и сервисы подписок сегодня строятся прямо на Stripe вместо разработки собственной обработки платежей.

Stripe моделирует весь платёжный процесс двумя строительными блоками: Checkout (соответствующая PCI платёжная страница, размещённая у Stripe, на которую вы перенаправляете клиента вместо самостоятельного приёма данных карты) и вебхуки (асинхронные уведомления, которыми Stripe сообщает вашему серверу, что платёж действительно завершён). Это осознанный шаблон безопасности и надёжности: перенаправление на вашу страницу успеха после оплаты — НЕ тот надёжный момент, когда следует, например, помечать заказ оплаченным: клиент может закрыть вкладку до перенаправления, открыть страницу успеха заново вручную, либо сбой браузера может полностью помешать перенаправлению. Источник истины — только подписанное событие вебхука (checkout.session.completed), потому что оно приходит прямо с серверов Stripe и доставляется независимо от браузера клиента.

Безопасность вебхуков

Частая ошибка новичков: доверять конечным точкам вебхуков без проверки. Поскольку URL вебхука должен быть общедоступным (Stripe должен вызывать его снаружи), теоретически любой может отправить поддельное сообщение checkout.session.completed и тем самым получить «оплаченный» заказ. Поэтому Stripe подписывает каждый запрос вебхука заголовком подписи HMAC (Stripe-Signature), который нужно проверить на сервере вашим собственным секретом вебхука, прежде чем вообще доверять содержимому:

const sig = request.headers.get("stripe-signature")!
const event = stripe.webhooks.constructEvent(
  rawBody, // ВАЖНО: неизменённое тело запроса, а не разобранный JSON
  sig,
  process.env.STRIPE_WEBHOOK_SECRET!,
)

Акцент на «неизменённом теле» — не мелочь: многие фреймворки по умолчанию автоматически разбирают тело запроса в JSON до того, как его увидит ваш код, но проверка подписи требует именно сырых байтов в том виде, как их подписал Stripe, иначе проверка не проходит (классическая ловушка интеграций Stripe).

Ключи идемпотентности и подписки

Ещё один важный строительный блок — ключи идемпотентности: поскольку сетевые ошибки могут привести к тому, что запрос придёт дважды (клиент отправляет его снова, потому что ответ не дошёл), каждому критичному запросу вроде «списать платёж» можно присвоить уникальный ключ — по нему Stripe распознаёт дубликаты и гарантирует, что действие будет выполнено лишь один раз, сколько бы раз ни пришёл один и тот же запрос.

const session = await stripe.checkout.sessions.create(
  { line_items, mode: "payment", success_url, cancel_url },
  { idempotencyKey: orderId },
)

Для повторяющихся платежей Stripe предлагает собственный mode: "subscription", который автоматически управляет расчётными циклами, пропорциональными изменениями (proration при смене плана посреди цикла) и неудачными попытками платежа (dunning — автоматические повторы, когда срок действия карты истёк), вместо того чтобы вам самим воссоздавать эту логику.

В сравнении с альтернативами

По сравнению с PayPal Stripe предлагает гораздо более детальные API и лучшую документацию для разработчиков, но ему не хватает огромной установленной базы пользователей PayPal (многие клиенты больше доверяют знакомой кнопке PayPal, чем незнакомой форме кредитной карты). Adyen ориентирован скорее на крупных клиентов с очень индивидуальными требованиями и более сложными условиями договоров, тогда как Stripe сознательно опирается на самообслуживание без переговоров о договорах. Mollie и Klarna сильны в Европе с местными способами оплаты (прямой дебет SEPA, мгновенный банковский перевод, оплата по счёту) — Stripe теперь поддерживает многие из них, но изначально был больше сосредоточен на кредитных картах.

О переходе от тестового к боевому режиму: у обоих режимов совершенно раздельные ключи API, клиенты, продукты и конечные точки вебхуков — «повысить» тестовые данные нельзя; переход практически означает чистый перезапуск с боевыми ключами.

См. также: Переменные окружения, JSON