> ## 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.

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

Платёжная ссылка — это постоянный URL, по которому кто угодно может вам заплатить. Вы создаёте её один
раз, дальше она работает сама: покупатель открывает ссылку, при необходимости вводит сумму, выбирает
монету и сеть, платит — и на вашем балансе появляются деньги.

<Tip>
  **Это единственный способ принимать платежи БЕЗ своего бэкенда.** Обычная интеграция требует сервера:
  каждый вызов API подписывается секретом, а секрет нельзя отдавать в браузер. У платёжной ссылки этой
  проблемы нет — страница оплаты живёт на стороне Oblodai и работает по **публичным** эндпоинтам, без
  вашего ключа. Поэтому ссылку можно повесить на кнопку в Tilda/Wix, отправить в мессенджере или
  положить в шапку профиля.
</Tip>

Справочник методов — [`POST /v1/payment/link`](/reference/payment-link) и
[публичные методы страницы оплаты](/reference/link-public).

***

## Когда это ваш инструмент

* **Сайт на конструкторе** (Tilda, Wix, Webflow) — сервера нет, писать код негде.
* **Донаты и чаевые** — сумму называет плательщик, а не вы.
* **Продажи в мессенджере/соцсетях** — сайта вообще нет, есть только диалог.
* **Разовый счёт клиенту** — выставить и отправить, не заводя интеграцию.

Если у вас есть бэкенд и вы хотите автоматически выдавать товар по факту оплаты — вам, скорее всего,
нужен обычный счёт: [Приём первого платежа](/guides/accept-first-payment). Ссылка и счёт не исключают друг
друга: ссылка при оплате **создаёт настоящий платёж**, с теми же статусами и теми же вебхуками.

***

## Шаг 1. Создать ссылку

<CodeGroup>
  ```python Python theme={null}
  link = call("/v1/payment/link", {
      "title": "Подписка Pro",
      "description": "Доступ на 30 дней",
      "amount_mode": "fixed",
      "currency": "USD",            # валюта ЦЕНЫ
      "amount_fixed": "10.00",
      "expires_in": 0,              # 0 = бессрочная
  })["result"]

  print(link["link_id"])            # для управления ссылкой
  print(link["url"])                # ЭТО и даёте покупателю
  ```

  ```js Node.js theme={null}
  const link = (await call("/v1/payment/link", {
    title: "Подписка Pro",
    description: "Доступ на 30 дней",
    amount_mode: "fixed",
    currency: "USD",            // валюта ЦЕНЫ
    amount_fixed: "10.00",
    expires_in: 0,              // 0 = бессрочная
  })).result;

  console.log(link.link_id);    // для управления ссылкой
  console.log(link.url);        // ЭТО и даёте покупателю
  ```
</CodeGroup>

Всё. `url` можно вешать на кнопку, отправлять в чат, печатать в QR‑коде.

***

## Шаг 2. Выбрать режим суммы

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

| `amount_mode` | Кто определяет сумму           | Обязательные поля           | Типичный сценарий      |
| ------------- | ------------------------------ | --------------------------- | ---------------------- |
| `fixed`       | **Вы**, заранее                | `amount_fixed`              | Товар, подписка        |
| `open`        | **Покупатель**                 | — (`amount_min` опционален) | Донаты, чаевые         |
| `range`       | **Покупатель**, в ваших рамках | `amount_min` + `amount_max` | Пополнение, предоплата |

### `fixed` — сумма зафиксирована

<CodeGroup>
  ```python Python theme={null}
  call("/v1/payment/link", {
      "title": "Курс по Python",
      "amount_mode": "fixed",
      "currency": "USD",
      "amount_fixed": "49.00",
      "expires_in": 0,
  })
  ```

  ```js Node.js theme={null}
  await call("/v1/payment/link", {
    title: "Курс по Python",
    amount_mode: "fixed",
    currency: "USD",
    amount_fixed: "49.00",
    expires_in: 0,
  });
  ```
</CodeGroup>

Покупатель сумму не вводит и не меняет — он видит 49 USD и платит их.

