# Чек-лист перед продом

Пройдите его, прежде чем принимать реальные платежи. Каждый пункт закрывает известный способ потерять деньги. Порядок работ по интеграции — в [интеграции под ключ](https://stons.io/ru/docs/ai-integration.md).

## Ключи и доступ

- [ ] Ключ API хранится в менеджере секретов и используется только на сервере. Его нет в браузере, мобильном приложении, репозитории и логах.
- [ ] Секрет вебхуков хранится так же и отдельно от ключа API. Тот же секрет подписывает вебхуки и редиректы со страницы оплаты.
- [ ] Продукт обращается к API только по `https://`: по `http://` ключ ушёл бы открытым текстом ещё до перенаправления — см. [аутентификацию](https://stons.io/ru/docs/authentication.md#сеть).
- [ ] Адрес вебхуков в настройках проекта начинается с `https://`: кабинет принимает и `http://`, но тогда события идут открытым текстом.

## Вебхуки

- [ ] Подпись проверяется по сырому телу запроса, до разбора JSON — см. [подпись](https://stons.io/ru/docs/webhooks.md#подпись).
- [ ] Подписи сравниваются за постоянное время.
- [ ] Вебхуки с `X-Timestamp`, отличающимся от текущего времени больше чем на 5 минут, отклоняются.
- [ ] Решение отдать товар принимается по ответу API — `GET /v1/invoices/{id}`, — а не по телу вебхука.
- [ ] Пополнение `per_user` зачисляется пользователю только после того, как `GET /v1/deposits/{tx_hash}` показал его перевод со `status` = `confirmed` и `credited` = `true`, — см. [проверку перевода](https://stons.io/ru/docs/addresses.md#проверить-перевод).
- [ ] Дубли отбрасываются по `id` события, и повторная доставка того же события не приводит к повторной выдаче товара.
- [ ] Обработчик не зависит от порядка событий: `invoice.confirmed` может прийти раньше `invoice.seen`.
- [ ] Обработчик отвечает `2xx` за 10 секунд, в том числе на типы событий, которые не обрабатывает, а тяжёлую работу выполняет асинхронно — см. [доставку](https://stons.io/ru/docs/webhooks.md#доставка).

## Платежи

- [ ] Товар отдаётся, только когда статус инвойса `confirmed` или `settled`, — не при `seen` и не при первом появлении транзакции, см. [статусы](https://stons.io/ru/docs/invoices.md#статусы).
- [ ] Продукт определил, что делает при `underpaid`, при `paid_late` и при переплате — `confirmed` с `amount_received` больше `amount_expected`.
- [ ] При `partially_paid` товар не отдаётся. Если продукт показывает оплату сам, покупатель видит `amount_remaining` и тот же адрес, см. [частичную оплату](https://stons.io/ru/docs/invoices.md#частичная-оплата).
- [ ] Суммы обрабатываются как строки или целые числа в минимальных единицах, никогда как числа с плавающей точкой.
- [ ] Число знаков после запятой берётся для конкретного актива и не зашивается в код: у USDT в BNB Chain их 18, а не 6. Сумма в ответе API содержит после точки ровно столько цифр, сколько знаков у её актива.
- [ ] Продукт сверяет свою цену с `amount_requested`, а у покупателя просит `amount_expected` — см. [комиссии](https://stons.io/ru/docs/invoices.md#комиссии).
- [ ] Каждый заказ создаёт инвойс со своим `order_id`, а повтор запроса после таймаута использует тот же `order_id` с теми же полями.

## Отображение

- [ ] Адрес показывается пользователю целиком, без сокращений, вместе с сетью и активом — см. [показ адреса](https://stons.io/ru/docs/addresses.md#показ-адреса).
- [ ] Пользователь предупреждён, что перевод в другой сети или другого токена не зачисляется автоматически.
- [ ] Интеграция принимает несколько переводов в одной транзакции и отрицательный `log_index`, отличный от `-1`: платёж нативной монетой EVM-сети, который отправил смарт-контракт, например ETH или BNB со смарт-кошелька, мультиподписи или с вывода биржи, приходит с `-2`, `-3` и далее, — см. [что приходит на адрес](https://stons.io/ru/docs/addresses.md#что-приходит-на-адрес).
- [ ] Инвойс, созданный без `asset`, оплачивается только через `checkout_url`: пока покупатель не выбрал токен, адреса у него нет.

## Страница оплаты

- [ ] Если используется страница оплаты, адреса возврата и отмены заданы в настройках проекта: без них страница не вернёт покупателя — см. [адреса возврата](https://stons.io/ru/docs/checkout.md#адреса-возврата).
- [ ] Подпись редиректа и окно `ts` в 5 минут проверяются, а товар по редиректу не отдаётся — см. [подпись](https://stons.io/ru/docs/checkout.md#подпись).
- [ ] Переход на адрес отмены со `status=created`, `status=seen` или `status=partially_paid` не отменяет заказ: инвойс ещё можно оплатить.

## Выплаты

- [ ] Адреса для выплат заранее внесены в вайтлист: их вносит оператор, и новый адрес становится доступен только после задержки — по умолчанию через 24 часа.
- [ ] Адрес для выплаты берётся из вайтлиста и никогда — из истории транзакций.
- [ ] Каждая выплата создаётся со своим `reference`, а повтор использует тот же `reference`.
- [ ] `pending_review` обрабатывается как принятая выплата, которая ждёт человека, а не как ошибка, а исход берётся из `GET /v1/payouts/{id}`.

## Проверка

- [ ] Весь сценарий — создание инвойса, оплата, вебхук, проверка статуса через API и выдача товара — пройден на небольшой сумме до приёма реальных платежей.
