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

# Тестирование интеграции

<Note>
  **У Oblodai нет отдельной песочницы (sandbox) и тестовых ключей.** API работает на боевом
  окружении. Это значит, что реальные платежи и выплаты двигают реальные средства. Тестировать
  интеграцию нужно осознанно — эта инструкция показывает, как проверить максимум логики **без** риска
  и без реальных переводов, а что придётся проверять малыми реальными суммами.
</Note>

***

## Что можно проверить без единого перевода

Часть флоу тестируется полностью бесплатно и безопасно:

| Что проверяем                                                                        | Чем                                                                                                        | Двигает деньги?       |
| ------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- | --------------------- |
| Подпись запроса работает                                                             | любой чтение‑эндпоинт, напр. [`/v1/balance`](/reference/balance)                                           | нет                   |
| Приёмник вебхуков: доставка, парсинг, ответ 2xx (подпись — только на боевом платеже) | [тестовые вебхуки](/reference/webhooks-test)                                                               | нет                   |
| Доступность методов приёма/выплат                                                    | [`/v1/payment/services`](/reference/payment-services), [`/v1/payout/services`](/reference/payout-services) | нет                   |
| Расчёт комиссии выплаты                                                              | [`/v1/payout/calculate`](/reference/payout-calculate)                                                      | нет                   |
| Курсы валют                                                                          | [`/v1/exchange-rate/list`](/reference/exchange-rate-list)                                                  | нет                   |
| Создание счёта и получение адреса                                                    | [`/v1/payment`](/reference/payment-create)                                                                 | нет (пока не оплачен) |
| Настройки (accuracy, autorefund, discount, accepted, fee‑config)                     | соответствующие `*/get`·`/set`                                                                             | нет                   |

**Создание счёта денег не двигает** — вы получаете адрес и все поля ответа, не оплачивая. Это уже
покрывает большую часть кода: сериализацию тела, подпись, разбор ответа, сохранение `uuid`.

***

