К содержанию
TelegaFirst

Для AI-агентов: markdown этой страницы — /docs/payments.mdиндекс документации — /llms.txt

Платежи и счета

Обновлено

В TelegaFirst покупатель получает предложение и счёт в ходе разговора с вашим бизнесом. Владелец управляет платёжной настройкой, а оператор работает в Telegram. Это руководство помогает проверить подключённые способы оплаты, согласовать отправку счёта и отдельно зафиксировать подтверждённый ручной расчёт.

Результаты этих действий различаются: сохранённые реквизиты означают настройку, delivery:"queued" — постановку отправки счёта в очередь, а запись платежа — факт расчёта. Проверка подключения провайдера не создаёт платёж и не подтверждает оплату заказа.

Доступ и подготовка

Пройдите авторизацию и убедитесь, что выбран нужный бизнес. В MCP проверьте get_active_bot и обновите tools/list; в REST сверяйте X-Client-Slug и X-Bot-Username. Все значения номеров и ответов ниже — учебные примеры, используйте объекты из собственного бизнеса.

Показанные REST-маршруты настройки, платежей и Sales принимают API credential через X-Api-Key либо Authorization: Bearer tgf_*. Произвольный JWT сессии покупателя не заменяет этот доступ. OAuth-подключение собственного агента через MCP использует свой действующий grant и согласованные права.

ДействиеПраво
Прочитать, настроить, включить или отключить платёжного провайдераpayments:config, доступ владельца
Подготовить/исполнить отправку счёта, ручную продажу, отметить ручную оплатуorders:write
Прочитать платежи через RESTpull:payments
Прочитать заказ через RESTpull:orders
Настроить RU-профиль бизнеса через onboardingonboarding:write

Собственный агент клиента работает в пределах выданных прав. Внутренние Qualifier, Manager и Coach советуют и передают денежное действие человеку; они не подтверждают оплату и не изменяют денежные условия. payments:config не даёт агенту произвольного доступа к другим бизнесам. Реальный API key, OAuth grant или M2M credential сохраняет свою настоящую принадлежность; фиктивное приложение для OAuth не создаётся.

Проверить настройки провайдеров

MCP: get_payment_config с {}. REST: GET /api/v1/tools/payments, право payments:config, успешный статус 200. Ответ не содержит секретов: доступны только отметки настройки, валюты и время изменения. Полный учебный пример:

{
  "updatedAt": "2026-09-30T12:34:56.000Z",
  "defaultCurrency": "EUR",
  "providers": [
    {
      "provider": "robokassa",
      "enabled": false,
      "hasCredentials": false,
      "currency": null
    },
    {
      "provider": "yookassa",
      "enabled": false,
      "hasCredentials": false,
      "currency": null
    },
    {
      "provider": "stars",
      "enabled": false,
      "hasCredentials": true,
      "currency": null
    },
    {
      "provider": "cryptobot",
      "enabled": false,
      "hasCredentials": false,
      "currency": null
    },
    {
      "provider": "stripe",
      "enabled": true,
      "hasCredentials": true,
      "currency": "USD"
    },
    {
      "provider": "paypal",
      "enabled": false,
      "hasCredentials": false,
      "currency": null
    },
    {
      "provider": "paddle",
      "enabled": false,
      "hasCredentials": false,
      "currency": null
    },
    {
      "provider": "tinkoff",
      "enabled": false,
      "hasCredentials": false,
      "currency": null
    },
    {
      "provider": "prodamus",
      "enabled": false,
      "hasCredentials": false,
      "currency": null
    }
  ]
}

hasCredentials:true сообщает о наличии необходимых реквизитов, а не об успешной оплате. enabled:false выключает способ оплаты. Доступность конкретного способа для покупки дополнительно зависит от цены, валюты, позиции и проверок провайдера. У Stars секретов нет, поэтому hasCredentials:true допустимо даже до включения.

Сохранить реквизиты и включить способ оплаты

Согласуйте с владельцем провайдера, валюту и режим. Получайте секреты через защищённый ввод своего клиента, храните их вне публичных промптов, переписки и документации. Для одного провайдера используется строгая форма credentials, различаемая по provider. Для Stripe нужны secret_key и webhook_secret, для YooKassa — shop_id и api_key; точную схему остальных провайдеров берите из описания configure_payment_credentials.

