Интеграция Т-Банк → amoCRM для автоматической обработки оплат

Кейс · платёжная интеграция и CRM · 2026

Построили и проверили связку, в которой подтверждённый платёж из Т-Банка доходит до нужной сделки amoCRM, меняет только необходимые данные и остаётся безопасным при повторной доставке webhook.

2внешних API
10попыток job
25+ часовокно retry
28автотестов
93проверки

Задача

После оплаты менеджер не должен вручную искать заказ, сверять сумму и переносить сделку между этапами. Но автоматизация платежей требует осторожности: уведомления могут приходить повторно, поле заказа может появиться в CRM чуть позже webhook, а любые секреты должны оставаться за пределами логов и комментариев.

Нужно было связать NotificationURL Т-Банка с существующей воронкой amoCRM и обеспечить понятную последовательность: проверить подлинность события, принять только CONFIRMED, найти единственную сделку по ORDERID, записать фактический результат и гарантировать идемпотентность.

Путь подтверждённой оплаты

  1. Публичный webhook без пользовательской сессии

    HTTPS-маршрут принимает уведомление банка без авторизации пользователя и CSRF, но с ограничением размера тела запроса и rate limit.

    POST /webhooks/tbank/payment
  2. Проверка Token до обработки

    Подпись рассчитывается по официальному алгоритму: корневые значения уведомления и пароль терминала сортируются по ключу, объединяются и хешируются SHA-256. Сравнение выполняется безопасным способом.

    TBANK_PASSWORD · SHA-256 · hash_equals
  3. Фиксация PaymentId

    Уведомление сохраняется в локальную таблицу с уникальным PaymentId. Повторная доставка не создаёт новую запись и не запускает вторую обработку уже завершённого платежа.

    unique payment_id · queued / processed / failed
  4. Поиск сделки по ORDERID

    Сервис ищет во всей настроенной воронке, независимо от текущего этапа, а затем проверяет точное значение поля ORDERID и единственность результата на всех страницах ответа.

    amoCRM leads API · exact custom field match
  5. Обновление сделки

    Сделка переводится в «Оплачено», в бюджет записывается сумма платежа в рублях, а банковский идентификатор сохраняется в поле PAYMENTID.

    status_id · price · PAYMENTID
  6. Комментарий без дублей

    После успешного обновления добавляется структурированное примечание: PaymentId, OrderId, сумма, статус и время получения подтверждения. Перед POST сервис проверяет существующие заметки по PaymentId.

    common note · idempotent by PaymentId

Что получает менеджер в amoCRM

Подтверждённый статус

Обрабатывается только успешный CONFIRMED с корректным Token. Неподтверждённые статусы принимаются без изменения сделки.

Актуальная карточка

Этап «Оплачено», реальный бюджет, сохранённый PAYMENTID и понятный комментарий об оплате находятся в одной сделке.

Защита от гонки

Если сделка уже создана, но ORDERID ещё не успел появиться в поиске, очередь повторит операцию по растущему backoff в течение более 25 часов.

Идемпотентность на двух уровнях

  • Платёж — уникальный PaymentId не позволяет повторно поставить уже обработанное уведомление в очередь.
  • Комментарий — перед добавлением примечания проверяется, нет ли в сделке точной строки с тем же PaymentId.
  • Сделка — поиск требует единственного точного совпадения по ORDERID; неоднозначный результат не изменяется автоматически.
  • Сумма — минимальные денежные единицы преобразуются целочисленно, без float и скрытого округления.

Диагностика без изменения данных

Для проверки подключения добавлена отдельная artisan-команда php artisan amocrm:inspect. Она безопасными GET-запросами показывает воронки, этапы и пользовательские поля сделок, не выводя access token или Authorization header.

Во время аудита были подтверждены нужная воронка, этап «Оплачено», поля ORDERID и PAYMENTID, доступность аккаунта и история нескольких последних сделок. Production-сделки при проверке не изменялись.

Архитектура

Laravel
Webhook — проверка размера, TerminalKey и Token
Хранилище — MySQL, уникальный PaymentId
Очередь — отдельная очередь tbank, 10 попыток
amoCRM
Авторизация — долгосрочный access token
Связь — T-Bank OrderId → amoCRM ORDERID
Результат — этап, бюджет, PAYMENTID и примечание

Техническая точка OAuth-подключения проекта: https://test.ifreework.com/integrations/amocrm/callback. Она защищена пользовательской авторизацией и не используется как публичная страница.

Безопасность

  • пароль терминала, access token и Authorization header не попадают в вывод и логи;
  • полный webhook payload не копируется в комментарий amoCRM;
  • ссылка на транзакцию не придумывается — NotificationPayment не предоставляет подтверждённый публичный URL платежа;
  • webhook отвечает банку точным 200 OK, а дальнейшую синхронизацию выполняет очередь;
  • проверка интеграции выполнялась без тестовых платежей и финансовых операций.

Результат

Подтверждённая оплата больше не требует ручной сверки: Laravel проверяет событие банка, находит правильную сделку независимо от её текущего этапа, фиксирует сумму и PaymentId, переводит её в «Оплачено» и оставляет понятный комментарий.

Повторные уведомления безопасны, задержка появления ORDERID покрывается длительными retry, а состояние интеграции можно проверить отдельной диагностической командой без изменения CRM.

Laravel · T-Банк API · amoCRM API v4 · MySQL · Queue · Webhook · Idempotency