Как проверить успешность платежа?
Что проверяют
Понимаете ли вы, что успех платежа подтверждает только сервер, а не браузер пользователя. Интервьюер ждёт рассказа про вебхуки, подпись и идемпотентность. Следом почти всегда спрашивают, что будет, если уведомление от провайдера придёт дважды или не придёт вовсе.
Как отвечать
Опишите путь платежа в бэкенде на Python:
- создание: сервер создаёт платёж через API провайдера с ключом идемпотентности и сохраняет запись со статусом
pending, суммой, валютой и идентификатором платежа у провайдера; - редирект не подтверждение: возврат пользователя на страницу «спасибо» ничего не доказывает, этот адрес можно открыть руками;
- вебхук: проверьте подпись (HMAC от тела запроса, сравнение через
hmac.compare_digest) или сверьте статус отдельным запросом к API провайдера. Только после этого заказ становится оплаченным; - сверка данных: сумма, валюта и номер заказа в уведомлении должны совпасть с сохранёнными. Иначе оплату в 10 рублей можно выдать за заказ на 10 тысяч;
- идемпотентная обработка: провайдеры повторяют вебхук, пока не получат ответ 2xx. Храните идентификатор события под уникальным индексом и меняйте статус атомарно, например
UPDATE ... WHERE status = 'pending'; - быстрый ответ: вебхук отвечает сразу, а письма и выдача доступа уходят в очередь, например в Celery;
- фоновая сверка: периодическая задача опрашивает API по платежам, которые висят в
pendingдольше обычного, на случай потерянного уведомления.
Деньги храните в Decimal или целым числом в копейках, а у HTTP-клиента (httpx, requests) всегда задавайте таймаут.
Где спотыкаются
Проверяют только код ответа 200. Он означает, что запрос дошёл, а статус платежа лежит в теле и может быть canceled или всё ещё pending.
Доверяют вебхуку без проверки подписи. Тогда любой, кто знает адрес обработчика, сам «оплатит» себе заказ.
Не думают о гонках: вебхук и фоновая сверка приходят одновременно, и без атомарного обновления статуса пользователь получает товар или письмо дважды.