REST: POST /api/v1/tools/payments, право payments:config, обязательный Idempotency-Key. Следующий JavaScript-фрагмент показывает полное тело учебного Stripe-запроса, получая значения секретов из защищённого ввода. Он не содержит реальных ключей и сам ничего не отправляет:

const configureRequest = {
  credentials: {
    provider: "stripe",
    secret_key: stripeSecretKeyFromSecureInput,
    webhook_secret: stripeWebhookSecretFromSecureInput,
    currency: "EUR"
  },
  enabled: false,
  default_currency: "RUB"
};

enabled:false позволяет сохранить реквизиты без включения способа оплаты. Если enabled не передан, значение по умолчанию — true, и сервер выполняет проверку допуска к включению. Успешный REST-ответ 201 для показанного запроса:

{
  "provider": "stripe",
  "enabled": false,
  "hasCredentials": true,
  "currency": "EUR"
}

В MCP configure_payment_credentials принимает ту же форму запроса, но результат — onboarding envelope с tenant, active_slug, stage, status, next_action и body проверки провайдера. REST-ответ настройки выше не является этим MCP envelope. Покажите владельцу фактический next_action.say_to_user и результат проверки.

Для включения уже настроенного провайдера используйте enable_payment_provider или POST /api/v1/tools/payments/enable. Для Stars это единственный путь подключения: реквизиты для него не передаются. После подтверждения владельца REST-запрос с Idempotency-Key содержит:

{
  "provider": "stars"
}

Успех — 201:

{
  "provider": "stars",
  "enabled": true,
  "hasCredentials": true
}

Для отключения используйте disable_payment_provider или POST /api/v1/tools/payments/disable, также с Idempotency-Key. Учебный запрос и полный успешный ответ 201:

{
  "provider": "stripe"
}
{
  "provider": "stripe",
  "disabled": true
}

Отключение сохраняет реквизиты. Повторное включение использует их; считайте способ готовым только после проверки фактического ответа и условий продажи. Секретные значения ни чтение настройки, ни ответы записи не возвращают.

Проверить подключение и профиль бизнеса

Для проверки используйте probe_payment_provider с {"provider":"yookassa"} либо POST /api/v1/tools/onboarding/payment-provider/probe с тем же телом, правом payments:config и Idempotency-Key. REST возвращает 201 с полным onboarding envelope; его body содержит provider, alive, test_mode, webhook_url. При успешной проверке учебного YooKassa: alive:true, test_mode:false. При транспортном отказе: alive:false, test_mode:null; секреты и внутренняя ошибка провайдера не раскрываются. Это диагностический результат, а не HTTP-ошибка оплаты.

Для RU-профиля самозанятого используйте set_tax_profile либо POST /api/v1/tools/onboarding/tax-profile, право onboarding:write, Idempotency-Key, тело:

{
  "jurisdiction": "ru",
  "business_type": "self_employed"
}

В полном onboarding envelope результат body равен {"business_type":"self_employed","taxation_system":null}. Самозанятость — вид бизнеса; не передавайте её как систему налогообложения. Для ip и ooo схема требует taxation_system; возьмите разрешённое значение из актуального описания инструмента.

Данные профиля и фискальные условия продавца проверяются перед включением соответствующих провайдеров. Ответственность продавца принадлежит вашему бизнесу. Обе зоны .ru и .com предусмотрены при запуске: они разделяют юрисдикцию и платёжные требования. Язык документа и выбор канала покупателя не определяют автоматически валюту или налоговый профиль.

Платёжные провайдеры отправляют уведомления через единый вход Gateway: сервер определяет провайдера по подписи и заголовкам, проверяет подлинность и приводит уведомление к единому платёжному событию. Это вход для провайдеров; справочник Hub описывает операции, которые вызывает ваш агент. Для настройки кабинета провайдера копируйте фактический webhook_url из диагностики своей среды; не отправляйте собственный «успешный webhook» для отметки заказа оплаченным.

Отправить счёт после подтверждения

