Идемпотентный workflow-движок для финансовых операций: AML, DEX-свопы и fail-closed по умолчанию
Вывод средств, обмен токенов, крупный депозит редко сводятся к одному действию «списать/зачислить». Если каждый сценарий писать if/else в контроллере, система быстро становится непредсказуемой.
По пути обычно нужно посчитать комиссию, проверить сумму, при необходимости прогнать операцию через AML-скрининг — и только потом исполнить её на блокчейне. Решение, применённое в TON-микросервисе, — конфигурируемый workflow-движок, через который проходит любая финансовая операция.
Операция = набор шагов, а не набор костылей
Для каждого типа операции (вывод, депозит, DEX-своп) в системе описан упорядоченный список шагов. Каждый шаг регистрируется под своим ключом-обработчиком, и добавление нового правила для конкретной валюты — это конфигурация, а не переписывание логики с нуля. Движок сохраняет промежуточный результат каждого шага в БД и продолжает с того места, где остановился, если процесс был прерван рестартом воркера или сбоем сети. Уже завершённые шаги повторно не выполняются.
Идемпотентность на входе, блокировка на исполнении
Запуск workflow защищён уникальным ключом идемпотентности — повторная инициация (например, из-за ретрая очереди) вернёт уже существующий процесс, а не создаст дубликат. Обработка конкретного запуска берёт распределённую блокировку на время выполнения, чтобы два воркера не начали одновременно двигать один и тот же workflow вперёд.
AML: fail-closed, а не fail-open
Если внешний AML-провайдер недоступен, вернул ошибку или не успел ответить — результат скрининга помечается как unavailable, и это осознанно не приравнивается к «проверка пройдена». Операция не может молча проскочить дальше только потому, что внешний сервис в моменте не работал: при отказе внешней системы безопасности процесс блокируется, а не продолжается в обход проверки. Для проекта с любым регуляторным контекстом это необходимое условие, а не опция.
Здесь же — идемпотентность самого запроса к провайдеру: повторный запуск проверки переиспользует уже сохранённый результат вместо повторного (часто платного) обращения, а параллельные попытки для одного субъекта синхронизируются блокировкой.
DEX-свопы: тот же принцип, только с блокчейном на другом конце
Котировка запрашивается отдельно и не исполняется автоматически, само исполнение свопа — отложенная, подтверждаемая операция, а не синхронный вызов «отправили — надеемся, получилось». Подтверждение выполняется отдельным шагом, который можно безопасно повторить, если ответ сети не пришёл вовремя.
Итог: движок окупается не в день запуска, а через полгода эксплуатации, когда появляется пятый тип операции, второй AML-провайдер или шаг проверки только для одной валюты. Вместо рефакторинга контроллеров — новая строка конфигурации.
Обсудить задачу
Если у вас есть проект, связанный с Laravel, CRM, Telegram, AI/RAG, API-интеграциями, автоматизацией или TON/GRAM-логикой — напишите в свободной форме, что нужно сделать.
Можно описать задачу коротко: что есть сейчас, что не работает, какой результат нужен и какие сервисы уже используются.
