Заказы и статусы
Создание заказа, жизненный цикл, повторы и идемпотентность.
Order означает выдачу Stars или Premium одному получателю. Заказ принадлежит Project, который его создал.
Создание
Checks the recipient, holds the price on your balance and queues the Order (QUEUED).
Repeating with the same externalId returns the existing Order (with different parameters: 409, code -9207).
Stars: quantity 50 to 1,000,000; Premium: months 3, 6 or 12.
Authorization
apiKey ifk_<clientId>_<secret>, for example ifk_48aa52d67c0fef6decb05b36_lVlZSWKN43sgb2vfEpFbqtzQ0ePNZya6yZr-RmJ4wxo
In: header
Header Parameters
8 to 128 characters [A-Za-z0-9._:-], unique per operation
^[A-Za-z0-9._:-]{8,128}$Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/orders" \ -H "Idempotency-Key: string" \ -H "Content-Type: application/json" \ -d '{ "externalId": "bot-order-1024", "username": "durov", "product": "STARS", "quantity": 100 }'{ "success": true, "data": { "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "externalId": "bot-order-1024", "product": "STARS", "quantity": 100, "months": null, "username": "durov", "recipientName": "Pavel Durov", "status": "QUEUED", "price": "1.65", "currency": "USD", "failure": null, "createdAt": "2026-10-06T09:15:22.443Z", "sentAt": null, "completedAt": null }, "meta": { "requestId": "9f1c2b7e-3a4d-4e5f-8a6b-7c8d9e0f1a2b", "timestamp": "2026-10-06T09:15:22.481Z", "processingTimeMs": 38 }}POST /v1/orders
X-API-Key: ifk_…
Idempotency-Key: 5c0e1d7a-3b1f-4c1e-9d55-0f6b6a1b2c3d
Content-Type: application/json{ "product": "STARS", "quantity": 500, "username": "durov", "externalId": "1042" }| Поле | Тип | Описание |
|---|---|---|
product | STARS | PREMIUM | что выдать |
quantity | integer | для STARS: от 50 до 1 000 000 |
months | 3 | 6 | 12 | для PREMIUM вместо quantity |
username | string | получатель: durov, @durov или https://t.me/durov; от 4 до 32 символов [a-z0-9_], начинается с буквы |
externalId | string | id заказа в вашей системе (от 1 до 128 символов), уникален в рамках Project |
Ответ 201 содержит объект заказа:
{
"id": "0199a1b2-6f00-7abc-9def-112233445566",
"externalId": "1042",
"product": "STARS",
"quantity": 500,
"months": null,
"username": "durov",
"recipientName": "Pavel Durov",
"status": "QUEUED",
"price": "8.25",
"currency": "USD",
"failure": null,
"createdAt": "2026-09-26T10:15:30.000Z",
"sentAt": null,
"completedAt": null
}price это строка в долларах США. failure заполнен только у FAILED: { "code": "RECIPIENT_NOT_FOUND", "message": "Telegram user not found" }.
При создании мы:
- проверяем получателя (через кэш): если его нет, сразу отвечаем
422(-9002), если Premium нельзя подарить, отвечаем422(-9003); деньги при этом не блокируются; - фиксируем цену по вашему прайсу, она сохраняется в заказе и дальше не меняется;
- блокируем сумму на балансе (
HOLD), при нехватке отвечаем402(-9301); - ставим заказ в очередь и отвечаем
201со статусомQUEUED.
Статусы
Current state of one order: its status, what was bought and for how much. Poll it after creating an order, or subscribe to the webhook instead of polling.
Authorization
apiKey ifk_<clientId>_<secret>, for example ifk_48aa52d67c0fef6decb05b36_lVlZSWKN43sgb2vfEpFbqtzQ0ePNZya6yZr-RmJ4wxo
In: header
Path Parameters
uuidResponse Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/orders/497f6eca-6276-4993-bfeb-53cbbbba6f08"{ "success": true, "data": { "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "externalId": "bot-order-1024", "product": "STARS", "quantity": 100, "months": null, "username": "durov", "recipientName": "Pavel Durov", "status": "SUCCEEDED", "price": "1.65", "currency": "USD", "failure": null, "createdAt": "2026-10-06T09:15:22.443Z", "sentAt": "2026-10-06T09:15:31.902Z", "completedAt": "2026-10-06T09:15:48.215Z" }, "meta": { "requestId": "9f1c2b7e-3a4d-4e5f-8a6b-7c8d9e0f1a2b", "timestamp": "2026-10-06T09:15:22.481Z", "processingTimeMs": 38 }}Project orders, newest first.
Authorization
apiKey ifk_<clientId>_<secret>, for example ifk_48aa52d67c0fef6decb05b36_lVlZSWKN43sgb2vfEpFbqtzQ0ePNZya6yZr-RmJ4wxo
In: header
Query Parameters
1 <= value11 <= value <= 10020QUEUED waiting, PROCESSING in progress, SENT transfer to the supplier sent and awaiting confirmation,
SUCCEEDED delivered, FAILED not delivered (hold released), NEEDS_REVIEW an operator checks the outcome.
Value in
- "QUEUED"
- "PROCESSING"
- "SENT"
- "SUCCEEDED"
- "FAILED"
- "NEEDS_REVIEW"
1 <= length <= 128Response Body
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/orders"{ "success": true, "data": [ { "id": "2f1a8b3c-5d6e-4f70-8a9b-0c1d2e3f4a5b", "externalId": "bot-order-1025", "product": "PREMIUM", "quantity": null, "months": 6, "username": "durov", "recipientName": "Pavel Durov", "status": "FAILED", "price": "16.99", "currency": "USD", "failure": { "code": "RECIPIENT_NOT_ELIGIBLE", "message": "The recipient cannot receive this gift (Premium may already be active)" }, "createdAt": "2026-10-06T09:16:02.118Z", "sentAt": null, "completedAt": "2026-10-06T09:16:05.774Z" }, { "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "externalId": "bot-order-1024", "product": "STARS", "quantity": 100, "months": null, "username": "durov", "recipientName": "Pavel Durov", "status": "SUCCEEDED", "price": "1.65", "currency": "USD", "failure": null, "createdAt": "2026-10-06T09:15:22.443Z", "sentAt": "2026-10-06T09:15:31.902Z", "completedAt": "2026-10-06T09:15:48.215Z" } ], "meta": { "requestId": "9f1c2b7e-3a4d-4e5f-8a6b-7c8d9e0f1a2b", "timestamp": "2026-10-06T09:20:00.012Z", "processingTimeMs": 21, "pagination": { "page": 1, "limit": 20, "totalItems": 2, "totalPages": 1 } }}QUEUED ──▶ PROCESSING ──▶ SENT ──▶ SUCCEEDED
▲ │ │
└── повтор ──┘ ├──▶ QUEUED (доказано, что перевод не прошёл)
│ └──▶ NEEDS_REVIEW ──▶ SUCCEEDED | FAILED
└──▶ FAILED (окончательная ошибка или 3 попытки)| Статус | Что значит | Конечный |
|---|---|---|
QUEUED | в очереди, ждёт свободный Supplier Account | нет |
PROCESSING | выполняется: бронь у поставщика и отправка платежа | нет |
SENT | платёж поставщику отправлен, ждём подтверждения в сети | нет |
SUCCEEDED | Stars/Premium выданы, сумма списана (CAPTURE) | да |
FAILED | не выполнен, блокировка снята (RELEASE), деньги не списаны | да |
NEEDS_REVIEW | исход неизвестен, заказ проверяет наша поддержка, итог придёт вебхуком | нет |
Обычно путь от QUEUED до SUCCEEDED занимает от 10 до 60 секунд. Если все аккаунты заняты (см. троттлинг), заказ ждёт в QUEUED, это нормально.
Повторы
Повторы делает платформа, вам не нужно пересоздавать заказ:
- проблема аккаунта до отправки платежа (истекла сессия, мало средств на кошельке): заказ возвращается в
QUEUEDи берётся другим аккаунтом, попытка не тратится; - временная ошибка поставщика или сети до отправки: повтор через 30 секунд × номер попытки; всего 3 попытки, после них заказ получает
FAILEDс кодомATTEMPTS_EXHAUSTED; - окончательная ошибка (получатель не найден, Premium уже активен): сразу
FAILEDс кодомRECIPIENT_NOT_FOUNDилиRECIPIENT_NOT_ELIGIBLE; - после
SENTзаказ повторяется, только если доказано, что перевод не исполнился (попытка тратится). Так двойная выдача и двойная оплата исключены; если исход не ясен за 10 минут, заказ уходит вNEEDS_REVIEWи решается вручную (при отказе заказ получаетFAILEDс кодомREJECTED_BY_REVIEW).
failure.code | Причина |
|---|---|
RECIPIENT_NOT_FOUND | получатель не найден у поставщика |
RECIPIENT_NOT_ELIGIBLE | получателю нельзя подарить (например, Premium уже активен) |
ATTEMPTS_EXHAUSTED | заказ не удалось выполнить за 3 попытки |
REJECTED_BY_REVIEW | заказ отменён после ручной проверки |
Идемпотентность
Две защиты от дублей, используйте обе:
Idempotency-Keyзащищает конкретный HTTP-запрос. Повтор с тем же ключом и тем же телом вернёт тот же ответ (с заголовкомIdempotent-Replayed: true), не создавая второй заказ. Тот же ключ с другим телом даёт422(-11002); если первый запрос ещё выполняется, ответ будет409(-11003), повторите чуть позже. Ответы с ошибкой не запоминаются: исправленный запрос можно повторить с тем же ключом. Генерируйте ключ один раз на операцию (например, UUID) и повторяйте его при таймауте.externalIdзащищает заказ в вашей системе. Второй заказ с тем жеexternalIdв Project не создастся, даже с новымIdempotency-Key: повторныйPOSTс теми же параметрами вернёт уже созданный заказ, а с другими (username,product,quantity,months) вернёт409(-9207). Если вы не уверены, создан ли заказ, найдите его:GET /v1/orders?externalId=1042.
Получение
GET /v1/orders/{id}: один заказ; для заказа чужого Project ответ404(-9201).GET /v1/orders?status=FAILED&externalId=1042&page=1&limit=20: список заказов Project, новые первыми (limitдо 100); пагинация вmeta.pagination.