Сначала прочитайте заказ своего бизнеса и проверьте покупателя, позиции, сумму, валюту и доступные способы оплаты. order_seq_num — публичный номер заказа внутри бизнеса. Номер берите из результата продажи или чтения заказа, а не из адреса таблицы базы данных.

  1. Вызовите prepare_send_invoice. Подготовка не отправляет сообщения.

  2. Прочитайте её payload, preparation_id, payload_hash и expires_at. Покажите человеку: кому будет отправлен счёт, по какому заказу и на каких условиях. Спросите: «Отправить этому покупателю счёт по этому заказу?»

  3. После явного подтверждения вызовите execute_send_invoice с точными preparation_id и payload_hash из той же подготовки. Сервер заново проверяет возможность отправки перед исполнением.

MCP-подготовка учебного заказа:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "prepare_send_invoice",
    "arguments": {
      "order_seq_num": 45
    }
  }
}

Execute принимает только значения из просмотренного фактического ответа:

const executeInvoiceArguments = {
  preparation_id: reviewedInvoicePreparation.preparation_id,
  payload_hash: reviewedInvoicePreparation.payload_hash
};

Успешное тело результата execute_send_invoice:

{
  "orderSeqNum": 45,
  "delivery": "queued",
  "replayed": false
}

queued означает сохранённый план отправки. Оно не обещает, что покупатель уже получил сообщение, перешёл по ссылке или оплатил. Следите за состоянием заказа и платежей отдельно. Подготовка действует 15 минут и привязана к бизнесу, операции и конкретному подключению. При истечении или переключении бизнеса заново подготовьте и согласуйте сценарий; не создавайте payload_hash самостоятельно.

REST-интеграция показывает тот же сценарий человеку до своей денежной команды: POST /api/v1/sales/orders/45/invoice, право orders:write, Idempotency-Key: sales-invoice-001, строгое тело:

{}

Успех — 201 с {"orderSeqNum":45,"delivery":"queued","replayed":false}. REST не имеет отдельного выдуманного маршрута prepare. Заказ без реального покупателя отклоняется; подставить произвольного получателя в тело нельзя.

Зафиксировать реальный ручной расчёт

mark_paid не является продолжением подготовки счёта. Используйте его только после проверки человеком, что деньги получены, и явного согласия перевести заказ на ручной расчёт. Допустимые значения settlement_type: cash, bank_transfer, transfer. switch_to_manual обязательно равно true; заметка необязательна, после удаления пробелов имеет длину от 1 до 500 символов.

После подтверждения MCP-запрос выглядит так:

{
  "jsonrpc": "2.0",
  "id": 5,
  "method": "tools/call",
  "params": {
    "name": "mark_paid",
    "arguments": {
      "order_seq_num": 45,
      "settlement_type": "bank_transfer",
      "settlement_note": "Paid at desk",
      "switch_to_manual": true,
      "idempotency_key": "sales-settlement-001"
    }
  }
}

REST: POST /api/v1/sales/orders/45/mark-paid, право orders:write, Idempotency-Key: sales-settlement-001, тело:

{
  "settlement_type": "bank_transfer",
  "settlement_note": "Paid at desk",
  "switch_to_manual": true
}

Полное успешное тело, в REST статус 201:

{
  "orderSeqNum": 45,
  "paymentSeqNum": 68,
  "replayed": false
}

paymentSeqNum — номер новой записи платежа; он может быть null, если результат расчёта не создал новую запись. Проверьте фактический ответ. Не выполняйте эту команду по одной лишь фразе покупателя, по статусу queued или из внутреннего AI-диалога без проверки человеком.

Прочитать результат и безопасно повторить запрос

GET /api/v1/payments/9 с правом pull:payments возвращает платёж по его номеру. Полный учебный ответ 200 без расширенных связей:

{
  "seq_id": 9,
  "amount": "100.00",
  "currency": "RUB",
  "provider": "yookassa",
  "provider_payment_id": "provider-safe-9",
  "status": "succeeded",
  "created_at": "2026-09-30T10:00:00.000Z",
  "updated_at": "2026-09-30T10:00:00.000Z"
}