### `open` — сумму вводит покупатель (донаты)

<CodeGroup>
  ```python Python theme={null}
  call("/v1/payment/link", {
      "title": "Поддержать проект",
      "amount_mode": "open",
      "currency": "USD",
      "amount_min": "1.00",     # необязательный ПОЛ: меньше $1 не примем
      "expires_in": 0,
  })
  ```

  ```js Node.js theme={null}
  await call("/v1/payment/link", {
    title: "Поддержать проект",
    amount_mode: "open",
    currency: "USD",
    amount_min: "1.00",     // необязательный ПОЛ: меньше $1 не примем
    expires_in: 0,
  });
  ```
</CodeGroup>

Поле ввода суммы на странице оплаты пустое — сколько напишет плательщик, столько и заплатит. Верхней
границы нет. `amount_min` — не обязателен, но полезен: он отсекает копеечные платежи, которые целиком
съест комиссия сети.

### `range` — сумма в диапазоне

<CodeGroup>
  ```python Python theme={null}
  call("/v1/payment/link", {
      "title": "Пополнение баланса",
      "amount_mode": "range",
      "currency": "USD",
      "amount_min": "5.00",
      "amount_max": "1000.00",
      "expires_in": 0,
  })
  ```

  ```js Node.js theme={null}
  await call("/v1/payment/link", {
    title: "Пополнение баланса",
    amount_mode: "range",
    currency: "USD",
    amount_min: "5.00",
    amount_max: "1000.00",
    expires_in: 0,
  });
  ```
</CodeGroup>

Покупатель вводит сумму, но шлюз проверит её по границам: меньше `amount_min` → `paylink.below_min`,
больше `amount_max` → `paylink.above_max`.

### Валюта цены: не только доллары

`currency` — это **валюта ЦЕНЫ**, и она не обязана быть `USD`. Работает любой из 23 поддерживаемых
фиатов (EUR, GBP, RUB, UAH, PLN, CZK, TRY…) или монета (`USDT`, `BTC`). Не путайте с валютой
**расчёта** — тем, чем реально платят.

<CodeGroup>
  ```python Python theme={null}
  # Донат «от €5», бессрочный
  call("/v1/payment/link", {"title": "Поддержать проект", "amount_mode": "open",
                            "currency": "EUR", "amount_min": "5", "expires_in": 0})

  # Фиксированные 5000 ₽
  call("/v1/payment/link", {"title": "Консультация", "amount_mode": "fixed",
                            "currency": "RUB", "amount_fixed": "5000", "expires_in": 0})
  ```

  ```js Node.js theme={null}
  // Донат «от €5», бессрочный
  await call("/v1/payment/link", { title: "Поддержать проект", amount_mode: "open",
                                   currency: "EUR", amount_min: "5", expires_in: 0 });

  // Фиксированные 5000 ₽
  await call("/v1/payment/link", { title: "Консультация", amount_mode: "fixed",
                                   currency: "RUB", amount_fixed: "5000", expires_in: 0 });
  ```
</CodeGroup>

