Endpoint (API v2): Корзина T-Bank — один рублёвый платёж на несколько товаров

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

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

Корзина — это один рублёвый платёж T-Bank за несколько ваших товаров, у каждого своё количество и, при желании, своя цена. Покупатель платит одну сумму, а в кассовом чеке каждая позиция идёт отдельной строкой: название, цена за единицу, количество, сумма строки.

Используйте, когда клиент покупает комбинацию, а не один товар:

  • тариф собирается из частей — «2 места в команде + 100 аккаунтов»;

  • заказ из нескольких товаров каталога, который нужно оплатить одним платежом;

  • AI-агент должен собрать такую ссылку по просьбе прямо в чате (через MCP — инструмент create_partner_tbank_cart_payment).

Для одного товара подходит и эта ручка, и Рублёвый платёж T-Bank под заказ.

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

Рекуррентных списаний в рублях нет: корзина — разовая оплата.

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

  1. API-ключ партнёра и разрешение tbank_payment — то же, что для рублёвого платежа на один товар.

  2. Все товары корзины — одобренные рублёвые товары вашего каталога. Их id видны в list_partner_invoiceable_products (currency=RUB) и list_partner_ruble_checkouts.

  3. Все товары одной корзины должны продаваться через один и тот же терминал (одна система налогообложения). Если товары на разных терминалах — разбейте корзину на отдельные платежи.

Endpoint

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

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

{
  "items": [
    { "product_id": 101, "quantity": 2 },
    { "product_id": 102, "quantity": 100, "unit_amount": 85000 }
  ],
  "customer_email": "client@example.com",
  "external_order_id": "order-2417",
  "success_url": "https://example.com/thanks",
  "client_token": "order-2417"
}

Параметр

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

Описание

items

Да

1..100 позиций. Каждый товар — не больше одной позиции: количество складывайте в quantity.

items[].product_id

Да

Числовой id одобренного рублёвого товара.

items[].quantity

Да

Количество, целое 1..9999.

items[].unit_amount

Нет

Цена одной единицы в копейках: 85000 = 850 ₽. Не передали — берётся цена товара из каталога.

customer_email

Один из двух

Email покупателя — туда придёт чек.

customer_phone

Один из двух

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

external_order_id

Нет

Ваш номер заказа: буквы, цифры, _ и -, до 64 символов. Вернётся в вебхуке (Payment.Data.ep_order) и в уведомлении в чат.

success_url / fail_url

Нет

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

environment

Нет

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

client_token

Нет

Ваш идемпотентный токен. См. «Повторы».

Сумму платежа не передают — сервер считает её сам: Σ (цена × количество) по всем позициям. Итог от 1 ₽ до 10 000 000 ₽.

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

HTTP-статус всегда 200 — смотрите поле success.

{
  "success": true,
  "payment_id": 9200408148,
  "payment_url": "https://<страница оплаты банка>",
  "sbp_url": "https://<ссылка СБП>",
  "order_id": "6d56065e39f7467db98ced23",
  "amount_rub": 93300,
  "amount_kopecks": 9330000,
  "status": "NEW",
  "line_item_count": 2,
  "items": [
    { "product_id": 101, "product_name": "<название из каталога>", "unit_amount": 415000, "quantity": 2, "amount": 830000 },
    { "product_id": 102, "product_name": "<название из каталога>", "unit_amount": 85000, "quantity": 100, "amount": 8500000 }
  ],
  "duplicate": false
}

По возможности давайте покупателю sbp_url — эквайринг по СБП дешевле карточного. Если придёт null, ведите на payment_url.

items — ровно те строки, что уйдут в кассовый чек (суммы в копейках). На странице банка покупатель видит общую сумму и название первой позиции с пометкой «и ещё N».

Повторы

  • Тот же запрос (тот же состав, цены, количества, покупатель, номер заказа) без client_token вернёт тот же платёж с duplicate: true — случайный повтор не создаёт второй.

  • Нужен отдельный платёж того же состава — передайте новый client_token.

  • Тот же client_token с другой корзиной вернёт IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PAYLOAD.

Ошибки

error_code

Что значит

INVALID_INPUT

Пустая корзина или больше 100 позиций; товар повторяется; количество или цена не целые; товары на разных терминалах; сумма вне 1 ₽ … 10 000 000 ₽; нет ни email, ни телефона; передан description; неверный external_order_id или не https:// адрес. Причина — в error_message.

PRODUCT_NOT_FOUND

Товара нет в вашем каталоге, он не рублёвый или ещё на модерации (причина — в error_message).

PERMISSION_DENIED

У ключа нет разрешения tbank_payment.

OPERATION_IN_PROGRESS

Такой же запрос ещё выполняется — дождитесь ответа.

INTEGRATION_UPSTREAM_ERROR / INTEGRATION_TIMEOUT

Банк не ответил или ответил ошибкой — повторите с новым client_token.

INTERNAL_ERROR

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

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

Так же, как у платежа на один товар: вебхук TBank.payment.succeeded на ваш зарегистрированный адрес — Webhook EasyPay: структура данных платежей T-Bank. У корзины в Payment.Data поле ep_product_id = null (товаров несколько); сопоставляйте оплату с заказом по ep_order.


T-Bank cart: one RUB payment for several products (EN)

A cart is one T-Bank RUB payment for several of your products, each with its own quantity and optionally its own price. The customer pays one total, and every item is a separate line of the fiscal receipt (name, unit price, quantity, line total). Via MCP the tool is create_partner_tbank_cart_payment.

Receipt line names are always the moderated catalogue names — description is rejected. One-time payment only.

Endpoint: POST https://api.appsign.me/create-partner-tbank-cart-payment, header X-Partner-Api-Key, permission tbank_payment. All products must be approved RUB products sold through the same terminal (same tax regime).

Request: items (1..100 of {product_id, quantity 1..9999, unit_amount?}unit_amount is the price of ONE unit in kopecks, 85000 = 850 RUB, omitted → catalogue price; one entry per product), customer_email or customer_phone (one is required), optional external_order_id, success_url, fail_url, environment, client_token. The total is computed by the server: Σ price × quantity, 1 … 10,000,000 RUB.

Response (HTTP 200, check success): payment_url, sbp_url (prefer it; null → use payment_url), payment_id, order_id, amount_rub, amount_kopecks, status, line_item_count, items[] exactly as they go to the receipt, duplicate.

Repeats: an identical request returns the same payment with duplicate: true; pass a new client_token for a separate payment with the same composition; the same token with a different cart → IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_PAYLOAD.

Errors: INVALID_INPUT, PRODUCT_NOT_FOUND, PERMISSION_DENIED, OPERATION_IN_PROGRESS, INTEGRATION_UPSTREAM_ERROR / INTEGRATION_TIMEOUT (retry with a new client_token), INTERNAL_ERROR.

Payment confirmation: the TBank.payment.succeeded webhook, same as for a single product; in a cart Payment.Data.ep_product_id is null — match the payment to your order by ep_order.