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

> Как ИИ-агент заказывает SSL, регистрирует и продлевает домены по ключу API: оплата с баланса, ссылка на доплату для человека и уведомление об оплате.

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

Скрипт или ИИ-агент может покупать по ключу API, но платит только с баланса организации. Если на балансе не хватает денег, API не отказывает, а возвращает ссылку для человека: он доплачивает ровно недостачу картой или счётом на IBAN, и заказ сразу уходит в работу. Агент сам узнаёт об оплате и продолжает.

Сейчас так можно заказать SSL-сертификат (право `ssl.order`) продлить домен (право `domain.renew`) и зарегистрировать новый (право `domain.register`), см. [ключи API](https://zrazu.com/ru/docs/api-keys.md). То же агент может делать через [MCP с ключом](https://zrazu.com/ru/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`.