Для списка используйте GET /api/v1/payments?limit=2&status=succeeded. limit — 1–200, по умолчанию 50; meta.next_cursor непрозрачен, действует 15 минут и связан с бизнесом, ресурсом и фактическими фильтрами. Следующую страницу читайте с теми же фильтрами. user_seq_num и order_seq_num — номера связей в бизнесе; raw user_id и order_id не передаются. include=user,order добавляет разрешённые связанные представления; порядок списка остаётся по времени создания, параметр sort не обещает другого порядка. GET не требует idempotency key и не поддерживает здесь ETag/If-Match.

У REST-настройки провайдеров действует HTTP-квитанция на 24 часа: тот же ключ и тот же запрос возвращают сохранённый ответ; изменённый запрос под тем же ключом даёт 422 IDEMPOTENCY_KEY_MISMATCH, одновременный повтор — 409 CONFLICT. Денежные Sales-команды используют отдельную долговременную квитанцию на 30 дней: точный повтор возвращает тот же результат с replayed:true, изменение команды — 422 IDEMPOTENCY_KEY_MISMATCH, ещё исполняемая квитанция — 409 IDEMPOTENCY_KEY_IN_FLIGHT. Live права и принадлежность креденшла проверяются перед повтором.

Если ответ потерян, сохраните ключ, тело и контекст команды. Не отправляйте тот же расчёт с новым ключом, пока не выяснили исход. Для MCP execute используется полученная подготовка; после её потребления повтор может быть отклонён как недоступный. Не обходите отказ новой подготовкой без проверки уже созданного заказа или платежа. Идемпотентность и версии.

Ошибки и следующий шаг

ОперацияHTTP / кодДействие
REST: нет действующего креденшла401 INVALID_API_KEYПовторить вход, проверить отзыв доступа.
REST: недостаточно прав403 INSUFFICIENT_SCOPEПроверить конкретные права в описании доступа.
RU-провайдер: профиль не заполнен422 PAYMENT_TAX_PROFILE_MISSINGЗаполнить профиль бизнеса и повторить согласованное включение.
Включение без нужных реквизитов422 VALIDATION_ERRORСохранить реквизиты нужного провайдера; ответ не раскрывает секрет.
REST: строгая схема не принята400 VALIDATION_ERRORИсправить поля validation_errors.
REST: отсутствует обязательный ключ400 IDEMPOTENCY_KEY_REQUIREDДать команде стабильный ключ.
Sales: заказ или покупатель отсутствует404 NOT_FOUNDПроверить текущий бизнес и номера из своего списка.
Sales: не выполнены бизнес-условия422 INVALID_REQUESTПроверить получателя, платёжные условия и необходимость ручного расчёта.
Номер/фильтр платежа неверен400 INVALID_REQUEST, INVALID_FILTER или INVALID_CURSORИсправить номер, фильтр или заново начать список.
Данные требуют доступного тарифа403 PLAN_UPGRADE_REQUIREDПроверить тариф, пробный период и оплаченное окно.
Ресурсный лимит413 PAYLOAD_TOO_LARGE или 429 RATE_LIMIT_EXCEEDEDСократить запрос или ждать Retry-After.

REST-ошибка — Problem Details с code, status, instance, traceId и при наличии hint. Полный пример отсутствующего права для чтения настройки:

{
  "type": "https://telegafirst.ru/docs/errors#INSUFFICIENT_SCOPE",
  "title": "Forbidden",
  "status": 403,
  "instance": "/api/v1/tools/payments",
  "code": "INSUFFICIENT_SCOPE",
  "traceId": "0123456789abcdef0123456789abcdef",
  "detail": "Missing required scope(s): payments:config",
  "hint": {
    "reason": "The credential lacks a scope this operation requires.",
    "recovery": "Compare missing_scopes at GET /api/v1/me with this operation and use a key that includes them."
  }
}

Ключи и внутренний текст провайдера в публичный ответ не включаются. При MCP isError:true читайте текст ошибки инструмента. При PREPARED_SCENARIO_TENANT_CHANGED остановите исполнение и проверьте активный бизнес. Другие недоступные или несовпавшие подготовки могут дать безопасное сообщение внутренней ошибки с traceId; не ожидайте раскрытия внутренних причин. Сверьте уже выполненное действие, сценарий и подключение перед повтором. Дополнительная диагностика: ошибки, каталог и продажи.