> ## Documentation Index
> Fetch the complete documentation index at: https://oblodai.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Платёжные ссылки

**Методы:** `/v1/payment/link` · `/list` · `/info` · `/toggle`

**Платёжная ссылка** — многоразовый URL оплаты, который вы просто даёте покупателю (в письме, в чате,
кнопкой на сайте). Каждый, кто по ней платит, получает **свой отдельный счёт** — ссылку можно
использовать сколько угодно раз.

<Tip>
  **Ссылка — единственный способ принимать платежи БЕЗ бэкенда.** Обычный [`POST /v1/payment`](/reference/payment-create)
  нужно подписывать секретом, а секрет нельзя класть в браузер — значит, нужен ваш сервер. У ссылки
  счёт создаёт **публичный** [`POST /v1/link/{id}/checkout`](/reference/link-public), подпись не нужна. Поэтому
  она работает на Tilda, Wix, в Notion, в письме — везде, где своего бэкенда нет.
</Tip>

**Базовый URL:** `https://api.oblodai.com` · **Аутентификация:** обязательна (управление ссылками).
Страница оплаты по ссылке — [публичные методы](/reference/link-public), без ключа.

<Note>
  Примеры используют хелпер `call()` и переменные `$SECRET`/`$PUBLIC_ID` — их определение см. в
  [Как подписать запрос](/guides/signing-requests). Проще не писать подпись руками, а взять
  [SDK](/sdk/overview).
</Note>

***

## Три режима суммы

Главное решение при создании ссылки — кто задаёт сумму.

| `amount_mode` | Кто задаёт сумму                                             | Для чего                                                            |
| ------------- | ------------------------------------------------------------ | ------------------------------------------------------------------- |
| `fixed`       | Вы — в `amount_fixed`. Покупатель изменить не может.         | Товар, услуга, счёт с конкретной ценой.                             |
| `open`        | **Покупатель — любую.** `amount_min` — необязательный «пол». | **Донаты**, чаевые, «заплати сколько хочешь».                       |
| `range`       | Покупатель — в пределах `amount_min`…`amount_max`.           | «От 5 до 1000 \$»: поддержка проекта с рамками, пополнение баланса. |

***

## POST /v1/payment/link — создать ссылку

### Параметры запроса

<ParamField body="title" type="string">
  Заголовок на странице оплаты.
</ParamField>

<ParamField body="description" type="string">
  Описание на странице оплаты.
</ParamField>

<ParamField body="amount_mode" type="string" required>
  Режим суммы: `fixed` | `open` | `range`.
</ParamField>

<ParamField body="currency" type="string" required>
  **Валюта цены** — фиат (`USD`, `EUR`, `RUB`, …) или монета. Список — `pricing_currencies` из [`GET /v1/currencies`](/reference/currencies).
</ParamField>

<ParamField body="amount_fixed" type="string">
  Сумма — для `fixed`. Обязательна в этом режиме.
</ParamField>

<ParamField body="amount_min" type="string">
  Нижняя граница: «пол» для `open` (необязателен) и минимум для `range` (обязателен).
</ParamField>

<ParamField body="amount_max" type="string">
  Верхняя граница — для `range`. Обязательна в этом режиме.
</ParamField>

<ParamField body="pinned_currency" type="string">
  **Валюта расчёта** (монета), закреплённая за ссылкой. Пусто — монету выбирает покупатель.
</ParamField>

<ParamField body="pinned_network" type="string">
  Сеть расчёта, закреплённая за ссылкой. Пусто — сеть выбирает покупатель.
</ParamField>

<ParamField body="expires_in" type="int64" default="0">
  Срок жизни ссылки, секунд от момента создания. **`0` (по умолчанию) — ссылка бессрочная.**
</ParamField>

<Info>
  Обязательность полей зависит от `amount_mode` — см. таблицу режимов выше.
</Info>

**Бессрочность.** `expires_in: 0` — ссылка живёт, пока вы её не выключите через `/toggle`. Это
нормальный режим для кнопки «Поддержать» на сайте. Ограниченный срок нужен только под разовую акцию.

**Закрепление монеты и сети.** Если задать `pinned_currency` + `pinned_network` — все платежи по
ссылке пойдут в этой монете и сети. Если оставить пустыми — покупатель выберет монету и сеть сам
(счёт создастся [валюто‑агностичным](/guides/payment-modes)). Промежуточный вариант (закрепить
только сеть, оставив монету на выбор) смысла не имеет: закрепляйте либо оба поля, либо ни одного.

### Пример запроса