**Тенге, сом и сум не поддерживаются** — попытка вернёт `400 paylink.unknown_currency`. Полный список и
причина — [Три режима создания счёта](/guides/payment-modes#цену-можно-назначать-не-только-в-долларах).

<Warning>
  **Знаки после запятой у суммы, которую вводит покупатель, проверяются по валюте ЦЕНЫ.** В
  `open`/`range`‑ссылке с ценой в евро «5.99» пройдёт, а в ссылке с ценой в **иене** «500.50» будет
  отвергнуто: у `JPY` (и `KRW`) **нет дробной части**. Если вы рисуете свою форму ввода — не давайте
  вводить копейки там, где валюта их не имеет.
</Warning>

***

## Шаг 3. Решить, кто выбирает монету и сеть

Второе решение: **закреплять ли валюту расчёта**.

<CodeGroup>
  ```python Python theme={null}
  # Вариант А. Покупатель выбирает сам (pinned_* не заданы)
  call("/v1/payment/link", {
      "title": "Донат", "amount_mode": "open", "currency": "USD", "expires_in": 0,
  })
  # → на странице оплаты покупатель сам выбирает: USDT/tron, BTC/bitcoin, TRX/tron…

  # Вариант Б. Вы закрепили монету и сеть
  call("/v1/payment/link", {
      "title": "Подписка Pro", "amount_mode": "fixed",
      "currency": "USD", "amount_fixed": "10.00",
      "pinned_currency": "USDT",     # валюта расчёта
      "pinned_network": "tron",      # сеть
      "expires_in": 0,
  })
  # → выбора нет: платят USDT в сети Tron
  ```

  ```js Node.js theme={null}
  // Вариант А. Покупатель выбирает сам (pinned_* не заданы)
  await call("/v1/payment/link", {
    title: "Донат", amount_mode: "open", currency: "USD", expires_in: 0,
  });
  // → на странице оплаты покупатель сам выбирает: USDT/tron, BTC/bitcoin, TRX/tron…

  // Вариант Б. Вы закрепили монету и сеть
  await call("/v1/payment/link", {
    title: "Подписка Pro", amount_mode: "fixed",
    currency: "USD", amount_fixed: "10.00",
    pinned_currency: "USDT",     // валюта расчёта
    pinned_network: "tron",      // сеть
    expires_in: 0,
  });
  // → выбора нет: платят USDT в сети Tron
  ```
</CodeGroup>

Не закрепляйте без нужды — чем шире выбор, тем выше конверсия. Закрепление имеет смысл, если вы
сознательно принимаете только один актив (например, только USDT в дешёвой сети, чтобы не разбирать
зоопарк монет на балансе).

***

## Шаг 4. Срок жизни

<CodeGroup>
  ```python Python theme={null}
  "expires_in": 0        # БЕССРОЧНАЯ — работает, пока вы её не выключите
  "expires_in": 86400    # живёт сутки с момента создания (секунды)
  ```

  ```js Node.js theme={null}
  expires_in: 0        // БЕССРОЧНАЯ — работает, пока вы её не выключите
  expires_in: 86400    // живёт сутки с момента создания (секунды)
  ```
</CodeGroup>

* **Бессрочная (`0`)** — для донатов, кнопки «Оплатить» на сайте, ссылки в профиле. Такая ссылка
  принимает платежи многократно, от разных людей.
* **С TTL** — для разового счёта конкретному клиенту: выставили, дали срок, дальше ссылка протухает.

***

## Что происходит, когда покупатель платит

Страница оплаты работает по **публичным** эндпоинтам — без вашего API‑ключа:

```
1. Покупатель открывает url
        ↓  страница читает GET /v1/link/{id} — заголовок, описание, режим суммы
2. Вводит сумму (если режим open/range) и выбирает монету (если не закреплена)
        ↓
3. POST /v1/link/{id}/checkout → создаётся НАСТОЯЩИЙ платёж, возвращается его uuid
        ↓
4. Дальше всё как у обычного счёта: адрес, QR, подтверждения сети, статусы
        ↓
5. Оплачено → на балансе деньги; если у вас есть бэкенд — придёт вебхук invoice.paid
```

Ключевое: **`/v1/link/{id}/checkout` создаёт обычный платёж.** Одна ссылка порождает столько платежей,
сколько раз по ней заплатили. Никакой отдельной сущности «оплата ссылки» нет — есть привычные платежи,
которые вы видите в истории, по которым приходят вебхуки и с которых делаются возвраты.

→ [Публичные методы ссылки](/reference/link-public)

***

## Как узнать, что по ссылке заплатили

Способ зависит от того, есть ли у вас сервер.

**Есть бэкенд** — ловите вебхук `invoice.paid`, как для любого платежа.
→ [Настройка вебхуков](/guides/webhooks-setup)

**Нет бэкенда** — смотрите платежи по ссылке в кабинете или запрашивайте их:

<CodeGroup>
  ```python Python theme={null}
  info = call("/v1/payment/link/info", {
      "link_id": "lnk_…",
      "limit": 50, "offset": 0,
  })["result"]
  # в ответе — сама ссылка и список платежей, созданных по ней
  ```

  ```js Node.js theme={null}
  const info = (await call("/v1/payment/link/info", {
    link_id: "lnk_…",
    limit: 50, offset: 0,
  })).result;
  // в ответе — сама ссылка и список платежей, созданных по ней
  ```
</CodeGroup>

Хотите **чек покупателю на почту** — на странице оплаты есть поле email, и `checkout` принимает
`payer_email`. Чек уйдёт автоматически после оплаты. → [Счёт и чек на почту](/guides/email-invoices)

***

## Управление ссылками

<CodeGroup>
  ```python Python theme={null}
  # Список всех ссылок
  call("/v1/payment/link/list", {"limit": 50, "offset": 0})

  # Выключить ссылку (перестанет принимать платежи)
  call("/v1/payment/link/toggle", {"link_id": "lnk_…", "active": False})

  # Включить обратно
  call("/v1/payment/link/toggle", {"link_id": "lnk_…", "active": True})
  ```

  ```js Node.js theme={null}
  // Список всех ссылок
  await call("/v1/payment/link/list", { limit: 50, offset: 0 });

  // Выключить ссылку (перестанет принимать платежи)
  await call("/v1/payment/link/toggle", { link_id: "lnk_…", active: false });

  // Включить обратно
  await call("/v1/payment/link/toggle", { link_id: "lnk_…", active: true });
  ```
</CodeGroup>

Выключение **обратимо** и не трогает уже созданные по ссылке платежи — они живут своей жизнью. Это
основной способ «закрыть» бессрочную ссылку: удалять её не нужно.

***

## Ошибки

Ошибки создания (ваш вызов):

| Код                                   | Значение                                                                  |
| ------------------------------------- | ------------------------------------------------------------------------- |
| `paylink.bad_mode`                    | `amount_mode` не `fixed`/`open`/`range`.                                  |
| `paylink.bad_amount`                  | Некорректная сумма.                                                       |
| `paylink.not_positive`                | Сумма ≤ 0.                                                                |
| `paylink.bad_min` / `paylink.bad_max` | Некорректная нижняя/верхняя граница.                                      |
| `paylink.bad_range`                   | `amount_min` больше `amount_max`.                                         |
| `paylink.unknown_currency`            | Валюта не поддерживается. → [`GET /v1/currencies`](/reference/currencies) |
| `paylink.disabled`                    | Ссылки временно выключены (`503`) — повторите позже.                      |

Ошибки оплаты (их увидит покупатель на странице):

| Код                                    | Значение                                                    |
| -------------------------------------- | ----------------------------------------------------------- |
| `paylink.not_found` / `paylink.bad_id` | Ссылки нет, она выключена или истёк её срок (`expires_in`). |
| `paylink.amount_required`              | Режим `open`/`range`, а сумма не введена.                   |
| `paylink.below_min`                    | Сумма меньше `amount_min`.                                  |
| `paylink.above_max`                    | Сумма больше `amount_max`.                                  |

***

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

<CardGroup cols={2}>
  <Card title="POST /v1/payment/link · /list · /info · /toggle" href="/reference/payment-link" icon="arrow-right" horizontal />

  <Card title="GET /v1/link/{id} · POST /v1/link/{id}/checkout" href="/reference/link-public" icon="arrow-right" horizontal>
    публичные методы.
  </Card>

  <Card title="Регистрация и ключи" href="/guides/get-keys" icon="arrow-right" horizontal>
    что делать, если сервера нет.
  </Card>

  <Card title="Счёт и чек на почту" href="/guides/email-invoices" icon="arrow-right" horizontal>
    автоматический чек плательщику.
  </Card>

  <Card title="Три режима создания счёта" href="/guides/payment-modes" icon="arrow-right" horizontal>
    цена vs валюта расчёта.
  </Card>

  <Card title="Приём первого платежа" href="/guides/accept-first-payment" icon="arrow-right" horizontal>
    обычный счёт, когда бэкенд есть.
  </Card>
</CardGroup>
