Почему пет-проекты ломаются на первой же оплате

Самый частый косяк в сервисах с онлайн-оплатой: фронт шлет юзера на платежный шлюз, а после редиректа на страницу «Успешно» бэк сразу открывает доступ к фиче.

В реале это гарантированные проблемы:

• Юзер закрыл вкладку до редиректа: списание прошло, а заказ повис «в обработке»

• Моргает сеть, шлюз шлет вебхук дважды: баланс улетает клиенту в double-размере (классический race condition).

• Каталог обновился, пока клиент тупил на чекауте: спишется старая цена или все упадет на валидации.

Когда собирал модуль эквайринга на базе Stripe, заложил три простых правила:

1. Доверяем только криптографическим вебхукам Статус заказа меняем строго по входящему вебхуку от шлюза с проверкой подписи заголовка (signature verification). Редирект в браузере вообще ничего не значит и доверия к нему ноль.

2. Строгая идемпотентность У каждого платежного события есть уникальный ID транзакции. Перед обработкой чекаем статус в PostgreSQL через SELECT FOR UPDATE или берем распределенный лок в Redis. Повторный вебхук просто получает 200 OK и идет дальше, ничего повторно не начисляя.

3. Снапшот цен на старте чекаута Цена товара или подписки жестко фиксируется в сущности Order в момент создания платежной сессии. Если прайс в каталоге изменится через секунду, на открытую сессию это уже не повлияет.

Обложил логику 16 тестами на pytest: прогнал эмуляцию таймаутов, дубли вебхуков и фейковые сигнатуры. Никаких задвоений и потерянных оплат.

Архитектуру и готовый код выложил на GitHub: https://github.com/map1772/stripe-shop Стек: Python, FastAPI / Django, Stripe API, Docker Compose, PostgreSQL, Pytest. Коллеги, сталкивались с дабл-списаниями на вебхуках или сразу закладываете локи в базу?

Почему пет-проекты ломаются на первой же оплате | Сетка — социальная сеть от hh.ru Почему пет-проекты ломаются на первой же оплате | Сетка — социальная сеть от hh.ru