Подключение магазина

Базовый 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/payments503, пока приём платежей не реализован полностью

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 от браузера не принимаются.

Скачать OpenAPI JSON