<Steps>
  <Step title="Проверить подпись «вхолостую»" titleSize="h2">
    Самый первый тест — убедиться, что подпись собирается правильно. Достаточно любого чтения:

    <CodeGroup>
      ```python Python theme={null}
      print(call("/v1/balance", {}))
      # Успех → {"state": 0, "result": {...}}  — подпись верна
      # 401   → разбираемся: см. «Как подписать запрос»
      ```

      ```js Node.js theme={null}
      console.log(await call("/v1/balance", {}));
      // Успех → {"state": 0, "result": {...}}  — подпись верна
      // 401   → разбираемся: см. «Как подписать запрос»
      ```
    </CodeGroup>

    Если тут `401` — не идите дальше, чините подпись. → [Как подписать запрос](/guides/signing-requests)
  </Step>

  <Step title="Проверить приёмник вебхуков тестовыми событиями" titleSize="h2">
    Не дожидаясь реальной оплаты, отправьте пробное событие на свой URL:

    <CodeGroup>
      ```python Python theme={null}
      resp = call("/v1/test-webhook/payment", {
          "url_callback": "https://shop.example/oblodai/callback",
          "status": "paid",
          "currency": "USDT",
          "network": "tron",
      })
      print(resp["result"])   # {"result": true, "status_code": 200}
      ```

      ```js Node.js theme={null}
      const resp = await call("/v1/test-webhook/payment", {
        url_callback: "https://shop.example/oblodai/callback",
        status: "paid",
        currency: "USDT",
        network: "tron",
      });
      console.log(resp.result);   // {"result": true, "status_code": 200}
      ```
    </CodeGroup>

    `status_code` — то, чем ответил ваш обработчик. Нужен `200`.

    <Warning>
      **Пробные тела не подписаны** и содержат `"is_test": true`. Ваш код проверки подписи должен уметь
      их пропускать (или тестируйте подпись отдельно). Готовый дружелюбный к тестам обработчик — в
      [Отладке вебхуков](/guides/webhooks-debug).
    </Warning>

    Так проверяется весь путь доставки: доходит ли запрос, парсится ли тело, отвечаете ли `2xx`. Не
    проверяется только **реальная подпись** — её отработаете на первом боевом платеже.
  </Step>

  <Step title="Прогнать создание счёта" titleSize="h2">
    Создайте счёт и убедитесь, что разбираете ответ:

    <CodeGroup>
      ```python Python theme={null}
      inv = call("/v1/payment", {
          "amount": "1", "currency": "USD", "order_id": "test-001",
          "to_currency": "USDT", "network": "tron",
      })["result"]

      assert inv["address"]         # адрес выделен
      assert inv["payment_status"] == "check"
      print(inv["url"])             # ссылка на страницу оплаты — можно открыть глазами
      ```

      ```js Node.js theme={null}
      import assert from "node:assert";

      const inv = (await call("/v1/payment", {
        amount: "1", currency: "USD", order_id: "test-001",
        to_currency: "USDT", network: "tron",
      })).result;

      assert(inv.address);                     // адрес выделен
      assert(inv.payment_status === "check");
      console.log(inv.url);                    // ссылка на страницу оплаты — можно открыть глазами
      ```
    </CodeGroup>

    Проверьте **оба** механизма идемпотентности — они независимы, и сломаться может любой:

    1. **Заголовок `Idempotency-Key`.** Отправьте один и тот же запрос дважды с одним и тем же значением
       заголовка — второй ответ должен быть **идентичен** первому и прийти с заголовком
       `Idempotent-Replayed: true`. Так вы убеждаетесь, что ваш клиент действительно **не генерирует новый
       ключ на каждую попытку** (самая частая ошибка внедрения).
    2. **`order_id`.** Повторите создание счёта с тем же `order_id` — должен вернуться **тот же** счёт, а не
       создаться второй.

    → [Идемпотентность](/reference/basics-idempotency) ·
    [Устойчивый клиент](/guides/resilient-client#главный-принцип)
  </Step>

  <Step title="Что придётся проверить реальными малыми суммами" titleSize="h2">
    Оплату «живой» транзакцией, подтверждения сети, реальную подпись вебхука и выплату полностью
    проверить синтетикой нельзя. Делайте это **малыми суммами на дешёвой сети**:

    * **Выберите дешёвую сеть.** Tron (`tron`), Polygon (`polygon`), BSC (`bsc`) — низкие комиссии сети.
      Избегайте Ethereum и Bitcoin для тестов: дорого и есть минимальные суммы.
    * **Помните про минимум сети.** На дорогих сетях платёж ниже минимума вернёт `payment.below_minimum`.
      На дешёвых минимума обычно нет.
    * **Проверьте боевую подпись вебхука** именно на этом реальном платеже — это единственный способ
      убедиться, что алгоритм и секрет верны. → [Объект вебхука](/reference/webhook-object)
    * **Тест выплаты:** сначала [`/v1/payout/calculate`](/reference/payout-calculate) (денег не
      двигает — видите комиссию и итог), затем реальная выплата малой суммы на свой же адрес. Помните:
      выплаты по API‑ключу **необратимы** и уходят сразу.
    * **Тест возврата/автовозврата:** сделайте недоплату/переплату малой суммой и проверьте, что статусы
      (`wrong_amount`/`paid_over`) и автовозврат отрабатывают. → [Недоплата и переплата](/guides/under-overpayment)
  </Step>

  <Step title="Проверить незрелые средства" titleSize="h2">
    Отдельно протестируйте сценарий, который часто всплывает уже в проде: сразу после оплаты средства на
    балансе, но ещё **не выводимы** (maturity‑холд). Попробуйте вывести их сразу — должны получить
    `409 payout.funds_maturing`. Убедитесь, что ваш код это корректно обрабатывает и не считает ошибкой
    навсегда. → [`POST /v1/balance`](/reference/balance)
  </Step>
</Steps>

***

## Дисциплина боевого тестирования

Раз песочницы нет, заведите правила, чтобы боевые тесты не смешивались с настоящими заказами:

* **Префикс для тестовых `order_id`** (например `test-...`) — легко отфильтровать и не спутать с
  реальными заказами.
* **Отдельный тестовый адрес‑получатель** для выплат, который вы контролируете.
* **Минимально возможные суммы** и дешёвые сети.
* **Логируйте `public_id`, `uuid`, `order_id`** каждого теста — потом проще свести концы.
* **Не коммитьте ключи** — даже во временном тестовом скрипте.

***

## Чек‑лист тестирования

* Подпись запроса верна (любой чтение‑эндпоинт вернул `state: 0`).
* Идемпотентность (заголовок): повтор с тем же `Idempotency-Key` вернул тот же ответ и
  `Idempotent-Replayed: true`; клиент **не** генерирует новый ключ на каждую попытку.
* Идемпотентность (`order_id`): повтор создания счёта с тем же `order_id` вернул тот же счёт.
* Приёмник вебхуков принимает тестовое событие и отвечает `status_code: 200`.
* Обработчик пропускает `is_test`‑тела и проверяет подпись боевых.
* Реальная подпись вебхука проверена на одном малом платеже.
* `payout/calculate` возвращает ожидаемую комиссию.
* Малая реальная выплата на свой адрес прошла до статуса `paid`.
* `409 payout.funds_maturing` обрабатывается корректно — клиент **повторяет** выплату позже, а не
  считает её проваленной.
* Недоплата/переплата и автовозврат проверены малой суммой.

***

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

<CardGroup cols={2}>
  <Card title="Тестовые вебхуки" href="/reference/webhooks-test" icon="arrow-right" horizontal />

  <Card title="Отладка вебхуков" href="/guides/webhooks-debug" icon="arrow-right" horizontal />

  <Card title="Сквозной пример приложения" href="/guides/end-to-end-example" icon="arrow-right" horizontal />

  <Card title="Чек‑лист перед запуском" href="/guides/production-checklist" icon="arrow-right" horizontal />

  <Card title="FAQ и устранение неполадок" href="/guides/faq-troubleshooting" icon="arrow-right" horizontal />
</CardGroup>
