> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.voodoo.center/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.voodoo.center/_mcp/server.

# Розміщення замовлень

Розміщення замовлення — це єдиний виклик `POST /api/v1/orders`. Він списує кошти
з балансу вашого акаунта й одразу повертає `201` зі `status: "pending"`.
Виконання відбувається асинхронно — кінцевий результат надходить на ваш
[webhook](/webhooks) і завжди доступний для читання з `GET /api/v1/orders/{id}`.

## Типи товарів

Кожен товар каталогу має **тип продукту**, який визначає, що ви маєте надіслати:

| Тип продукту | Що це                                       | `quantity`                           | `fields`            |
| ------------ | ------------------------------------------- | ------------------------------------ | ------------------- |
| `key`        | Коди подарункових карток / ліцензійні ключі | Ціла кількість, за замовчуванням `1` | Не використовується |
| `topup`      | Поповнення балансу/валюти                   | Десяткова сума, **обовʼязково**      | **Обовʼязково**     |
| `service`    | Ручні/ігрові послуги                        | Пропустіть (завжди `1`)              | **Обовʼязково**     |

`item_id` товару, тип продукту, межі кількості та визначення полів ви
дізнаєтеся з **експорту каталогу** — окремого каналу даних, а не частини цього
API. API не надає ендпоінта для перегляду каталогу.

## Поля запиту

* **`item_id`** *(ціле число, обовʼязково)* — числовий id товару з каталогу.
* **`quantity`** *(число)* — див. таблицю типів товарів вище. Має бути в межах
  діапазону min/max товару.
  * `key`: ціла кількість (за замовчуванням `1`).
  * `topup`: десяткова сума (обовʼязково).
  * `service`: пропустіть — вона завжди `1`.
* **`merchant_order_id`** *(рядок, необовʼязково)* — ваш власний ідентифікатор,
  **унікальний у межах акаунта**. Використовуйте його для **ідемпотентності** та
  для звʼязування подій webhook із вашими записами.
* **`fields`** *(обʼєкт)* — обовʼязкові лише для товарів `topup` і `service`,
  індексовані за **іменами полів** товару. Товари `key` не приймають `fields`.

### Значення полів: текст проти вибору

Кожне поле товару є або **текстовим** полем, або полем **вибору**:

* **Текстове поле** → надсилайте значення як **рядок** (наприклад, `"player_id":
  "123456789"`).
* **Поле вибору** → надсилайте **числовий id вибору**, а не мітку (наприклад,
  `"server": 17`, де `17` — це id вибору «Europe (EU-West)»).

У відповідях надіслані `fields` повертаються з рендерингом значень вибору як
їхніх читабельних **відображуваних назв** (наприклад, `"server": "Europe
(EU-West)"`), навіть якщо ви надіслали числовий id. Це лише для відображення —
під час створення продовжуйте надсилати числові id вибору.

## Створення замовлення

```bash title="Товар типу key (подарункова картка / код)"
curl -X POST https://api.voodoo.center/api/v1/orders \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "item_id": 4090,
    "quantity": 2,
    "merchant_order_id": "po-10231"
  }'
```

```bash title="Товар типу top-up (поля; server — id вибору)"
curl -X POST https://api.voodoo.center/api/v1/orders \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "item_id": 4211,
    "quantity": 10,
    "merchant_order_id": "po-10232",
    "fields": { "player_id": "123456789", "server": 17 }
  }'
```

```bash title="Товар типу service (без кількості)"
curl -X POST https://api.voodoo.center/api/v1/orders \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "item_id": 5000,
    "merchant_order_id": "po-10233",
    "fields": { "account_email": "player@example.com" }
  }'
```

```python title="create_orders.py"
import httpx

BASE = "https://api.voodoo.center"
headers = {"Authorization": f"Bearer {access_token}"}

# Товар типу key — ціла кількість, без полів
key_order = httpx.post(f"{BASE}/api/v1/orders", headers=headers, json={
    "item_id": 4090,
    "quantity": 2,
    "merchant_order_id": "po-10231",
}).json()

# Товар типу top-up — десяткова кількість + поля (server — числовий id вибору)
topup_order = httpx.post(f"{BASE}/api/v1/orders", headers=headers, json={
    "item_id": 4211,
    "quantity": 10,
    "merchant_order_id": "po-10232",
    "fields": {"player_id": "123456789", "server": 17},
}).json()

# Товар типу service — пропустіть кількість, надішліть поля
service_order = httpx.post(f"{BASE}/api/v1/orders", headers=headers, json={
    "item_id": 5000,
    "merchant_order_id": "po-10233",
    "fields": {"account_email": "player@example.com"},
}).json()

print(key_order["id"], key_order["status"])  # ... pending
```

