# Покупки через API — оплата з балансу й посилання на доплату

> Як ШІ-агент замовляє SSL, реєструє й продовжує домени за ключем API: оплата з балансу, посилання на доплату для людини й сповіщення про оплату.

URL: https://zrazu.com/docs/api-orders/

Скрипт або ШІ-агент може купувати за ключем API, але платить лише з балансу організації. Якщо на балансі бракує грошей, API не відмовляє, а повертає посилання для людини: вона доплачує рівно нестачу карткою або рахунком на IBAN, і замовлення одразу йде в роботу. Агент дізнається про оплату сам і продовжує.

Зараз так можна замовити SSL-сертифікат (право `ssl.order`) продовжити домен (право `domain.renew`) і зареєструвати новий (право `domain.register`), див. [ключі API](https://zrazu.com/docs/api-keys.md). Те саме агент може робити через [MCP з ключем](https://zrazu.com/docs/api-mcp-account.md).

## Як це працює

1. Агент замовляє сертифікат: `POST /v1/ssl/certificates` з полем `"if_short": "pay_link"`.
2. Якщо на балансі вистачає грошей, сума списується одразу. Відповідь — `201`, сертифікат іде на перевірку домену.
3. Якщо грошей бракує, нічого не списується і не резервується. Відповідь — `402` з кодом `payment_required` і посиланням `payment_url`.
4. Агент передає посилання людині: у чат, листом, повідомленням.
5. Людина відкриває посилання без входу в кабінет, бачить склад замовлення й суму до сплати і платить карткою або рахунком на IBAN.
6. Гроші зараховуються на баланс, і з балансу одразу оплачується замовлення.
7. Агент бачить, що замовлення оплачене (через `GET /v1/orders/{id}` або вебхук), і працює далі: чекає на випуск, забирає файли сертифіката.

Без `if_short` API поводиться як раніше: при нестачі відповідає `402 balance_short` і замовлення не створює.

## Замовлення з посиланням на доплату

```sh
curl -X POST https://api.zrazu.com/v1/ssl/certificates \
  -H "Authorization: Bearer zr_live_..." \
  -H "Idempotency-Key: 0b7c6e1a-3f42-4d8e-9a51-2c6f0e9d7b10" \
  -H "Content-Type: application/json" \
  -d '{"product_id": "…", "mode": "vat", "domain": "example.com.ua",
       "csr": "-----BEGIN CERTIFICATE REQUEST-----…", "dcv_method": "dns",
       "if_short": "pay_link"}'
```

Відповідь, коли грошей бракує:

```json
{
  "error": { "code": "payment_required", "message": { "uk": "…", "en": "…" } },
  "amount_due": 22500,
  "payment_url": "https://vse.zrazu.com/pay-link/…/",
  "expires_at": "2026-11-16T12:00:00Z",
  "order": { "id": "…", "number": "202611-48271", "status": "awaiting_payment", "amount_due": 22500, "items": [ … ] },
  "certificate": { "id": "…", "status": "unpaid", … }
}
```

Суми — у копійках. `amount_due` — це замовлення мінус живі гроші на балансі; бонуси сюди не входять.

## Посилання на доплату

- Посилання діє 72 години. Сторінка показує склад замовлення, суму до сплати й продавця. Даних вашої організації на ній немає.
- Карткою: до суми додається комісія банку, кнопка показує повну суму. Рахунком на IBAN: рахунок виписується на нестачу, номер рахунку збігається з номером замовлення.
- Сума перераховується щоразу, коли сторінку відкривають. Якщо баланс тим часом поповнили, доплачувати треба менше.
- Якщо посилання загубили або строк минув, нове видає `POST /v1/orders/{id}/payment-link`. Попереднє посилання цього замовлення після цього перестає діяти. Поки людина платить карткою, нове посилання не видається: відповідь — `409 payment_in_progress`.
- Якщо баланс поповнили іншим способом (у кабінеті, переказом), агент сам оплачує замовлення: `POST /v1/orders/{id}/pay`. Якщо грошей знову не вистачає, відповідь — `402`. Поки попереднє посилання діє, нового немає (`payment_url` — `null`): людина платить за тим самим.
- Оплачувати й видавати посилання ключ може лише для замовлень, які зробив сам. Замовлення з кабінету чи іншого ключа для нього не існує (`404`).

Посилання — це право доплатити саме це замовлення. Передавайте його тим, кому довіряєте: за сумою до сплати видно, скільки приблизно лежить на балансі.

## Як агент дізнається, що оплата прийшла

**Опитування — основний спосіб для ШІ-агентів.** Асистенти в чаті не приймають вхідних запитів, тому питають самі:

```sh
curl -H "Authorization: Bearer zr_live_..." "https://api.zrazu.com/v1/orders/{id}?wait=60"
```

З `wait` (до 60 секунд) відповідь приходить, щойно замовлення змінилося, або після `wait` секунд, якщо нічого не сталося. Повторюйте запит у циклі. Одночасно чекати можна до 3 запитів на ключ і до 10 на організацію; понад це — `429 too_many_waits`, тоді питайте без `wait`.

| Поле | Що означає |
| --- | --- |
| `status` | `awaiting_payment` — чекає на гроші; `review` — гроші прийшли, замовлення на перевірці безпеки; `paid` — оплачено; `partly_failed` — частину не виконано, гроші за неї на балансі; `cancelled` — скасовано |
| `amount_due` | скільки ще доплатити, у копійках. За цією сумою видно залишок балансу, тому ключ лише з `ssl.read` отримує `null`; суму бачать ключі з `ssl.order` або `billing.read` |
| `fulfilled` | `true` — усе виконано: сертифікат випущено або остаточно відмовлено |
| `items[].certificate_id` | id сертифіката: з ним агент працює далі через `/v1/ssl/certificates/{id}` |
| `payment_link_expires_at` | до коли діє останнє посилання; `null` — посилання немає або його строк минув |

Читати замовлення може ключ з правом `ssl.read`, `ssl.order` або `billing.read`.

**Вебхук — для серверних інтеграцій.** Якщо в організації налаштовано вебхук, ZRAZU надсилає події `order.paid`, `order.fulfilled` і `order.cancelled` для замовлень, по яких видавали посилання. У тілі запиту, у полі `data`, — `event_id` і замовлення в тому ж вигляді, що й у `GET /v1/orders/{id}`. Запит підписано так само, як інші вебхуки (`X-Zrazu-Signature`). Якщо ваш сервер не відповів, ZRAZU повторює подію з паузою, що зростає до години. Тому подія може прийти двічі: відрізняйте повтори за `event_id`. Події не надсилаються, якщо у вебхука вимкнено категорію «Гроші».

## Продовження домену

Ключу потрібне право `domain.renew`. Продовження оформлюється окремим замовленням і в кошик кабінету не потрапляє.

```sh
curl -X POST https://api.zrazu.com/v1/domains/example.com.ua/renew \
  -H "Authorization: Bearer zr_live_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"years": 1, "expires_at": "2027-03-14", "if_short": "pay_link"}'
```

- `years` — від 1 до 10. Строк домену після продовження не може бути далі ніж 9 років від сьогодні.
- `expires_at` — обов'язковий: поточна дата закінчення з `GET /v1/domains`. Якщо в нас вона вже інша, домен продовжили раніше, і API відповідає `409 expiry_mismatch`: двічі ви не заплатите. Поле необов'язкове, але радимо його передавати.
- `mode` — `vat` або `no_vat`. Потрібен, лише якщо домен ще не оплачували в нас (наприклад, його щойно перенесли). Інакше продовжує той самий продавець, що й минулого разу.
- Якщо грошей вистачає, відповідь — `201`, замовлення в статусі `paid`. Новий строк з'явиться в `GET /v1/domains`, щойно реєстр підтвердить продовження; `fulfilled` у замовленні стане `true`.
- Якщо грошей бракує, усе як для SSL: без `if_short` — `402 balance_short` і замовлення немає; з `"if_short": "pay_link"` — `402` з посиланням.

## Реєстрація домену

Ключу потрібне право `domain.register`. Реєстрація оформлюється окремим замовленням і в кошик кабінету не потрапляє.

1. Візьміть власника домену зі списку `GET /v1/contacts/owners`: `id`, вид (`person` чи `org`), ім'я, `complete` (чи є повна поштова адреса) і `authority` (чи підтверджено в кабінеті повноваження щодо цієї особи). Пошти й телефону там немає. Нового власника ключ не створює: запис додає людина в кабінеті, у «Контактах». Власника потім ключем не змінити, тому обирайте уважно.
2. Надішліть запит без `documents_hash`. Якщо реєстр вимагає згоди з документами, API відповідає `409 documents_required`: у відповіді `documents` (назва, редакція, посилання) і `documents_hash`.
3. Прочитайте документи й повторіть запит із цим `documents_hash`. Повтор із відбитком — згода вашої організації з документами реєстру в показаних редакціях. Якщо власник домену — інша особа, ви погоджуєтеся від її імені й гарантуєте, що маєте на це повноваження і що вона ознайомлена з цими документами. Якщо документи змінилися, ви знову отримаєте `documents_required` з новим відбитком.

```sh
curl -X POST https://api.zrazu.com/v1/domains/example.com.ua/register \
  -H "Authorization: Bearer zr_live_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"years": 1, "owner": "ID_ЗАПИСУ", "mode": "no_vat", "documents_hash": "ВІДБИТОК_З_ВІДПОВІДІ", "if_short": "pay_link"}'
```

- `years` — від 1 до 10.
- `owner` — обов'язковий: `id` запису з `GET /v1/contacts/owners`.
- `mode` — обов'язковий: `vat` або `no_vat`.
- Поки не надіслано правильний `documents_hash`, замовлення не створюється й гроші не списуються.
- Якщо грошей вистачає, відповідь — `201`, замовлення в статусі `paid`. Домен з'явиться в `GET /v1/domains`, щойно реєстр його зареєструє; `fulfilled` у замовленні стане `true`.
- Якщо грошей бракує, усе як для SSL. Людина на сторінці доплати бачить ті самі документи й погоджується з ними сама.

## Обмеження

- Денний ліміт трат ключа рахує й замовлення, що чекають оплати.
- Перед оплатою замовлення проходить ту саму перевірку безпеки, що й оплата в кабінеті. Якщо її потрібно перевірити вручну, статус буде `review`.
- Оплата `POST /v1/orders/{id}/pay` замовлення реєстрації знову перевіряє власника й документи. Якщо запис власника прибрали з довідника або документи реєстру змінилися, оплату не приймуть: оформіть замовлення заново.
- Замовлення, яке не оплатили, лишається в кабінеті в розділі «Замовлення». Його можна оплатити там або скасувати.

## Якщо не вийшло

- **`409 documents_required`.** Прочитайте `documents` або покажіть їх людині й повторіть запит із `documents_hash` з цієї відповіді: повтор означає згоду.
- **`422 owner_required`, `owner_not_found`.** Передайте `owner` — `id` з `GET /v1/contacts/owners`.
- **`422 owner_unconfirmed`.** Для запису не підтверджено повноваження: відкрийте його в «Контактах», поставте позначку й збережіть.
- **`422 owner_incomplete`.** У власника неповна поштова адреса: доповніть її в кабінеті або оберіть інший запис.
- **`409 name_taken`.** Ім'я вже зареєстроване.
- **`409 register_unavailable`.** Реєстр зараз не відповідає або реєстрацію в зоні призупинено. Спробуйте пізніше.
- **`429 rate_limited`.** Ключ, організація або адреса вичерпали частку перевірок імен у реєстрі. Спробуйте за хвилину.
- **`409 expiry_mismatch`.** Домен уже продовжили: перевірте строк у `GET /v1/domains`.
- **`422 mode_required`.** Домен ще не оплачували в нас: передайте `"mode": "vat"` або `"no_vat"`.
- **`409 order_refused`.** Продовження не прийняли: домен уже продовжується, продовження зупинено або строк вийшов би за 9 років. Причина — у `message.uk`.
- **`409 renew_unavailable`.** Домен зараз не продовжити: він заблокований, процедура в реєстрі ще не завершилась або реєстр не відповідає. Спробуйте пізніше.
- **`402 balance_short`.** Запит без `"if_short": "pay_link"`: додайте поле, щоб отримати посилання.
- **`409 not_awaiting_payment`.** Замовлення вже оплачене або скасоване. Перевірте `GET /v1/orders/{id}`.
- **`409 balance_enough`.** На балансі вже вистачає грошей. Оплатіть замовлення: `POST /v1/orders/{id}/pay`.
- **`409 payment_in_progress`.** Людина саме платить карткою. Зачекайте на результат через `GET /v1/orders/{id}?wait=60`.
- **Сторінка пише «Посилання недійсне».** Адресу скопіювали не повністю. Попросіть агента надіслати посилання ще раз.
- **Сторінка пише «Посилання прострочене».** Строк минув або для замовлення видали нове посилання. Попросіть агента надіслати останнє або видати нове: `POST /v1/orders/{id}/payment-link`.
