API

API для криптоплатежей: справочник для разработчиков

Практический справочник по API платежей Qvard: аутентификация, создание платежа, redirectUrl, статусы, webhook, проверка доступности способа и выплаты, с ошибками и тем, чего пока нет.

API Qvard намеренно небольшой. Три маршрута покрывают весь цикл: создать платёж, проверить, что способ оплаты доступен, и отправить выплату. Справочник описывает каждый из них так, как он работает сегодня, с ошибками, которые вам встретятся, и честно говорит, чего в API нет, чтобы вы не строили интеграцию на несуществующей возможности.

Что покрывает API

Публичное API находится по адресу https://api.qvard.com/api/v1 и содержит три маршрута:

  • POST /payment: создать платёж и получить адрес страницы оплаты.
  • GET /method/:id/info: проверить, готов ли способ оплаты из вашего проекта принимать платежи.
  • POST /payout: отправить выплату на криптоадрес.

Результаты приходят по webhook: Qvard вызывает адрес, сохранённый в вашем проекте, когда платёж завершён. Маршрута для чтения платежа по его id нет, поэтому итог вы узнаёте из webhook. Всё остальное, такое как кабинет, балансы и настройки, делается в веб-интерфейсе.

Аутентификация

Каждый запрос несёт API-ключ вашего проекта в заголовке x-api-key. Токенов для обновления и OAuth нет. Отсутствующий или неизвестный ключ даёт 401 с сообщением error.wrong.api.key.

Относитесь к ключу как к паролю: держите его на сервере, в переменной окружения или хранилище секретов, но не во фронтенд-коде и не в публичном репозитории. Этот же ключ Qvard присылает вам в заголовке x-api-key webhook, поэтому утечка затрагивает оба направления.

Создание платежа

POST /api/v1/payment принимает JSON:

  • id (строка, обязательно): ваш идентификатор заказа или счёта. Он вернётся в webhook.
  • price (число, обязательно): сумма в долларах США. Клиент платит эквивалент в выбранном активе и сети.
  • paymentSystemId (число, необязательно): способ оплаты из вашего проекта. Если передать его, страница оплаты откроется с этим активом и сетью.

Ответ 201 с двумя полями: id, идентификатор платежа на стороне Qvard, и redirectUrl, адрес страницы оплаты вида https://my.qvard.com/pay/<id>. Перенаправьте клиента туда или вставьте ссылку в письмо.

Вызов идемпотентен по id и способу оплаты: повторная отправка того же id для того же способа возвращает уже созданный платёж, а не второй, поэтому повторять после таймаута безопасно. Обратите внимание: код ответа 201, а не 200.

curlcreate-payment.sh
curl -X POST https://api.qvard.com/api/v1/payment \
  -H "x-api-key: $QVARD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "id": "order-1042", "price": 49.9 }'

# 201 Created
# { "id": "6f1c2d3e-...", "redirectUrl": "https://my.qvard.com/pay/6f1c2d3e-..." }

# 401 { "message": "error.wrong.api.key" }
# 400 { "message": "Error validation", "errors": { "price": "..." } }

Ошибки

У ошибок одна форма, JSON с полем message:

  • 400: тело не прошло проверку. Сообщение Error validation, а объект errors сопоставляет каждому полю первую проблему, например пропущенный id или price, не являющийся числом. Сумма ниже минимума для выбранного способа отклоняется так же.
  • 401: заголовок x-api-key отсутствует или неизвестен (error.wrong.api.key).
  • 404: на маршруте информации о способе, несуществующий id способа (error.notfound).

Логируйте тело ответа целиком при 4xx: сообщение называет поле, которое нужно исправить. Не повторяйте 400 и 401, ничего не изменив, но повторяйте после таймаута или 5xx, что безопасно благодаря идемпотентности выше.

Статусы платежа и webhook

У платежа один из четырёх статусов: wait (создан, не оплачен), partial (пришло меньше полной суммы), completed (пришла вся сумма) и rejected.

Webhook отправляется, когда платёж завершён: Qvard делает POST на callback URL вашего проекта с небольшим JSON, где ваш id и status, а ваш API-ключ кладёт в заголовок x-api-key. Ваша точка должна ответить ровно HTTP 200; любой другой статус, таймаут или редирект считаются неудачной доставкой и повторяются, всего пять попыток примерно за шесть минут. Заголовок это заголовок аутентификации, а не криптографическая подпись, поэтому сравнивайте его с ключом за постоянное время. Делайте обработчик идемпотентным, потому что доставка может прийти дважды.

Подробности с кодом в материале как защитить webhook криптоплатежей, а весь процесс разобран в как принимать криптоплатежи на сайте.

Проверка готовности способа

GET /api/v1/method/:id/info принимает числовой id способа оплаты из вашего проекта и отвечает 200 с тремя полями:

  • server: сведения о состоянии способа.
  • isReady: true, когда способ готов принять платёж.
  • isActive: true, когда способ не отключён, даже если он ещё догоняет сеть.

Используйте его перед тем, как предлагать на чекауте конкретный актив и сеть, например чтобы скрыть временно недоступный способ. Неизвестный id возвращает 404. Это необязательный шаг: если клиент выбирает на странице оплаты, он вам не нужен.

Выплаты

POST /api/v1/payout отправляет средства с вашего баланса на криптоадрес. В JSON:

  • id (строка, обязательно): ваш идентификатор выплаты, он используется для устранения дублей при повторах, поэтому отправка того же id дважды не платит дважды.
  • price (число, обязательно): сумма в криптовалюте способа, а не в долларах.
  • methodId (число, обязательно): способ оплаты из вашего проекта.
  • address (строка, обязательно): адрес назначения.
  • comment (строка, необязательно).

Успешный вызов возвращает 201. Выплаты двигают реальные деньги, поэтому проверяйте на небольшой сумме, дважды сверяйте адрес и сеть способа и уточните у Qvard, что выплаты через API включены для вашего проекта. Вывода на банковский счёт в фиате нет; выплата идёт на криптоадрес и стоит только сетевую комиссию.

Чего в API пока нет

Чтобы вы не искали лишнего:

  • Нет маршрута для получения платежа по id, поэтому опирайтесь на webhook и собственные записи.
  • Нет подписи webhook; аутентификация это заголовок x-api-key.
  • Нет sandbox: отдельная тестовая среда в планах, поэтому берите небольшие реальные суммы. Демо-счёт показывает страницу оплаты без платежа.
  • Нет возврата по ссылке после оплаты: клиент возвращается на сайт сам.
  • Нет готовых плагинов для платформ магазинов, а платёжные ссылки в разработке.

Форматы и примеры в документации для разработчиков. Коммерческие условия на странице тарифов.

FAQ

В какой валюте задавать цену?

В долларах США. Клиент платит эквивалент в выбранном на странице оплаты активе и сети по курсу, зафиксированному на один час. Исключение выплата: её сумма в криптовалюте способа.

Безопасно ли повторять создание платежа?

Да. Отправка того же id для того же способа оплаты возвращает уже созданный платёж, поэтому повтор после таймаута не создаёт дубль.

Как узнать итог платежа?

Из webhook, который отправляется, когда платёж завершён. Маршрута чтения платежа по id нет, поэтому сохраняйте отправленный id и сопоставляйте его при получении webhook.

Есть ли sandbox?

Пока нет. Отдельная тестовая среда в планах. Сейчас берите небольшие реальные суммы, а страницу оплаты смотрите на демо-счёте.

Похожие статьи

Похожие статьи