Endpoint (API v2): Рублёвый платёж T-Bank под заказ

ℹ️ EasyPay API v2. Это ручка второго поколения EasyPay API (база https://api.appsign.me), пришедшего на смену legacy-API v1 (https://n8n.thenextgen.store/webhook/*). Отличия v2 от v1: авторизация заголовком X-Partner-Api-Key, плоское тело запроса, идемпотентность через опциональный client_token (полный ключ собирает сервер), коды ошибок — в UPPER_CASE.

Зачем это нужно

Принять оплату в рублях под конкретный заказ: покупатель нажал «купить» у вас на сайте — вы создаёте платёж на нужную сумму, получаете ссылку и ведёте по ней человека.

Это второй из двух способов принимать рубли, и они решают разные задачи:

Способ

Когда подходит

Публичная ссылка pay.appload.tech/<slug>

Одна постоянная ссылка с фиксированной суммой и одним названием товара — для лендинга, поста, закреплённого сообщения. См. Checkout: Публичная T-Bank ссылка

Эта ручка

У вас каталог и заказы: на каждую покупку своя сумма, свой номер заказа и название именно того товара, который покупают

Ручка возвращает две ссылки: payment_url — страница оплаты, где покупатель платит картой или выбирает СБП, и sbp_url — прямая ссылка СБП, которая открывается сразу в приложении банка.

По возможности давайте покупателю **sbp_url**. Эквайринг по СБП стоит заметно дешевле карточного, а покупатель пропускает форму ввода карты. Поле best-effort: если QR по какой-то причине не выпустился, придёт null — тогда ведите на payment_url.

⚠️ Название товара в чеке и на странице банка задать нельзя. Туда всегда идёт название из каталога — то, которое прошло модерацию. Кассовый чек по рублёвым платежам выдаёт юридическое лицо EasyPay, поэтому наименование в нём должно быть строкой, за которую отвечаем мы. Нужна другая формулировка — заведите товар через create_partner_ruble_payable_product и проведите через модерацию. Поле description в запросе не принимается: вернётся INVALID_INPUT.

Как подключиться

  1. Запросите API-ключ у вашего менеджера EasyPay (или скопируйте в мини-аппе, «Show key» на первом шаге онбординга).

  2. Менеджер активирует разрешение tbank_payment для вашего аккаунта.

  3. Заведите хотя бы один рублёвый товар через create_partner_ruble_payable_product и дождитесь одобрения. Пока одобренного товара нет, платить не за что: ручка принимает product_id, а не произвольную сумму.

Список готовых товаров и постоянных ссылок — list_partner_ruble_checkouts.

Endpoint

POST https://api.appsign.me/create-partner-tbank-payment
Content-Type: application/json
X-Partner-Api-Key: ваш-api-ключ

Формат запроса

{
  "product_id": 87,
  "customer_email": "client@example.com",
  "customer_phone": "+79991234567",
  "unit_amount_override": 149000,
  "external_order_id": "order-2417",
  "success_url": "https://example.com/thanks",
  "fail_url": "https://example.com/payment-failed",
  "client_token": "order-2417"
}

Параметры:

Параметр

Обязательный

Описание

product_id

Да

Числовой идентификатор одобренного рублёвого товара. Берётся из list_partner_ruble_checkouts или list_partner_invoiceable_products.

customer_email

Один из двух

Email покупателя.

customer_phone

Один из двух

Телефон покупателя, лучше в формате +79991234567.

unit_amount_override

Нет

Сумма в копейках (целое положительное число), если она отличается от цены товара в каталоге: 1 490 ₽ → 149000. Единицы те же, что у unit_amount в list_partner_invoiceable_products. Передадите рубли — платёж выйдет в 100 раз дешевле (1490 = 14,90 ₽); итоговую сумму в рублях показывает поле amount_rub ответа. Не больше 1000000000 (10 000 000 ₽). Не передали — берётся цена товара.

external_order_id

Нет

Ваш номер заказа — аналог client_reference_id у Stripe. Буквы, цифры, _ и -, до 64 символов; значение вне этого набора отклоняется, а не обрезается. Вернётся к вам в вебхуке и попадёт в уведомление в чат. Сам по себе ключом идемпотентности не является, но входит в отпечаток запроса: повторная отправка того же заказа с тем же содержимым вернёт тот же платёж — это защита от дубля при ретрае. Нужен второй платёж по тому же заказу — передайте другой client_token.

success_url

Нет

Куда вернуть покупателя после успешной оплаты. Только https://.

fail_url

Нет

Куда вернуть покупателя после неудачной оплаты. Только https://.

environment

Нет

live (по умолчанию) или test.

client_token

Нет

Ваш идемпотентный токен. Не передали — сервер дедупит по содержимому запроса.

Как минимум один из customer_email / customer_phone обязателен: без адреса или телефона некуда отправить кассовый чек.

description в запросе не принимается — см. предупреждение выше.

Формат ответа

Успешный ответ (200)

{
  "success": true,
  "payment_id": 9200408148,
  "payment_url": "https://<страница оплаты банка>",
  "sbp_url": "https://<ссылка СБП>",
  "order_id": "6d56065e-39f7-467d-b98c-ed233c65ebc5",
  "amount_rub": 1490,
  "status": "NEW",
  "duplicate": false
}

Поле

Описание

payment_url

Страница оплаты: карта или выбор СБП.

sbp_url

Прямая ссылка СБП для приложения банка. null, если QR не выпустился — используйте payment_url.

payment_id

Идентификатор платежа на стороне банка.

order_id

Наш внутренний идентификатор платёжной сессии. Для сопоставления с вашим заказом используйте не его, а external_order_id.

amount_rub

Сумма платежа в рублях.

status

Статус платежа на момент создания (обычно NEW).

duplicate

true, если это повтор ранее созданного платежа с тем же содержимым.

Ошибки

Все ошибки возвращаются с HTTP 200 + полем success: false и error_code. Проверяйте success, а не HTTP-статус.

error_code

Когда срабатывает

INVALID_INPUT

Передан description; не передан ни email, ни телефон; сумма меньше 1 ₽; success_url / fail_url не https://; external_order_id длиннее 64 символов или с недопустимыми символами.

PRODUCT_NOT_FOUND

Товара с таким product_id у вас нет, он не рублёвый, ещё не прошёл модерацию или был отклонён.

PERMISSION_DENIED

У ключа нет разрешения tbank_payment. Запросите его у менеджера EasyPay.

AUTH_REQUIRED / INVALID_API_KEY

Не передан или невалиден API-ключ.

OPERATION_IN_PROGRESS

Такой же запрос ещё выполняется. Дождитесь ответа, не повторяйте с новым ключом.

IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PAYLOAD

Тот же client_token пришёл с другим содержимым запроса.

INTEGRATION_UPSTREAM_ERROR / INTEGRATION_TIMEOUT

Банк не ответил или ответил ошибкой. Можно повторить.

INTERNAL_ERROR

Внутренний сбой EasyPay. Команда заботы уведомлена.

Как узнать, что заказ оплачен

Подтверждение оплаты приходит вебхуком TBank.payment.succeeded на ваш зарегистрированный адрес — тем же способом и с той же подписью, что и события Stripe. Отдельной регистрации и отдельного секрета для рублей не нужно, но событие подключается адресно: если рублёвых уведомлений на вашем адресе ещё нет, попросите менеджера их включить.

Структура тела и разбор полей — Webhook EasyPay: структура данных платежей T-Bank.

Главное при сопоставлении: заказ ищите по Payment.Data.ep_order — это то, что вы передали в external_order_id. Поле Payment.OrderId — наш внутренний идентификатор, для поиска вашего заказа он не годится.

Две вещи, которые стоит заложить сразу:

  • Отказ в оплате события не порождает. Если покупатель не смог заплатить, вебхука не будет — заказ так и останется у вас в ожидании. Ставьте собственный таймаут и считайте оплату состоявшейся только по пришедшему TBank.payment.succeeded.

  • Возврат тоже не приходит вебхуком — о нём вы узнаете из уведомления в чате, и отметить его у себя придётся вручную.

Пример на Python

import uuid, requests

resp = requests.post(
    "https://api.appsign.me/create-partner-tbank-payment",
    headers={"X-Partner-Api-Key": API_KEY},
    json={
        "product_id": 87,
        "customer_email": "client@example.com",
        "unit_amount_override": 149000,
        "external_order_id": f"order-{order_number}",
        "success_url": "https://example.com/thanks",
        "client_token": str(uuid.uuid4()),
    },
    timeout=30,
)
data = resp.json()

if not data.get("success"):
    raise RuntimeError(f"{data['error_code']}: {data.get('error_message')}")

# Ведём покупателя в приложение банка, если СБП доступен
checkout_link = data["sbp_url"] or data["payment_url"]

Через MCP

Если вы работаете с EasyPay из чата с AI-агентом, эта же ручка доступна как инструмент create_partner_tbank_payment — см. MCP-сервер EasyPay.