> ## Documentation Index
> Fetch the complete documentation index at: https://wallet-docs.iexexchanger.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Частые вопросы

> Подписи, время, идемпотентность, суммы, memo/TON, тестирование webhooks, IP-whitelist и ротация ключей

Подборка вопросов, на которых чаще всего спотыкаются интеграторы CMS обменника. Если ответа
нет — загляните в [Аутентификацию](/authentication), [Идемпотентность](/idempotency),
каталог [Ошибок](/errors) и [Лимиты запросов](/rate-limits).

## Подпись запросов

<AccordionGroup>
  <Accordion title="Постоянно получаю INVALID_SIGNATURE — что не так?" icon="signature">
    В 9 из 10 случаев подписаны не те байты тела. Подпись считается от **сырого тела** —
    ровно той строки, что уходит на сервер.

    * Сериализуйте JSON **один раз**, подпишите эту строку и отправьте именно её.
    * Не используйте библиотеку, которая повторно сериализует объект перед отправкой (другой
      порядок ключей или пробелы сломают подпись).
    * Сообщение для HMAC — это `{timestamp}.{raw_body}` (timestamp, точка, тело).
    * Ключ HMAC — `api_secret`, результат — **hex в нижнем регистре**.

    Эталонные сниппеты на Node.js, Python, PHP и cURL — на странице [Аутентификация](/authentication).
  </Accordion>

  <Accordion title="Как подписывать GET-запросы и запросы без тела?" icon="link-slash">
    Для GET/DELETE и любых запросов без тела `raw_body` — **пустая строка** (не `{}` и не `null`).
    Тогда сообщение для подписи получается вида `{timestamp}.` (timestamp, затем точка и ничего
    после неё).
  </Accordion>

  <Accordion title="Передаётся ли api_secret по сети?" icon="lock">
    Нет. `api_secret` участвует только в вычислении `X-Signature` на вашей стороне и **никогда**
    не отправляется в заголовках. Платформа хранит секрет в зашифрованном виде и проверяет
    подпись на сервере. Не используйте устаревший заголовок `X-Api-Secret`.
  </Accordion>
</AccordionGroup>

## Время и часы

<AccordionGroup>
  <Accordion title="Что означает TIMESTAMP_SKEW?" icon="clock">
    `X-Timestamp` вышел за пределы **±300 секунд** от времени сервера платформы. Обычно это
    рассинхронизация часов.

    * Включите синхронизацию по NTP на сервере обменника.
    * Берите `X-Timestamp` непосредственно перед отправкой запроса, а не заранее.
    * Время — в **секундах** Unix (не в миллисекундах).
  </Accordion>

  <Accordion title="В каких единицах X-Timestamp?" icon="hourglass">
    В целых секундах Unix-времени (например, `1782000000`). Распространённая ошибка — прислать
    миллисекунды; такой timestamp окажется далеко в будущем и вернёт `TIMESTAMP_SKEW`.
  </Accordion>
</AccordionGroup>

## Идемпотентность и дубликаты

<AccordionGroup>
  <Accordion title="Как не создать дубликат при сетевом сбое?" icon="copy">
    Присылайте на каждую write-операцию заголовок `X-Idempotency-Key: <uuid>`. Повтор того же
    запроса с тем же ключом и тем же телом вернёт первый результат — без дубликата и без `409`.
    Ключ хранится **24 часа** и изолирован в пределах вашего сайта.
  </Accordion>

  <Accordion title="В чём разница между order_id и X-Idempotency-Key?" icon="fingerprint">
    `order_id` — ваш бизнес-идентификатор заявки; по нему ресурс ищется позже через
    `GET .../by-order-id/{order_id}`. По умолчанию он строго уникален в рамках сайта — повтор
    вернёт `409 DUPLICATE_ORDER_ID`. `X-Idempotency-Key` — технический ключ безопасного повтора
    одного и того же HTTP-запроса. Используйте оба: `order_id` для связи с заявкой,
    `X-Idempotency-Key` для надёжных ретраев. Подробнее — [Идемпотентность](/idempotency).
  </Accordion>

  <Accordion title="Получаю IDEMPOTENCY_CONFLICT, хотя ключ новый — почему?" icon="triangle-exclamation">
    Этот код возвращается, когда тот же `X-Idempotency-Key` уже использовался, но с **другим
    телом** запроса. Сгенерируйте новый UUID для нового тела, либо повторяйте ровно то же тело,
    что и в первый раз.
  </Accordion>
</AccordionGroup>

## Суммы и числа

<AccordionGroup>
  <Accordion title="Почему суммы — строки, а не числа?" icon="money-bill">
    Деньги в API — всегда **строки** (`"100.50"`). Числа с плавающей точкой теряют точность
    (`0.1 + 0.2 !== 0.3`), что недопустимо для финансов. Передавайте и читайте суммы как строки;
    на своей стороне считайте через decimal-библиотеку, а не через `float`/`number`.
  </Accordion>

  <Accordion title="Что значит AMOUNT_TOO_MANY_DECIMALS?" icon="calculator">
    Сумма содержит больше знаков после запятой, чем поддерживает актив (`asset.decimals`).
    Например, USDT\_TRC20 — 6 знаков, BTC/LTC — 8. Округлите сумму до точности актива
    (значение `decimals` есть в `GET /v1/public/assets`).
  </Accordion>

  <Accordion title="Где взять минимальные суммы и точность актива?" icon="list">
    Из `GET /v1/public/assets`: поля `minDeposit`, `minPayout`, `decimals`. Не хардкодьте —
    набор активов и лимиты зависят от настроек инстанса.
  </Accordion>
</AccordionGroup>

## Сети, адреса и memo (TON)

