Для 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 |
| Прочитать платежи через REST | pull:payments |
| Прочитать заказ через REST | pull:orders |
| Настроить RU-профиль бизнеса через onboarding | onboarding: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 — публичный номер заказа внутри бизнеса. Номер берите из результата продажи или чтения заказа, а не из адреса таблицы базы данных.
Вызовите
prepare_send_invoice. Подготовка не отправляет сообщения.Прочитайте её
payload,preparation_id,payload_hashиexpires_at. Покажите человеку: кому будет отправлен счёт, по какому заказу и на каких условиях. Спросите: «Отправить этому покупателю счёт по этому заказу?»После явного подтверждения вызовите
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; не ожидайте раскрытия внутренних причин. Сверьте уже выполненное действие, сценарий и подключение перед повтором. Дополнительная диагностика: ошибки, каталог и продажи.