Оптовые Telegram Stars и Telegram Premium через REST API. Модель — предоплата: вы пополняете закупочный баланс, с него списывается партнёрская цена каждого заказа, конечному клиенту продаёте по своей.
"13.50", а не 13.5. Валюта каждой суммы указана в поле
currency. Строка, а не число, — намеренно: суммы считаются десятичной арифметикой,
и перевод их во float исказил бы центы.POST /orders с обязательным idempotency_key.
В этот момент с баланса списывается партнёрская цена.Оплату конечного клиента вы принимаете сами, в своей системе. Ваша маржа — разница между вашей ценой и партнёрской.
Цена одинакова для всех партнёров. Уровней, порогов оборота и персональных скидок нет, торга тоже: одна цифра для каждого, кто подключился.
Цены номинированы в USDT, курс рубля в расчёте не участвует. Значение пересчитывается вслед за рынком, поэтому перед заказом его стоит перечитывать из каталога.
Актуальные цены — GET /products. Точная сумма заказа фиксируется в ответе на
POST /orders; поле price_per_star в каталоге — справочное (6 знаков),
перемножать его самостоятельно не нужно.
Баланс закупочный и предоплатный: расходуется только на заказы и выводу не подлежит. Валюта счёта — доллары США (USDT).
Как пополнить. В кабинете выберите сеть (TON, TRC-20 или BEP-20) и сумму — сервис назовёт точную сумму с копейками и адрес. Отправьте ровно её: у переводов TRC-20 и BEP-20 поля комментария не существует, поэтому платёж опознаётся по сумме. Зачисление автоматическое, обычно в течение минуты после подтверждения сети.
Активация. Первое пополнение — от $10.00. До него кабинет
закрыт, API-ключ выпустить нельзя, а запросы к API отклоняются с
403 partner_inactive.
Остаток — GET /me, поле balance. Если баланса не хватает, заказ
отклоняется сразу с 402 insufficient_balance: деньги не резервируются, заказ
не подвисает в ожидании.
База: https://pay.tgsuperstars.com/api/partner/v1. Аутентификация:
Authorization: Bearer pk_live_... (ключ выпускается в кабинете; опционально —
IP-whitelist на ключ). Машиночитаемая спека:
openapi.json.
Идемпотентность: тот же idempotency_key в POST /orders →
тот же заказ и ровно одно списание. Повтор запроса при таймауте безопасен — это основной способ
не потерять и не задвоить заказ.
curl -H "Authorization: Bearer $KEY" https://pay.tgsuperstars.com/api/partner/v1/me
{
"partner_id": 100200300,
"status": "active",
"balance": "42.50",
"currency": "USD",
"pricing": {"note": "актуальные цены — GET /products"},
"limits": {"api_rate_limit": {"per_minute": 120, "burst": 30},
"stars_max_per_order": 50000}
}
curl -H "Authorization: Bearer $KEY" https://pay.tgsuperstars.com/api/partner/v1/products
{
"currency": "USD",
"stars": {"price_per_1000": "15.15", "price_per_star": "0.015150",
"currency": "USD", "max_per_order": 50000},
"premium": {"3": {"partner_price": "12.11", "currency": "USD"},
"6": {"partner_price": "16.15", "currency": "USD"},
"12": {"partner_price": "29.28", "currency": "USD"}}
}
Если цена временно недоступна, вместо цен приходит
{"unavailable": true, "reason": "cost_unavailable"} — это не ошибка HTTP,
а честный признак «сейчас не продаём». Заказ в этот момент тоже не примется.
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"type":"stars","username":"@durov"}' https://pay.tgsuperstars.com/api/partner/v1/validate/recipient
Для premium проверка дополнительно сообщает, что у получателя уже есть подписка —
это избавляет от заказа, который завершится ошибкой already_premium.
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"type":"stars","idempotency_key":"ord-1","params":{"quantity":100,"recipient":"@durov"}}' https://pay.tgsuperstars.com/api/partner/v1/orders
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"type":"premium","idempotency_key":"ord-2","params":{"months":3,"recipient":"@durov"}}' https://pay.tgsuperstars.com/api/partner/v1/orders
Допустимые сроки Premium — 3, 6 и 12 месяцев. Других типов заказа нет:
type принимает только stars и premium.
{
"order_id": "PA-12345",
"type": "stars",
"status": "processing",
"partner_price": "1.53",
"currency": "USD",
"retail": null,
"quantity": 100,
"recipient": "@durov",
"created_at": "2026-08-10T18:20:31+03:00",
"refunded": false
}
partner_price — списанная с баланса сумма, строкой. У архивных заказов,
созданных до 10.08.2026, это число в рублях и currency: "RUB";
ориентируйтесь на currency, а не на тип значения.retail — всегда null: розничная цена сайта рублёвая,
в долларовом ответе ей не место. Явный null, а не ноль, чтобы никто
не прочитал его как «бесплатно».quantity — количество звёзд для stars и число месяцев
для premium.GET /orders/{id} и
GET /orders?status=&type=&from=&to=&cursor=&limit=.
Статусы: processing | completed | partial | canceled | failed. Исходящие вебхуки
(order.completed | order.failed | order.refunded) подписаны заголовком
X-Signature: hex(hmac_sha256(body, ваш webhook_secret)) — проверяйте подпись
и обрабатывайте идемпотентно (доставка «как минимум один раз»).
Формат зависит от того, где ошибка возникла. Ошибки обработки заказа приходят плоскими:
{"code": "insufficient_balance", "detail": "Не хватает баланса"}
Ошибки уровня запроса — аутентификация, лимит частоты, неизвестный тип,
отсутствующий idempotency_key — тот же объект, но вложенный в поле
detail:
{"detail": {"code": "bad_type", "detail": "type ∈ stars|premium"}}
Различие историческое и сохранено намеренно, чтобы не ломать существующих
клиентов. Надёжный разбор: взять detail, и если это объект — читать
code из него, иначе из корня.
| HTTP | code | Что значит |
|---|---|---|
| 401 | unauthorized | Нет или неверный Bearer-ключ |
| 403 | ip_not_allowed | IP не в whitelist ключа |
| 403 | partner_inactive | Кабинет не активирован — нужно первое пополнение от $10.00 |
| 429 | rate_limited | Превышен лимит запросов — снизьте частоту |
| 400 | idempotency_required | Не передан idempotency_key в POST /orders |
| 400 | bad_type | type не stars и не premium |
| 400 | bad_quantity / bad_months | Неверное количество звёзд или срок подписки |
| 400 | recipient_required / recipient_not_found | Получатель не указан или не найден |
| 400 | already_premium | У получателя уже есть Premium |
| 402 | insufficient_balance | Не хватает баланса — пополните счёт |
| 502 | resolver_error | Сбой резолва получателя — повторите позже |
| 503 | product_unavailable | Товар временно недоступен |
/validate/* — 30 в минуту.Что со Stars при сбое доставки? Ведём так же, как розницу: при недоступности сети доставки заказы копятся и досдаются после восстановления — деньги не теряются.
Повторил запрос из-за таймаута — спишется дважды? Нет, если вы передали тот же
idempotency_key: вернётся тот же заказ и списание останется одно.
Отправил сумму не до копейки — что будет? Платёж не опознается автоматически и попадёт в ручной разбор. Напишите в поддержку @tg_super_support_bot с хэшем транзакции.
Поддержка: @tg_super_support_bot — по вопросам интеграции и платежей. Своих конечных клиентов поддерживаете вы.