Интеграция банков, мерчантов и сервисов в одну платформу

Почему «набор подключений» рано или поздно перестаёт работать
Платёжная инфраструктура почти всегда начинается одинаково: компания подключает один банк для расчётного счёта, один платёжный провайдер для приёма онлайн-оплат и пару внешних сервисов — фискализацию, рассылку чеков, выгрузку в бухгалтерию. На старте это разумно: меньше кода, меньше согласований, быстрее запуск. Каждая интеграция живёт сама по себе, и пока сценарий один, никто не чувствует боли.
Проблемы начинаются не от роста объёма платежей, а от роста разнообразия. Появляется второй банк — потому что первый не поддерживает нужный вид расчётов или потому что часть оборота идёт через дочернее юрлицо. Добавляется второй и третий мерчант — для разных продуктов, регионов или валют. Подключаются Click, Payme, Uzum, карты UZCARD/HUMO, рассрочка, эквайринг. И вдруг выясняется, что каждая из этих интеграций сделана по-своему: свой формат запроса, своя логика подтверждения, свой способ узнать статус платежа, свои коды ошибок.
В этот момент система превращается в клубок частных случаев. Любое изменение — новый банк, новый способ оплаты, новое требование регулятора — требует править код в десятках мест и тестировать заново всё, что было раньше. Команда тратит время не на развитие, а на удержание хрупкой конструкции от падения.
Что на самом деле болит: не количество, а связность
Распространённое заблуждение — что главная сложность в количестве интеграций. На практике критична связность: насколько бизнес-логика приложения переплетена с деталями конкретного банка или провайдера. Если в коде оформления заказа напрямую вызывается API конкретного мерчанта и тут же разбирается его формат ответа, то этот мерчант «вшит» в ядро системы. Заменить его или добавить рядом второй — значит переписать ядро.
Типичные симптомы того, что связность вышла из-под контроля:
- Чтобы понять, оплачен ли заказ, разработчик должен помнить, через какой именно провайдер он шёл, — потому что у каждого свой способ проверки статуса.
- Один и тот же платёж в разных частях системы называется по-разному: где-то «транзакция», где-то «инвойс», где-то «заказ».
- Возвраты, частичные возвраты и сверки сделаны для одного провайдера и просто отсутствуют для остальных.
- Никто не может быстро ответить на вопрос «сколько денег прошло за вчера по всем каналам» — данные раскиданы по разным таблицам и кабинетам.
Всё это — следствие отсутствия единого слоя, который говорит с банками и мерчантами на одном внутреннем языке.
Архитектура единой платёжной платформы
Решение — не «подключить ещё аккуратнее», а ввести промежуточный слой абстракции между бизнес-логикой и внешними системами. Его часто называют платёжным шлюзом или payment-оркестратором. Суть в том, что приложение работает с одним универсальным интерфейсом («создай платёж», «проверь статус», «сделай возврат»), а уже внутри платформа решает, какой банк или провайдер использовать и как именно с ним общаться.
Хорошая платёжная платформа обычно состоит из нескольких чётко разделённых частей:
- Адаптеры (коннекторы) — по одному на каждый банк, мерчант или сервис. Адаптер знает все детали конкретного API: формат запросов, подписи, IP-whitelist, коды ошибок. Снаружи он отдаёт результат в едином формате платформы.
- Ядро (оркестратор) — единая модель платежа, статусы и переходы между ними, маршрутизация: какой платёж через какой канал отправить.
- Слой идемпотентности и журналирования — гарантия, что повторный запрос не создаст второй платёж, и полный неизменяемый лог всех операций.
- Сверка и отчётность — регулярное сопоставление того, что система считает оплаченным, с тем, что реально подтвердил банк.
Ключевой принцип: добавление нового банка должно сводиться к написанию одного нового адаптера, а не к правке ядра. Если для подключения провайдера приходится менять логику оформления заказа — абстракция спроектирована неверно.
Единая модель платежа и статусы
Сердце платформы — общая модель платежа, которая не зависит от провайдера. У платежа есть стабильный внутренний идентификатор, сумма, валюта, ссылка на заказ, выбранный канал и статус. Статусов должно быть немного и они должны быть однозначными: создан, ожидает оплаты, оплачен, отклонён, возвращён, ошибка. Все разнообразные коды банков адаптеры приводят к этому единому набору.
Отдельное внимание — переходам между статусами. Платёж не должен «прыгать» из оплаченного обратно в ожидание из-за запоздавшего ответа банка. Поэтому переходы делают однонаправленными и фиксируют каждый из них в журнале с указанием источника (ответ API, webhook, ручная операция, сверка). Это превращает платёж в прозрачную историю, по которой всегда можно восстановить, что и почему произошло.
Идемпотентность, webhook и повторы — где всё ломается
Самая частая причина инцидентов в платёжных системах — не отказ банка, а двойная обработка. Сеть ненадёжна: запрос мог дойти, но ответ потерялся; webhook о подтверждении может прийти дважды; пользователь нажал «оплатить» три раза. Если система не защищена, это превращается в двойные списания, задвоенные заказы и расхождения в сверке.
Защита строится на двух механизмах. Первый — ключ идемпотентности: каждая операция помечается уникальным ключом, и повторный запрос с тем же ключом возвращает прежний результат, а не создаёт новый платёж. Второй — обработка webhook как ненадёжного источника: подпись проверяется обязательно, событие сохраняется, но истинным состоянием считается то, что подтверждено прямым запросом статуса к банку.
Сверка и наблюдаемость — то, без чего нельзя в продакшн
Пока интеграций мало, расхождения замечают вручную. Когда их десятки, нужна автоматическая сверка: ежедневное сопоставление платежей в вашей системе с реестром каждого банка и мерчанта. Сверка ловит именно те ошибки, которые иначе всплывают через недели — «оплачено у нас, но не у банка», «возврат сделан дважды», «деньги пришли без привязки к заказу».
Рядом со сверкой работает наблюдаемость: единый дашборд с оборотом по всем каналам, доля отклонённых платежей по каждому провайдеру, время ответа банков, очередь застрявших платежей. Без этого вы узнаёте о проблеме от клиента, а не от системы. Хорошая платформа должна уметь ответить на простой вопрос «всё ли в порядке с деньгами прямо сейчас» без раскопок в логах.
Типичные ошибки при объединении интеграций
- «Большой выключатель» вместо абстракции. Логика вида «если банк А — сделай так, если банк Б — иначе» прямо в коде заказа. Это та же связность, только в одном файле. Нужны адаптеры, а не разветвления.
- Хранение секретов в коде и в URL. Ключи мерчантов, токены и пароли должны лежать в защищённом хранилище секретов, а не в репозитории и не в конфигах под git.
- Отсутствие тестового контура. Платёжную логику нельзя проверять на боевых деньгах. Нужны песочницы провайдеров и возможность прогонять сценарии оплаты, отказа, возврата и таймаута без риска.
- Игнорирование частичных и отложенных сценариев. Частичный возврат, доплата, рассрочка, отложенное подтверждение — их закладывают в модель сразу, иначе потом приходится ломать структуру данных.
- Отсутствие плана на отказ провайдера. Если основной канал недоступен, платформа должна уметь либо переключиться на резервный, либо корректно поставить платёж в очередь, а не терять заказ.
Вывод
Объединение банков, мерчантов и сервисов в одну платформу — это не про «подключить побольше», а про то, чтобы вынести все частности внешних систем в адаптеры и оставить в ядре единую, прозрачную модель платежа с идемпотентностью, журналом, сверкой и наблюдаемостью. Такой подход делает добавление нового банка предсказуемым и дешёвым, а деньги — управляемыми и проверяемыми. Если вы чувствуете, что текущие интеграции стали тормозить развитие и каждое изменение пугает — это сигнал, что пора переходить от набора подключений к платформе. Команда OneDev проектирует и строит такие платёжные платформы под реалии Узбекистана (Click, Payme, Uzum, UZCARD/HUMO, банковский эквайринг, фискализация) — расскажите о своём проекте, и мы поможем выстроить архитектуру, которая выдержит рост.
Чем платёжный оркестратор отличается от обычной интеграции с провайдером?
Сколько стоит и сколько занимает добавление нового банка в готовую платформу?
Зачем нужна автоматическая сверка, если платежи и так подтверждаются банком?
Можно ли постепенно перейти на единую платформу, не останавливая бизнес?
Как платформа ведёт себя, если банк или провайдер недоступен?
Подходит ли такой подход для госсектора и крупных организаций?
Нужна похожая система или хотите обсудить проект?
Опишите задачу — предложим архитектуру, технический подход и план работ. Часто для старта достаточно короткого звонка.
Обсудить проект