Заказы и товар

Смета, заказ с оплатой из аванса и выдача товара. Товар забирается отдельным запросом — в ответе на создание заказа его нет.

Обновлено 26 сентября 2026 г. · 5 мин чтения
Markdown

Как проходит заказ

  1. Смета POST /v1/orders/quote: цены строк, итог и наличие. Товар она не резервирует: зовите сколько угодно.
  2. Заказ POST /v1/orders списывает оптовую сумму с аванса и выдаёт товар в той же операции.
  3. Товар GET /v1/orders/{id}: массив goods, по строке на единицу. Храните его зашифрованным.
  4. Активация если у позиции needs_activation, ждите событие activation.needs_input и передайте данные клиента (раздел «Активации»).

reseller_ref — ваш номер заказа и ключ повтора

Создайте его один раз на заказ и сохраните ДО запроса. Повтор с тем же ref и телом вернёт тот же заказ — второго не будет. Тот же ref с другим телом — 422 idempotency_conflict с order_id прежнего заказа.

Каталог

GET /v1/catalog — товары и варианты для опта: wholesale_usd, способ выдачи (delivery_type), нужна ли активация (needs_activation), какие данные клиента могут понадобиться (possible_credential_kinds), срок подписки, наличие in_stock и уровень few|ok (точных остатков API не отдаёт). Кэш — 1 мин.

Создать заказ

POST /v1/orders — заказ оплачивается авансом и выдаётся сразу: {reseller_ref, items[{product_id, variant_id?, quantity, item_ref?}], new_account?, max_total_usd?, metadata?} → 201 {id, status, fulfillment, total_usd, lines, goods_ready, activations[]}.

  • Пара «товар + вариант» — одна строка: дубль — 422 validation_error · duplicate_line; единиц в заказе не больше лимита партнёра — max_units.
  • max_total_usd — потолок суммы: цена выросла выше — 409 price_changed с новой total_usd, аванс не тронут.
  • metadata — ваши данные к заказу (до 1 КБ JSON), возвращаются в заказе и событиях.
  • Нет в наличии — 409 out_of_stock с позициями и причиной (без количеств).
curl https://api.astrum.shop/v1/orders \
  -H "Authorization: Bearer $ASTRUM_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reseller_ref": "ord-10482",
    "items": [{"product_id": "3f6c0e7e-2b1d-4c1a-9a57-4d0f1b8e2c11", "quantity": 1}],
    "max_total_usd": "25.00"
  }'
import os, httpx

order = httpx.post(
    "https://api.astrum.shop/v1/orders",
    headers={"Authorization": f"Bearer {os.environ['ASTRUM_KEY']}"},
    json={
        "reseller_ref": "ord-10482",  # сохранить ДО запроса
        "items": [{"product_id": "3f6c0e7e-2b1d-4c1a-9a57-4d0f1b8e2c11", "quantity": 1}],
        "max_total_usd": "25.00",
    },
    timeout=30,
).json()
const res = await fetch("https://api.astrum.shop/v1/orders", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ASTRUM_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    reseller_ref: "ord-10482", // сохранить ДО запроса
    items: [{ product_id: "3f6c0e7e-2b1d-4c1a-9a57-4d0f1b8e2c11", quantity: 1 }],
    max_total_usd: "25.00",
  }),
});
const order = await res.json();

Товара в этом ответе нет.

Забирайте его из GET /v1/orders/{id}, храните зашифрованным и не пишите в логи. goods_ready: true — значит, забирать уже есть что.

Пример: Заказ с аванса

{
  "reseller_ref": "ord-10482",
  "items": [
    {
      "product_id": "3f6c0e7e-2b1d-4c1a-9a57-4d0f1b8e2c11",
      "quantity": 1,
      "item_ref": "line-1"
    }
  ],
  "max_total_usd": "25.00",
  "metadata": {
    "customer": "c-7781"
  }
}
{
  "id": "b1e04c6e-5a0b-4f6e-9a39-0b9f2f1c8d21",
  "reseller_ref": "ord-10482",
  "status": "delivered",
  "fulfillment": "complete",
  "total_usd": "20.00",
  "metadata": {
    "customer": "c-7781"
  },
  "lines": [
    {
      "item_ref": "line-1",
      "product_id": "3f6c0e7e-2b1d-4c1a-9a57-4d0f1b8e2c11",
      "variant_id": null,
      "title": "ChatGPT Plus · 1 месяц",
      "delivery_type": "activation",
      "subscription_days": 30,
      "new_account": false,
      "quantity": 1,
      "unit_usd": "20.00",
      "line_usd": "20.00"
    }
  ],
  "goods_ready": true,
  "activations": [],
  "refunds": [],
  "created_at": "2026-09-24T10:14:03Z",
  "paid_at": "2026-09-24T10:14:03Z",
  "delivered_at": "2026-09-24T10:14:04Z"
}

Статусы

Заказ с активацией становится delivered сразу после выдачи — «выдан» ещё не значит «подписка включена», смотрите fulfillment.

status Что с заказом
pending ждёт оплаты — у опта почти не бывает
paid оплачен авансом
delivered товар выдан
canceled отменён
refunded возвращён на аванс
fulfillment Что с активациями
complete всё выдано и включено
awaiting_customer ждём данные клиента
in_progress поставщик включает
manual занимаются люди
failed не вышло — причина в активации

Что приходит в goods

goods_ready — в заказе есть что забрать через GET /v1/orders/{id}. Товар — массив goods, по строке на единицу; у каждой — item_ref и product_id строки заказа:

type Что это Поля
key ключ, который и есть товар value
api_key API-ключ сервиса value
account готовый аккаунт raw — строка как есть (двоеточие законно внутри пароля)
new_account «новый аккаунт от нас» (card_pay) login, password, login_method, mailbox{email, password, recovery}

Список, заказ и отмена

  • GET /v1/orders/{id} — заказ целиком, с товаром goods, активациями и возвратами.
  • GET /v1/orders — список с курсором и фильтром status.
  • POST /v1/orders/{id}/cancel — только заказ в pending (у опта почти не бывает: оплата идёт в той же операции). Нужен Idempotency-Key.

Отказы

Ветвитесь по code, а не по тексту: message написан для людей и может меняться. Отказы доступа — общие для всех методов, полный реестр — в разделе «Ошибки».

HTTP code Что это и что делать
402 insufficient_balance Аванса не хватает — пополните и повторите с тем же reseller_ref
409 out_of_stock Нет в наличии
409 price_changed Сумма выше max_total_usd — перечитайте цену
404 product_not_found Товар не найден или скрыт
409 not_available_via_api Этот товар через API не продаётся
409 variant_required Укажите вариант товара
409 new_account_unavailable «Новый аккаунт» доступен только для оплаты нашей картой
422 empty_order В заказе нет позиций
422 idempotency_conflict Ключ повтора уже использован с другим запросом
409 idempotency_in_progress Такой же запрос ещё выполняется — повторите позже
429 daily_cap_reached Исчерпан суточный лимит
503 rate_unavailable Курс недоступен — повторите позже
422 validation_error Запрос не прошёл проверку
Страница помогла?