Обзор
Каждый платёж в evntflo проходит через определённую последовательность статусов. Переходы между статусами происходят автоматически на основе webhook-уведомлений от платёжного шлюза. Организатор видит текущий статус в разделе Участники и в детали регистрации.
Статусы платежа
| Статус | Описание |
|---|---|
pending | Платёж создан, участник перенаправлен на страницу оплаты шлюза |
paid | Деньги получены, шлюз подтвердил оплату через webhook |
failed | Оплата не прошла (недостаточно средств, карта заблокирована, ошибка 3D Secure) |
expired | Участник не завершил оплату в течение отведённого времени (30 минут) |
refunded | Возврат выполнен полностью |
partially_refunded | Выполнен частичный возврат |
Диаграмма переходов
создание платежа
│
▼
┌────────┐
│pending │
└───┬────┘
│
┌───────┼───────┐
▼ ▼ ▼
┌──────┐ ┌────┐ ┌───────┐
│failed│ │paid│ │expired│
└──────┘ └─┬──┘ └───────┘
│
┌──────┴──────┐
▼ ▼
┌──────────┐ ┌──────────────────┐
│refunded │ │partially_refunded│
└──────────┘ └──────────────────┘
Переходы необратимы: paid не может вернуться в pending, а refunded — в paid.
Бронирование (Reservation)
Перед созданием платежа evntflo создаёт бронь — временный захват билета, чтобы он не ушёл другому участнику, пока первый оплачивает.
Как работает бронь
- Участник нажимает «Оплатить» — evntflo создаёт reservation с
TTL 15 минут. - Из доступного количества билетов вычитается забронированное место.
- Участник перенаправляется на страницу оплаты шлюза.
- Если оплата прошла — бронь превращается в подтверждённую регистрацию.
- Если TTL истёк — бронь автоматически освобождается, билет снова доступен.
Бронирование предотвращает ситуацию, когда двое участников оплачивают последний билет одновременно.
Webhook-обработка
evntflo узнаёт о результате платежа через webhook — HTTP-запрос от платёжного шлюза на серверы evntflo.
Последовательность
- Шлюз (ЮKassa, Точка, Telegram) отправляет POST-запрос на webhook URL evntflo.
- evntflo проверяет подпись запроса (каждый шлюз использует свой механизм подписи).
- Платёж обновляет статус в базе данных.
- Если статус
paid— регистрация участника подтверждается, отправляется email с билетом. - Если статус
failedилиexpired— бронь освобождается.
Повторные доставки
Если evntflo не смог обработать webhook (например, вернул 5xx), шлюз повторяет запрос:
- ЮKassa: до 10 попыток с экспоненциальной задержкой
- Точка: до 5 попыток с интервалом 5 минут
Благодаря idempotency-ключам повторная обработка одного и того же webhook безопасна и не создаёт дубликатов.
Idempotency-защита
Каждая платёжная операция в evntflo защищена idempotency-ключом — уникальным идентификатором, который гарантирует, что операция выполняется ровно один раз.
Зачем это нужно
- Участник случайно нажал «Оплатить» дважды — создаётся только один платёж
- Webhook пришёл повторно из-за таймаута — статус обновляется один раз
- Сетевой сбой прервал запрос, клиент отправил повтор — деньги не списываются дважды
Как это работает
- При создании платежа evntflo генерирует
Idempotency-Key(UUIDv7). - Ключ отправляется в заголовке запроса к шлюзу.
- Если шлюз получает повторный запрос с тем же ключом, он возвращает результат первой операции.
- evntflo кэширует ключ в Redis с TTL 24 часа.
Связь статусов платежа и регистрации
Статус платежа напрямую влияет на статус регистрации участника:
| Статус платежа | Статус регистрации | Что видит участник |
|---|---|---|
pending | payment_pending | «Ожидает оплаты» |
paid | registered | «Зарегистрирован», получает билет на email |
failed | payment_failed | «Оплата не прошла», предлагается повторить |
expired | expired | «Время оплаты истекло», предлагается начать заново |
refunded | refunded | «Возврат оформлен» |
При включённой модерации между оплатой и финальным статусом registered может быть промежуточный этап проверки организатором.
Просмотр истории платежей
Все платежи и их статусы доступны в разделе Участники вашего мероприятия. Для каждой записи отображаются:
- Текущий статус платежа
- Метод оплаты (карта, СБП, Stars)
- Сумма и валюта
- Дата и время создания / оплаты / возврата
- Idempotency-ключ (для диагностики)
- История переходов между статусами
Для экспорта данных о платежах — Экспорт платежей и отчёты.