<CodeGroup>
  ```bash cURL wrap theme={null}
  BODY='{"title":"Поддержать проект","description":"Спасибо!","amount_mode":"open","currency":"USD","amount_min":"1.00","expires_in":0}'
  TS=$(date +%s)
  SIG=$(printf '%s\n%s\n%s\n%s' "$TS" 'POST' '/v1/payment/link' "$BODY" \
    | openssl dgst -sha256 -hmac "$SECRET" -hex | sed 's/^.* //')
  curl -s https://api.oblodai.com/v1/payment/link \
    -X POST -H 'Content-Type: application/json' \
    -H "X-Public-Id: $PUBLIC_ID" -H "X-Timestamp: $TS" -H "X-Signature: $SIG" \
    -d "$BODY"
  ```

  ```python Python theme={null}
  # Донат: сумму вводит покупатель, минимум $1, ссылка бессрочная, монету выбирает покупатель.
  call("/v1/payment/link", {
      "title": "Поддержать проект",
      "description": "Спасибо!",
      "amount_mode": "open",
      "currency": "USD",
      "amount_min": "1.00",
      "expires_in": 0,
  })

  # Товар: фиксированные 25 EUR, оплата только USDT в Tron.
  call("/v1/payment/link", {
      "title": "Футболка",
      "amount_mode": "fixed",
      "currency": "EUR",
      "amount_fixed": "25.00",
      "pinned_currency": "USDT",
      "pinned_network": "tron",
  })

  # Диапазон: от 5 до 1000 USD.
  call("/v1/payment/link", {
      "title": "Пополнение баланса",
      "amount_mode": "range",
      "currency": "USD",
      "amount_min": "5.00",
      "amount_max": "1000.00",
  })
  ```

  ```js Node.js theme={null}
  await call("/v1/payment/link", {
    title: "Поддержать проект",
    description: "Спасибо!",
    amount_mode: "open",
    currency: "USD",
    amount_min: "1.00",
    expires_in: 0,
  });
  ```
</CodeGroup>

### Пример ответа

```json theme={null}
{
  "state": 0,
  "result": {
    "link_id": "5d3f2a71-9c84-4b0e-8d17-3e6a2c9f1b40",
    "url": "https://pay.oblodai.com/link/5d3f2a71-9c84-4b0e-8d17-3e6a2c9f1b40"
  }
}
```

`url` — это и есть то, что вы даёте покупателю: ставите ссылкой на кнопку, шлёте в письме, кладёте в
QR‑код.

***

## POST /v1/payment/link/list — список ссылок

### Параметры запроса

<ParamField body="limit" type="int64">
  Сколько ссылок вернуть.
</ParamField>

<ParamField body="offset" type="int64">
  Смещение.
</ParamField>

<CodeGroup>
  ```python Python theme={null}
  call("/v1/payment/link/list", {"limit": 50, "offset": 0})
  ```

  ```js Node.js theme={null}
  await call("/v1/payment/link/list", { limit: 50, offset: 0 });
  ```
</CodeGroup>

### Пример ответа

```json theme={null}
{
  "state": 0,
  "result": {
    "items": [
      {
        "link_id": "5d3f2a71-9c84-4b0e-8d17-3e6a2c9f1b40",
        "title": "Поддержать проект",
        "description": "Спасибо!",
        "amount_mode": "open",
        "currency": "USD",
        "amount_min": "1.00",
        "active": true,
        "url": "https://pay.oblodai.com/link/5d3f2a71-9c84-4b0e-8d17-3e6a2c9f1b40",
        "created_at": "2026-07-13T12:00:00Z"
      }
    ]
  }
}
```

<ResponseField name="link_id" type="string">
  Идентификатор ссылки.
</ResponseField>

<ResponseField name="title" type="string">
  Что видит покупатель.
</ResponseField>

<ResponseField name="description" type="string">
  Что видит покупатель.
</ResponseField>

<ResponseField name="amount_mode" type="string">
  `fixed` | `open` | `range`.
</ResponseField>

<ResponseField name="currency" type="string">
  Валюта цены.
</ResponseField>

<ResponseField name="amount_fixed" type="string">
  Сумма при `fixed`. Присутствует, только если задана.
</ResponseField>

<ResponseField name="amount_min" type="string">
  Границы суммы. Присутствуют только те, что заданы.
</ResponseField>

<ResponseField name="amount_max" type="string">
  Границы суммы. Присутствуют только те, что заданы.
</ResponseField>

<ResponseField name="pinned_currency" type="string">
  Закреплённые монета и сеть. Отсутствуют, если выбирает покупатель.
</ResponseField>

<ResponseField name="pinned_network" type="string">
  Закреплённые монета и сеть. Отсутствуют, если выбирает покупатель.
</ResponseField>

<ResponseField name="active" type="bool">
  Работает ли ссылка сейчас.
</ResponseField>

<ResponseField name="url" type="string">
  Публичный URL страницы оплаты.
</ResponseField>

<ResponseField name="expires_at" type="string">
  Момент истечения (ISO 8601). **Отсутствует у бессрочной ссылки.**
</ResponseField>

<ResponseField name="created_at" type="string">
  Время создания.
</ResponseField>

***

## POST /v1/payment/link/info — ссылка и её платежи

### Параметры запроса

<ParamField body="link_id" type="string" required>
  Идентификатор ссылки.
</ParamField>

<ParamField body="limit" type="int64">
  Пагинация списка платежей.
</ParamField>

<ParamField body="offset" type="int64">
  Смещение.
</ParamField>

<CodeGroup>
  ```python Python theme={null}
  call("/v1/payment/link/info", {"link_id": "5d3f2a71-9c84-4b0e-8d17-3e6a2c9f1b40"})
  ```

  ```js Node.js theme={null}
  await call("/v1/payment/link/info", { link_id: "5d3f2a71-9c84-4b0e-8d17-3e6a2c9f1b40" });
  ```