Успішне створення повертає `201` із замовленням у стані `pending`:

```json title="201 Created"
{
  "id": "0190f8a1-6b2c-7e33-9a10-4c1d2e3f5a6b",
  "item": 4211,
  "item_name": "Sample Game Top-up",
  "item_product_type": "topup",
  "quantity": 10,
  "delivered_quantity": 0,
  "price": 12.50,
  "refund_amount": 0,
  "fields": { "player_id": "123456789", "server": "Europe (EU-West)" },
  "status": "pending",
  "error": "",
  "error_message": "",
  "codes": [],
  "merchant_order_id": "po-10232",
  "source": "api",
  "created_by": { "id": "0190f8a0-1111-7000-8000-000000000001", "email": "integrations@merchant.example" },
  "created_at": "2026-07-05T12:00:00Z",
  "completed_at": null
}
```

## Життєвий цикл замовлення

Замовлення починається у стані `pending`, може ненадовго перейти в `processing`,
а потім завершується одним із трьох термінальних статусів:

| Термінальний статус | Значення                                 | Ключові поля                                    |
| ------------------- | ---------------------------------------- | ----------------------------------------------- |
| `completed`         | Доставлено повністю                      | `codes` (товари типу key), `delivered_quantity` |
| `partial`           | Доставлено частину одиниць               | `delivered_quantity`, `refund_amount`           |
| `failed`            | Нічого не доставлено, списання повернуто | `error`, `error_message`, `refund_amount`       |

* **`codes`** — рядки доставлених ключів, для товарів типу `key`.
* **`refund_amount`** — сума, повернута за недоставлені одиниці для замовлення
  `partial` або `failed`.
* **`error` / `error_message`** — встановлюються, коли `status` дорівнює `failed`
  (наприклад, `error: "OUT_OF_STOCK"`).

Товар, якого **немає в наявності на момент створення**, відхиляється одразу як
помилка валідації `400` («Item is not available»). Якщо запас або виконання дають
збій **після** прийняття замовлення, замовлення завершується термінальним
`status: "failed"` (відображається на вашому webhook) — а не HTTP-помилкою. Див.
[Помилки](/errors).

## Читання замовлення

Отримайте поточний стан будь-якого зі своїх замовлень за допомогою
`GET /api/v1/orders/{id}`:

```bash title="Отримання замовлення"
curl https://api.voodoo.center/api/v1/orders/0190f8a1-6b2c-7e33-9a10-4c1d2e3f5a6b \
  -H "Authorization: Bearer <access_token>"
```

```python title="get_order.py"
order_id = "0190f8a1-6b2c-7e33-9a10-4c1d2e3f5a6b"
order = httpx.get(
    f"{BASE}/api/v1/orders/{order_id}",
    headers={"Authorization": f"Bearer {access_token}"},
).json()
print(order["status"], order["codes"])
```

```json title="Виконане замовлення з ключами"
{
  "id": "0190f8a1-6b2c-7e33-9a10-4c1d2e3f5a6b",
  "item": 4090,
  "item_name": "Sample Gift Card 10 USD",
  "item_product_type": "key",
  "quantity": 2,
  "delivered_quantity": 2,
  "price": 18.00,
  "refund_amount": 0,
  "fields": {},
  "status": "completed",
  "error": "",
  "error_message": "",
  "codes": ["ABCD-1234-EFGH-5678", "IJKL-9012-MNOP-3456"],
  "merchant_order_id": "po-10231",
  "source": "api",
  "created_by": { "id": "0190f8a0-1111-7000-8000-000000000001", "email": "integrations@merchant.example" },
  "created_at": "2026-07-05T12:00:00Z",
  "completed_at": "2026-07-05T12:00:07Z"
}
```

`GET /api/v1/orders/{id}` повертає `404` (`code: "not_found"`) для замовлення,
яке не існує **або** не належить вашому акаунту. В API немає ендпоінта для
отримання списку замовлень — переглядайте замовлення в дашборді.

## Webhook проти опитування

Надавайте перевагу [webhook](/webhooks): Voodoo Center надсилає термінальну подію
на вашу URL, щойно замовлення завершується — опитування не потрібне. Опитування
`GET /api/v1/orders/{id}` — це прийнятний запасний варіант (наприклад, якщо
доставку webhook було пропущено), але webhook — це шлях із меншою затримкою та
меншим навантаженням.

Отримуйте та перевіряйте події термінального статусу.

Валідація, недостатній баланс та асинхронні збої.