Архитектура платёжных шлюзов и финансовых сервисов

Почему платёжный шлюз — самая дорогая часть продукта
Платёжный шлюз — это не просто «провести оплату». Это точка, где одновременно сходятся деньги, безопасность, внешние интеграции и пиковая нагрузка. Именно здесь чаще всего происходят самые дорогие ошибки: задвоенные списания, «зависшие» платежи без статуса, расхождения между тем, что показал клиент, и тем, что реально прошло в банке. Любая из этих ситуаций бьёт не только по выручке, но и по доверию — а доверие в финансовых сервисах восстанавливается куда дольше, чем правится баг.
Большинство систем начинают с простой логики: принять платёж, показать «успешно», записать заказ как оплаченный. На старте этого хватает. Проблемы начинаются, когда подключается второй провайдер, появляются возвраты, рассрочки, подписки, а нагрузка вырастает с десятков транзакций в день до тысяч в час. Архитектура, заложенная «на вырост», стоит дешевле, чем переписывание боевой платёжной системы под нагрузкой и под штрафы.
Базовые принципы, без которых нельзя начинать
Перед тем как выбирать конкретные технологии и провайдеров, важно зафиксировать несколько архитектурных принципов. Они кажутся очевидными, но именно их игнорирование становится причиной 90% инцидентов в платёжных системах.
- Идемпотентность. Любой запрос на оплату должен сопровождаться уникальным ключом. Если клиент дважды нажал «оплатить», сеть оборвалась и запрос повторился, или провайдер прислал вебхук трижды — система обязана понять, что это одна и та же операция, и не списать деньги повторно.
- Единый источник правды о статусе. Статус платежа определяет не фронтенд и не редирект пользователя, а подтверждение от провайдера (вебхук) и сверка по API. Пользователь может закрыть вкладку в момент успешной оплаты — деньги при этом уже ушли.
- Разделение денег и бизнес-логики. Платёжный модуль должен отвечать только за движение денег и их статусы. Начисление бонусов, активация подписки, отгрузка товара — это отдельный слой, который реагирует на подтверждённое событие оплаты.
- Полный аудит. Каждое изменение статуса, каждый входящий вебхук, каждый ответ банка должны логироваться неизменяемо. В споре с клиентом или банком выигрывает тот, у кого есть журнал.
Частая ошибка: считать платёж успешным по факту редиректа пользователя обратно в приложение. Редирект может не произойти (потеря сети, закрытая вкладка), а может быть подделан. Деньги списались, а заказ не оплачен — или наоборот, заказ оплачен дважды. Статус всегда подтверждается серверным вебхуком и контрольной сверкой по API провайдера, а не возвратом браузера.
Слои правильной архитектуры платёжного шлюза
Зрелый платёжный шлюз — это не один сервис, а несколько чётко разделённых слоёв. Такое разделение позволяет менять провайдеров, добавлять методы оплаты и масштабировать нагрузку, не трогая ядро.
- Слой приёма (API оплаты). Принимает запросы от клиентских приложений, создаёт платёжную сессию, генерирует идемпотентный ключ и заказ во внутреннем формате, не зависящем от конкретного провайдера.
- Слой адаптеров провайдеров. Для каждого платёжного оператора — Click, Payme, Uzum, банковский эквайринг, международные карты — отдельный адаптер с единым внутренним интерфейсом. Это позволяет подключать и отключать провайдеров без переписывания ядра.
- Слой состояний (state machine). Платёж проходит по строго описанному конечному автомату: создан → ожидает → авторизован → подтверждён → возвращён / отменён / истёк. Никаких «свободных» переходов между статусами быть не должно.
- Слой обработки событий. Вебхуки и колбэки складываются в очередь, обрабатываются асинхронно, с повторными попытками и защитой от дублей. Бизнес-события (активация, отгрузка) триггерятся только отсюда.
- Слой сверки и отчётности. Регулярная автоматическая сверка внутренних статусов с реестрами провайдеров и банка. Любое расхождение — повод для алерта, а не для ручного поиска раз в месяц.
Важный выбор: одно ядро на несколько провайдеров. Не привязывайте бизнес-логику к API конкретного оператора. Внутренний контракт «создать платёж / получить статус / сделать возврат» должен быть единым, а различия провайдеров спрятаны в адаптерах. Это окупается при первой же смене или добавлении банка-эквайера и при выходе на новые рынки.
Безопасность и соответствие требованиям
Финансовые сервисы живут в зоне жёстких требований. В Узбекистане это нормы Центрального банка по работе с платёжными операторами и хранению данных, а при работе с международными картами — стандарт PCI DSS. Базовое правило, которое снимает большую часть рисков: не хранить данные карт у себя. Полные номера карт, CVV и срок действия должны передаваться напрямую в инфраструктуру сертифицированного провайдера (через токенизацию или платёжную форму оператора), а у вас остаётся только токен.
Помимо этого, обязательны: проверка подписи входящих вебхуков (иначе любой может прислать вам «успешную оплату»), ограничение доступа к платёжным эндпоинтам, шифрование чувствительных полей в базе, разграничение прав и неизменяемый аудит-лог. Отдельное внимание — локализации данных: для многих систем в госсекторе и финансах персональные и платёжные данные граждан должны храниться на серверах внутри страны.
Хранить данные карт у себя или нет. Своё хранение карт даёт гибкость (рекуррентные платежи, единый кошелёк), но требует полной сертификации PCI DSS, регулярного аудита и берёт на вас всю ответственность за утечку. Токенизация через провайдера снимает почти всю нагрузку по сертификации и риски утечки, но привязывает к возможностям оператора. Для большинства бизнесов в Узбекистане второй путь дешевле и безопаснее; своё хранение оправдано лишь у крупных финтех-платформ с собственной командой безопасности.
Нагрузка, отказоустойчивость и деньги под пиком
Платёжный трафик неравномерен: распродажи, выплаты зарплат, дедлайны по оплате услуг создают пики в десятки раз выше среднего. Здесь критично, чтобы при отказе одного компонента деньги не «терялись» и не «задваивались». Помогают несколько приёмов: асинхронная обработка вебхуков через очередь (платёж не должен зависеть от того, успел ли отработать ваш бизнес-процесс), таймауты и ретраи с экспоненциальной задержкой при обращении к провайдеру, а также механизм компенсаций — если деньги списались, но дальнейшая операция упала, система должна уметь инициировать автоматический возврат.
Отдельный класс проблем — «зависшие» платежи в промежуточном статусе. Их источник всегда один: где-то прервалась цепочка подтверждения. Лечится это не ручным разбором, а фоновым процессом сверки, который раз в N минут опрашивает провайдера по всем незавершённым операциям и доводит их статус до финального.
Частая ошибка: обрабатывать вебхук синхронно и завязывать на него тяжёлую бизнес-логику. Если активация подписки или запись в десяток таблиц упадёт по таймауту, провайдер посчитает доставку вебхука неудачной и пришлёт его снова — а ваша логика выполнится дважды. Правильно: быстро принять вебхук, проверить подпись, положить в очередь, ответить 200, а всё остальное делать асинхронно и идемпотентно.
Типичные ошибки, которые дорого обходятся
- Определение статуса оплаты по фронтенду или редиректу вместо серверного подтверждения.
- Отсутствие идемпотентности — задвоенные списания при ретраях и повторных вебхуках.
- Жёсткая привязка к одному провайдеру без слоя адаптеров — переезд превращается в переписывание.
- Нет автоматической сверки с банком — расхождения всплывают спустя недели, когда деньги уже не вернуть.
- Хранение полных данных карт без сертификации — юридический и репутационный риск.
- Логика возвратов и частичных возвратов прикручена «потом» — а это половина споров с клиентами.
- Нет неизменяемого аудита — в конфликте с банком или клиентом нечем доказать свою правоту.
Вывод
Платёжный шлюз — это место, где архитектурная дисциплина важнее, чем где-либо ещё. Идемпотентность, единый источник правды о статусе, слой адаптеров под провайдеров, асинхронная обработка событий и регулярная сверка с банком — это не «избыточность», а минимальный набор, который отличает систему, спокойно проходящую распродажу и аудит, от той, что теряет деньги и доверие на первом же пике. Если вы запускаете финансовый сервис, маркетплейс или госуслугу с оплатой в Узбекистане и хотите заложить платёжное ядро правильно с первого раза — или привести в порядок уже работающую систему — обсудите проект с командой OneDev. Мы поможем спроектировать архитектуру под ваши провайдеры, нагрузку и требования регулятора.
Сколько платёжных провайдеров стоит подключать сразу?
Нужно ли проходить сертификацию PCI DSS?
Как избежать задвоенных списаний?
Что делать с «зависшими» платежами в промежуточном статусе?
Можно ли встроить надёжный платёжный шлюз в уже работающий продукт?
Сколько времени занимает разработка платёжного ядра?
Нужна похожая система или хотите обсудить проект?
Опишите задачу — предложим архитектуру, технический подход и план работ. Часто для старта достаточно короткого звонка.
Обсудить проект