</CodeGroup>

### Пример ответа

Та же карточка ссылки, что в `/list`, плюс массив `payments` — все счета, порождённые этой ссылкой:

```json theme={null}
{
  "state": 0,
  "result": {
    "link_id": "5d3f2a71-9c84-4b0e-8d17-3e6a2c9f1b40",
    "title": "Поддержать проект",
    "amount_mode": "open",
    "currency": "USD",
    "active": true,
    "url": "https://pay.oblodai.com/link/5d3f2a71-9c84-4b0e-8d17-3e6a2c9f1b40",
    "created_at": "2026-07-13T12:00:00Z",
    "payments": [
      {
        "uuid": "8b1d7d2e-2b0a-4a1f-9c3e-1f2a3b4c5d6e",
        "status": "paid",
        "amount": "10.00",
        "currency": "USD",
        "created_at": "2026-07-13T12:31:00Z"
      }
    ]
  }
}
```

Полный объект каждого платежа берите через [`POST /v1/payment/info`](/reference/payment-info) по его `uuid`.

***

## POST /v1/payment/link/toggle — включить / выключить

Выключенная ссылка перестаёт открываться: публичные методы отдают `404 paylink.not_found`, новые
счета по ней не создаются. Уже созданные счета продолжают жить и оплачиваться.

### Параметры запроса

<ParamField body="link_id" type="string" required>
  Идентификатор ссылки.
</ParamField>

<ParamField body="active" type="bool" required>
  `false` — выключить, `true` — включить обратно.
</ParamField>

<CodeGroup>
  ```python Python theme={null}
  call("/v1/payment/link/toggle", {"link_id": "5d3f2a71-…", "active": False})
  ```

  ```js Node.js theme={null}
  await call("/v1/payment/link/toggle", { link_id: "5d3f2a71-…", active: false });
  ```
</CodeGroup>

### Пример ответа

```json theme={null}
{ "state": 0, "result": { "link_id": "5d3f2a71-9c84-4b0e-8d17-3e6a2c9f1b40", "active": false } }
```

***

## Коды ошибок

| Код                            | Значение                                               |
| ------------------------------ | ------------------------------------------------------ |
| `400 request.bad_json`         | Тело не парсится.                                      |
| `400 paylink.bad_id`           | `link_id` не является корректным UUID.                 |
| `404 paylink.not_found`        | Ссылка не найдена (или принадлежит другому мерчанту).  |
| `400 paylink.bad_mode`         | `amount_mode` не `fixed` / `open` / `range`.           |
| `400 paylink.unknown_currency` | Неизвестная `currency`.                                |
| `400 paylink.bad_amount`       | `amount_fixed` не положительное число (режим `fixed`). |
| `400 paylink.bad_min`          | `amount_min` не положительное число.                   |
| `400 paylink.bad_max`          | `amount_max` не положительное число.                   |
| `400 paylink.bad_range`        | `amount_min` больше `amount_max`.                      |
| `503 paylink.disabled`         | Платёжные ссылки недоступны на этом шлюзе.             |
| `401 auth.*`                   | Ошибки аутентификации.                                 |

Ошибки, которые возникают при оплате **покупателем** (`paylink.amount_required`, `paylink.below_min`,
`paylink.above_max`, `paylink.not_positive`), — на странице [публичных методов](/reference/link-public).

***

## Нюансы

* **Каждый checkout — новый счёт.** Ссылка — не счёт, а «фабрика счетов»: каждый checkout создаёт новый
  инвойс со своим адресом и своим сроком жизни.
* **Комиссия, скидки, минимумы, допуски — как у обычного счёта.** Платёж по ссылке проходит ровно
  тот же путь, что [`POST /v1/payment`](/reference/payment-create), и точно так же присылает
  [вебхуки](/reference/webhook-object).
* **Цена в фиате работает.** `currency` может быть любым из 23 поддерживаемых фиатов, а не только
  `USD` — см. [Форматы сумм и денег](/reference/basics-money).
* **`order_id` у платежей по ссылке нет** — вы его не задаёте (покупатель приходит без вашего
  контекста). Сопоставляйте платежи со ссылкой через `/link/info` — по `uuid` счёта из
  [вебхука](/reference/webhook-object).

***

## Связанные страницы

<CardGroup cols={2}>
  <Card title="GET /v1/link/{id} · POST /v1/link/{id}/checkout" href="/reference/link-public" icon="arrow-right" horizontal>
    публичная страница оплаты.
  </Card>

  <Card title="POST /v1/payment" href="/reference/payment-create" icon="arrow-right" horizontal />

  <Card title="Объект платежа" href="/reference/payment-object" icon="arrow-right" horizontal />

  <Card title="GET /v1/currencies" href="/reference/currencies" icon="arrow-right" horizontal>
    какие валюты цены и какие монеты доступны.
  </Card>

  <Card title="Форматы сумм и денег" href="/reference/basics-money" icon="arrow-right" horizontal />
</CardGroup>