<AccordionGroup>
  <Accordion title="Зачем для TON нужен memo/comment?" icon="hashtag">
    TON относится к **memo-based** архетипу: используется общий приёмный адрес, а конкретная
    заявка идентифицируется уникальным memo (comment). При создании депозита в TON платформа
    выдаёт пару «адрес + memo» — **плательщик обязан указать memo**, иначе платёж невозможно
    привязать к заявке. Передавайте memo пользователю вместе с адресом и не теряйте его.
  </Accordion>

  <Accordion title="Получаю INVALID_ADDRESS / INVALID_MEMO — что проверить?" icon="map-pin">
    Адрес и memo проверяются по правилам конкретной сети. Убедитесь, что адрес соответствует
    выбранной сети (`code` из `GET /v1/public/networks`), а memo — формату memo-based сети.
    Не подставляйте адрес одной сети в операцию другой сети.
  </Accordion>

  <Accordion title="Как узнать, какие сети и активы включены?" icon="network-wired">
    `GET /v1/public/networks` — список включённых сетей с архетипом и числом подтверждений;
    `GET /v1/public/assets` — активы с привязкой к сети, точностью и лимитами. Эти справочники
    меняются редко — кэшируйте их.
  </Accordion>
</AccordionGroup>

## Webhooks, тестирование и polling

<AccordionGroup>
  <Accordion title="Как протестировать приём webhooks?" icon="paper-plane">
    Используйте `POST /v1/public/webhooks/test` — платформа поставит в очередь тестовый webhook
    (`X-Event-Type: webhook.test`) на ваш `callback_url` с настоящей подписью. Так вы проверите,
    что endpoint доступен и корректно валидирует `X-Signature`, ещё до первой реальной операции.
    Переотправить уже сгенерированное событие можно через `POST /v1/public/webhooks/resend/{event_id}`
    (по `X-Event-Id`).
  </Accordion>

  <Accordion title="Webhooks или polling — что использовать?" icon="bell">
    Основной механизм — **webhooks**: изменения статуса доставляются мгновенно. Polling
    (`GET .../{uuid}` или `.../by-order-id/{order_id}`) держите как редкий запасной механизм
    на случай пропущенного webhook — не чаще раза в несколько секунд, иначе упрётесь в
    [лимиты запросов](/rate-limits).
  </Accordion>

  <Accordion title="Как проверять подпись входящего webhook?" icon="shield-check">
    Webhook приходит с заголовками `X-Signature`, `X-Timestamp`, `X-Event-Type`, `X-Event-Id`.
    Подпись — `HMAC-SHA256` от сырого тела webhook с вашим `callback_secret`. Сверяйте её и
    используйте `X-Event-Id` для идемпотентной обработки на своей стороне. Детали — на странице
    [Webhooks](/webhooks/overview).
  </Accordion>
</AccordionGroup>

## Доступ: IP-whitelist и ключи

<AccordionGroup>
  <Accordion title="Есть ли отдельная sandbox/тестовая среда?" icon="vial">
    Отдельного публичного sandbox нет: WalletCore — это **отдельный инстанс на каждого клиента**
    (свой сервер, свои ключи, своя БД). Тестирование выполняется на вашем инстансе — оператор
    может включить нужные сети/активы и помочь с тестовыми параметрами. Для проверки доставки
    уведомлений используйте `POST /v1/public/webhooks/test`.
  </Accordion>

  <Accordion title="Получаю IP_NOT_WHITELISTED" icon="ban">
    Для сайта задан белый список IP, и запрос пришёл не с разрешённого адреса. Добавьте
    **исходящий** IP сервера обменника в whitelist в личном кабинете. Учтите прокси/NAT: в
    whitelist должен попасть реальный внешний IP, с которого уходит запрос.
  </Accordion>

  <Accordion title="Как ротировать API-ключ без простоя?" icon="rotate">
    Выпустите новый ключ в личном кабинете, переключите интеграцию на новую пару
    `api_id` / `api_secret`, убедитесь, что запросы проходят, и только потом отзовите старый
    ключ. `api_secret` показывается **один раз** при создании — сохраните его сразу в надёжном
    месте. Запросы старым отозванным ключом получат `API_KEY_REVOKED`.
  </Accordion>

  <Accordion title="Что делать, если api_secret скомпрометирован?" icon="key">
    Немедленно отзовите ключ в личном кабинете и выпустите новый. Поскольку подпись зависит от
    секрета, отзыв ключа делает любые ранее перехваченные запросы невалидными для новых вызовов.
  </Accordion>
</AccordionGroup>

## Общее

<AccordionGroup>
  <Accordion title="На что ориентироваться при обработке ошибок?" icon="bug">
    Только на `error.code` — он стабилен. `error.message` предназначен для людей и может меняться.
    Полный каталог кодов с рекомендациями по устранению — на странице [Ошибки](/errors).
  </Accordion>

  <Accordion title="Что такое traceId в ответе и зачем он нужен?" icon="magnifying-glass">
    `error.traceId` — идентификатор запроса в логах инстанса. При обращении в поддержку укажите
    его: по `traceId` оператор быстро найдёт конкретный запрос. Для `5xx` это основной способ
    диагностики, так как внутренний `message` в production скрыт.
  </Accordion>

  <Accordion title="Базовый URL — какой он?" icon="globe">
    У каждого клиента свой инстанс, поэтому base URL выдаётся при подключении (например,
    `https://wallet.your-exchange.com`). Все эндпоинты живут под `/v1/public/*`. Подробнее —
    [Окружения и справочники](/environments).
  </Accordion>
</AccordionGroup>

<Note>
  Связанные страницы: [Аутентификация](/authentication), [Идемпотентность](/idempotency),
  [Ошибки](/errors), [Лимиты запросов](/rate-limits), [Webhooks](/webhooks/overview).
</Note>
