Skip to content

Интеграция: эквайринг Т-Банка через mock (10 минут) ​

Мок воспроизводит контракт EACQ/Мультирасчеты по официальной документации (https://developer.tbank.ru/eacq): Init → платёжная форма → нотификации → Confirm/Cancel, плюс верификация счетов (AV) и e2c-выплаты.

1. Поднять стенд ​

bash
docker compose up tbank-mock     # http://localhost:3100
# или без docker: npm run start:tbank

Мерчантская часть (ваша интеграция) должна принимать вебхуки. Для локальной проверки укажите в Init NotificationURL=http://host.docker.internal:PORT/webhook или задайте MOCK_DEFAULT_NOTIFICATION_URL на стенде.

2. Базовый флоу ​

bash
# Init: создать платёжную сессию
curl -s http://localhost:3100/v2/Init -H 'Content-Type: application/json' -d '{
  "TerminalKey": "TBANKMOCKTEST", "OrderId": "order-1", "Amount": 100000,
  "CreateDealWithType": "NN", "NotificationURL": "http://host.docker.internal:8080/webhook",
  "SuccessURL": "https://myapp.test/success/{order_id}", "FailURL": "https://myapp.test/fail/{order_id}"
}'
# → { PaymentURL, PaymentId, Status: "NEW" }

Откройте PaymentURL в браузере: на форме — тестовые карты со сценариями (успех/3DS-challenge/недостаточно средств/отказ). Коды 3DS: 1qwezxc.

  1. Подпись. Каждый API-запрос подписывается Token = sha256 по алгоритму «значения top-level скаляров (без Token, null, пустых) + Password, отсортированные по ключу, boolean в нижнем регистре» — конспект с примерами: документации Т-Банка. Нотификации от мока подписаны так же; мерчант обязан проверять (мок умеет слать дубли — кнопка в /admin, для проверки идемпотентности).

3. Профили ​

MOCK_PROFILE=plain (по умолчанию) — классический эквайринг без сделок: мультирасчётные поля (DealId/CreateDealWithType/PaymentRecipientId) игнорируются как незнакомые банку. MOCK_PROFILE=multisplit — профиль со сделками (Мультирасчеты): платёж с PaymentRecipientId требует DealId или CreateDealWithType=NN.

4. Что мок проверяет за вас (важно для отладки) ​

Мок ведёт себя как банк там, где ошибка интегратора была бы незаметна локально:

ПроверкаОтвет мока
Token короткий/битый (не 64 hex)ErrorCode 13, а не «внутренняя ошибка»
Чужой TerminalKeyErrorCode 7 с названием ожидаемого терминала
Повторный Init с тем же OrderIdErrorCode 7 (в бою OrderId уникален); отключается MOCK_ALLOW_DUPLICATE_ORDER_ID=true
Cancel с Amount больше доступной суммыErrorCode 7 + OriginalAmount (раньше выполнялся полный возврат!)
Confirm не из AUTHORIZEDErrorCode 32 (операция недоступна в статусе)
GetState без PaymentIdпринимается OrderId; при нескольких платежах — ErrorCode 7 со списком PaymentId

Журнал запросов: GET /admin/journal (JSON) и таблица в /admin — видно метод, путь, ключевые поля, код ответа и время обработки: «что мок понял в моём запросе».

5. Сценарии и консоль ​

/admin — платежи со историей статусов, сделки (баланс), поступления AV, верификации, нотификации (статус доставки, ретраи, кнопка «повторить»), кнопки сценариев: «банк подтвердил холд», «отмена платформой», «чарджбэк эмитента».

6. Ошибки (DX) ​

Ошибка — не голый код: Details содержит Field (какое поле), Hint (рекомендация) и Doc (раздел официальной документации). Известные коды: 7 (невалидные параметры), 8 (не найдено), 13 (подпись), 32 (недоступно в статусе), 501 (метод не реализован в моке).

7. Чеклист готовности к бою ​

  • [ ] все нотификации проверяют Token, ответ 200 «OK» ровно на подтверждённые
  • [ ] дубли и ретраи нотификаций обрабатываются идемпотентно (кнопка «повторить»/«дубль»)
  • [ ] переходы Confirm/Cancel только из допустимых статусов (см. историю в /admin)
  • [ ] чарджбэк-сценарий доводит вашу логику до корректного финала
  • [ ] повторный Init с тем же OrderId (ретрай сети) не создаёт второй платёж
  • [ ] Cancel не превышает доступную сумму и повторяется идемпотентно (ExternalRequestId)
  • [ ] рестарт стенда с MOCK_STATE_FILE не теряет необработанные нотификации (недоставленные догоняются после подъёма)
  • [ ] смена TBANK_API_URL на боевой хост + реальные TerminalKey/Password — код интеграции не меняется

8. Ссылки ​