Подключение магазина
Базовый URL: https://pay.coolnik.ru. Версия API /v1. Сейчас доступна test-checkout 0.2.0, только тестовые проекты. Реальные переводы и выдачу оплаченных товаров на этом основании пока не включать.
Доступ
Владелец создаёт магазин в /admin или через локальную утилиту и передаёт project_id, секретный api_key и разрешённые payment_method_id защищённым способом. Для активаций и депозита создаются разные проекты даже при одном кошельке. API-ключ хранится только на сервере магазина. Ключ не передаётся клиентской оболочке GIZMO.
Запросы: Authorization: Bearer <api_key>. Все POST также требуют Idempotency-Key: 8–100 символов из букв, цифр, ._:-. Сохраняйте ключ операции до ответа; при таймауте повторяйте то же тело и тот же ключ. Другое тело с прежним ключом даст 409. Повтор возвращает первоначальный ответ; актуальный статус читается GET-запросом.
Создание счёта
POST /v1/invoices
Authorization: Bearer <api_key>
Idempotency-Key: order-123-attempt-1
Content-Type: application/json
{
"external_order_id": "order-123",
"attempt_no": 1,
"amount": "10.000000",
"payment_method_id": "usdt-nile"
}Ответ 201 содержит id, project_id, order_id, attempt, route, due, received, excess, reference, created_at, expires_at, cancelled_at, status, version. Суммы в ответе — атомарные целые строки, время — Unix milliseconds UTC. due: "10000000" означает 10 USDT. Поля сети, контракта и адреса берутся из настроек проекта и не принимаются от браузера.
Одна незавершённая попытка на заказ. После истечения/отмены следующая попытка имеет увеличенный attempt_no и новый ключ идемпотентности. Сохраняйте все попытки: старый своевременный перевод может подтвердиться позже.
Реализованные методы
| Метод | Назначение |
| GET /v1/payment-methods | Методы, разрешённые данному магазину |
| POST /v1/invoices | Создать тестовый счёт |
| GET /v1/invoices/{id} | Прочитать актуальный счёт своего магазина |
| POST /v1/invoices/{id}/cancel | Отменить неоплаченный счёт |
| POST /v1/invoices/{id}/checkout-sessions | Создать checkout_token и checkout_url для тестовой оплаты |
| GET /v1/events?after=0 | Получить до 100 событий после курсора |
| GET /health/live | Процесс работает |
| GET /health/ready | БД и журнал готовы для текущей стадии |
| GET /health/payments | 503, пока приём платежей не реализован полностью |
Checkout-сессия возвращает invoice_id, checkout_token, expires_at, checkout_url. Открывайте возвращённый URL; токен находится во фрагменте #. Он разрешает доступ только к этому счёту. В checkout реализован тестовый сценарий TronLink/Nile; кнопка подписи недоступна до настройки двух независимых RPC. После перезагрузки страницы повторно открывайте исходную ссылку — токен не сохраняется в браузере.
Подтверждение и выдача
Наблюдатель TRON Nile реализован; для живого запуска нужна независимая пара RPC. TON-наблюдатель и вебхуки находятся в плане. Уже существует журнал событий, который можно опрашивать сервером магазина. Ответ: { "events": [{ "cursor": "1", "payload": { "event_id": "...", "schema_version": 1, "environment": "test", "type": "invoice.paid", "invoice": { "...": "..." }, "occurred_at": 0 } }] }. Показанное invoice.paid — формат автоматически подтверждённого тестового события; публичного API для его искусственного создания нет.
Курсор хранить отдельно для каждого магазина как строку, без преобразования в JavaScript number. Обработку события, изменение заказа и сохранение курсора выполнять транзакционно. При ошибке повторить обработку. Уникальность event_id защищает от повторной доставки; уникальность результата по заказу защищает от разных оплаченных попыток. Сверяйте проект, заказ, среду, сеть, сумму и статус через авторизованный GET. Страница возврата браузера не является подтверждением.
Сейчас статусы: PENDING, PARTIALLY_PAID, PAID, EXPIRED, CANCELLED. События: invoice.partially_paid, invoice.paid, invoice.expired, invoice.cancelled. Событие создания не публикуется. Переводы по отменённым/несвоевременным счетам сохраняются для ручного разбора без PAID. Полный интерфейс разбора, возвраты, вебхуки и роли появятся позже. Ротация ключей уже доступна владельцу.
Рубли и GIZMO
Сервер магазина фиксирует рублёвую сумму, источник/момент курса и рассчитанную сумму USDT до создания счёта. UCPS получает только USDT. После подтверждения магазин один раз начисляет зафиксированный рублёвый депозит или выдаёт активацию. Округление USDT вверх делает магазин; курс задним числом не пересчитывается. Источник курса и конечные правила округления согласуются при интеграции GIZMO.
Ошибки
Формат { "error": "CODE" }. 401 — неверный доступ; 404 — счёт не найден в вашем проекте; 409 — конфликт операции/состояния; 422 — неверные параметры; 503 — функция или реальная сеть ещё не включена. Сетевые ошибки и 5xx повторять с задержкой и прежним ключом. 409/422 не повторять вслепую. OpenAPI описывает фактически опубликованные маршруты.
Кошельки проекта
При подключении проекта владелец задаёт wallets: ID кошелька, сеть и публичный адрес. Один адрес может использоваться в нескольких проектах. Способ оплаты routes ссылается на кошелёк через wallet_id; менять настройки может только владелец. При смене адреса новые счета используют новый кошелёк, прежние сохраняют реквизиты. Mainnet-адреса можно заранее сохранить, но mainnet-способы оплаты выключены в коде.
API владельца: GET/POST /v1/admin/projects, PUT /v1/admin/projects/{id}, POST /v1/admin/projects/{id}/rotate-key, POST /v1/admin/projects/{id}/test-invoice. Они требуют отдельного ключа владельца; ключ магазина не подходит. Схемы запросов описаны в OpenAPI.
В версии 0.2.1 владелец также видит очередь проверки и состояние RPC в кабинете. GET /v1/admin/observer возвращает состояние без секретных URL; PUT по тому же пути сохраняет общие интервалы (активный 30–300 секунд, простой от активного до 3600 секунд) с Idempotency-Key. POST /v1/admin/observer/diagnostics запускает чтение genesis/solidified-блоков, возвращает 202; результат доступен через GET. Диагностика не подтверждает платёж и не заменяет наблюдение транзакции. API магазина не имеет доступа к этим операциям.
Публичный checkout читает GET /v1/checkout с Bearer checkout_token и создаёт TRON-инструкцию POST /v1/checkout/tron-instruction с телом { "sender": "<адрес>" }. Для подготовки инструкции отдельный Idempotency-Key не требуется: сервер выдаёт ранее связанную инструкцию для того же счёта/отправителя, пока она действует. Транзакционные доказательства и произвольный txID от браузера не принимаются.