Платёж — единственное место в системе, где ошибка стоит денег напрямую. Поэтому он проектируется так, будто связь оборвётся в самый неподходящий момент: она обязательно оборвётся.
Каждый шаг может завершиться неудачей — и в каждом система должна остаться в понятном состоянии.
checkout.example.rs
Операция по заказу #4821
LIVE
расхождений нет
Двойное нажатие
одна операция
Сумма подменена
подпись верна
Клиент закрыл вкладку
callback принят
Шлюз не ответил
статус уточняется
Возврат
возвращено
Сверка за день
расхождений нет
ЧТО МОЖЕТ ПОЙТИ НЕ ТАК
01Двойное нажатиеКлюч операции делает повтор безопасным: два запроса создают один платёж, а не два списания
02Сумма подмененаСумма берётся из заказа на сервере, а не из формы — подпись запроса проверяется
03Клиент закрыл вкладкуРезультат приходит отдельным уведомлением от шлюза — заказ обновится и без возврата клиента
04Шлюз не ответилОперация помечается неопределённой и допрашивается: статус запрашивается, пока не станет ясен
05ВозвратПолный или частичный, привязан к исходной операции; повторный запрос не создаёт второй возврат
06Сверка за деньВыписка сопоставляется с операциями: расхождения выводятся списком, а не ищутся вручную
ЗНАКОМАЯ КАРТИНА
Что бывает, когда оплату подключили «по инструкции»
Минимальное подключение
Клиента списали дважды, потому что он нажал кнопку два раза
Статус заказа меняется только при возврате клиента на сайт после оплаты
Если шлюз не ответил, операция остаётся в подвешенном состоянии навсегда
Возврат делают в кабинете банка, и система об этом не знает
Сверка — это бухгалтер, выписка и вечер с калькулятором в конце месяца
Инженерное подключение
Повторный запрос с тем же ключом возвращает ту же операцию, а не создаёт новую
Результат приходит на сервер напрямую и обрабатывается независимо от браузера
Неопределённые операции автоматически допрашиваются до окончательного статуса
Возврат идёт через систему, поэтому заказ, склад и отчёт узнают о нём сразу
Сверка ежедневная и автоматическая: список расхождений приходит утром
ОБЪЁМ РАБОТ
Что входит в работу с платежами
Модель операций
Заказ и платёж — разные сущности со своими состояниями; переходы между ними описаны явно.
Подключение шлюза
Инициализация, подпись запроса, обработка ответа и защищённые уведомления от банка.
Повторяемость операций
Ключи идемпотентности, чтобы повтор запроса не превращался во второе списание.
Отказы и таймауты
Понятное сообщение клиенту, сохранение заказа и автоматическое уточнение неясных статусов.
Возвраты и отмены
Полные и частичные операции из админки с проверкой прав и записью, кто их выполнил.
Сверка
Ежедневное сопоставление операций с выпиской и отчёт о том, что не сошлось.
Журнал и наблюдаемость
Каждая попытка сохранена с ответом шлюза; рост доли отказов виден сразу, а не по жалобам.
Тестовые сценарии
Проверяем не только успешную оплату, но и отказ, обрыв, двойное нажатие и возврат.
ТЕХНОЛОГИЧЕСКИЙ КОНТУР
Из чего складывается надёжность
Форма банкаРеквизиты карты вводятся на стороне банка и не попадают на ваш серверПодпись запросовСумма и параметры защищены подписью — их нельзя изменить в браузереКлючи идемпотентностиПовтор запроса возвращает прежний результат вместо новой операцииОчередь уведомленийУведомления шлюза обрабатываются по одному и переживают перезапуск сервераФоновая проверкаОперации без окончательного статуса допрашиваются, пока не разрешатсяОтчёт сверкиЕжедневное сопоставление с выпиской и список несовпадений
Договор эквайринга и тарифы — между вами и банком. Мы отвечаем за то, чтобы деньги и заказы сходились, а спорная ситуация разбиралась по журналу, а не по памяти.
ВОПРОСЫ
Что обычно спрашивают
Клиента списали дважды. Как такое возможно?
Чаще всего из-за отсутствия ключа идемпотентности: пользователь нажал кнопку дважды или браузер повторил запрос после обрыва, и создались две операции. Правильное решение — не прятать кнопку на секунду, а сделать так, чтобы повтор с тем же ключом возвращал прежнюю операцию.
Что делать с «зависшими» платежами?
Они возникают, когда шлюз не ответил вовремя, а результат уже известен на его стороне. Мы помечаем такие операции как неопределённые и периодически запрашиваем их статус, пока он не станет окончательным. Без этого механизма деньги списаны, а заказ не оплачен — и разбирается это вручную.
Нужно ли хранить данные карт, чтобы делать повторные списания?
Нет. Для повторных платежей банк выдаёт токен, привязанный к карте: он хранится у вас вместо реквизитов и работает только для ваших операций. Сами номера карт при этом на вашем сервере не появляются, а требования по их хранению вас не касаются.
Как понять, что доля отказов выросла?
По журналу операций и наблюдению за ним. Каждая попытка сохраняется вместе с кодом ответа банка, поэтому видно не только «стало меньше оплат», но и почему: недостаточно средств, отклонение по лимиту, неудачное подтверждение. Это разные проблемы с разными решениями.
Можно подключить несколько способов оплаты сразу?
Да, и это обычная ситуация: карта, перевод по счёту и оплата при получении живут вместе. Важно, чтобы у каждого способа была своя цепочка статусов: наложенный платёж подтверждается отчётом курьерской службы, а не банковской выпиской, иначе сверка перестанет сходиться.