Интеграция API для приема криптоплатежей: счета, подписи и вебхуки
Практическое руководство для разработчика: один подписанный запрос для создания счёта, один webhook-эндпоинт для получения статуса и детали безопасности, которые делают интеграцию надёжной.

Интеграция API для приема криптоплатежей состоит из двух частей: серверного запроса, который создаёт счёт для каждого заказа и возвращает ссылку на страницу оплаты, и webhook-эндпоинта, который получает подписанные обновления статуса, когда платёж обнаружен и подтверждён в блокчейне. В mistKET обе части — это обычный HTTPS и JSON с подписью HMAC-SHA256, без всякого SDK.
В этом руководстве весь процесс разобран с примерами кода, а затем — детали безопасности и надёжности, которые отличают демо от продакшена.
Архитектура крипто платежного API на одной схеме
Любая интеграция API для приема криптовалюты следует одному и тому же циклу из пяти шагов:
- Заказ создан — ваш бэкенд вызывает
POST /api/v1/invoicesс суммой, валютой, ID заказа и callback URL. - Редирект — вы отправляете клиента на полученный
checkout_url. - Оплата — клиент выбирает сеть и платит на хостинговой странице; курс фиксируется на всё время жизни счёта.
- Вебхук — mistKET отправляет POST с
invoice.paid,invoice.confirmedили событием-исключением на ваш callback URL. - Исполнение — вы проверяете подпись, отмечаете заказ оплаченным и выполняете его.
API-ключ, API-секрет и секрет вебхука выдаются в панели мерчанта после одобрения аккаунта. Полная документация находится в панели в разделе API.
Шаг 1: подпишите и отправьте запрос на создание счёта
Каждый запрос к API содержит три заголовка. Подпись — это hex HMAC-SHA256 от строки {timestamp}.{raw body} с вашим API-секретом:
POST /api/v1/invoices
X-Api-Key: mp_live_…
X-Api-Timestamp: 1760000000
X-Api-Signature: hex(hmac_sha256("{ts}.{body}", secret))
{
"amount": "184.50",
"currency": "USD",
"order_id": "2041",
"callback_url": "https://yourstore.com/webhooks/mistket"
} Минимальная версия на PHP выглядит так:
$body = json_encode([
'amount' => '184.50', 'currency' => 'USD',
'order_id' => '2041',
'callback_url' => 'https://yourstore.com/webhooks/mistket',
]);
$ts = (string) time();
$sig = hash_hmac('sha256', $ts . '.' . $body, $apiSecret);
// send $body with X-Api-Key, X-Api-Timestamp, X-Api-Signature Подписывайте ровно те байты, которые отправляете. Повторная сериализация JSON после подписи (другие пробелы или порядок ключей) — причина ошибок подписи номер один.
Шаг 2: редирект на страницу оплаты
Успешный вызов возвращает 201 Created с UUID счёта, его статусом (new) и checkout_url. Сохраните UUID вместе с заказом и перенаправьте клиента. Хостинговая страница показывает точную сумму, QR-код, обратный отсчёт и статус в реальном времени и работает на мобильных. Клиент выбирает сеть там же — USDT в TRON, BNB Smart Chain, Ethereum или Arbitrum, а также TRX, BNB и ETH, — если только вы не зафиксировали сеть в API-запросе.
Помимо создания счетов, API позволяет получать их список, запрашивать отдельный счёт и отменять его, что полезно, когда корзина меняется или заказ брошен.
Шаг 3: приём и проверка вебхуков о криптоплатежах
Когда статус меняется, mistKET отправляет JSON на ваш callback URL со следующими заголовками:
| Заголовок | Назначение |
|---|---|
X-Mistket-Event | Название события, например invoice.confirmed |
X-Mistket-Timestamp | Unix-время, используемое в подписи |
X-Mistket-Signature | sha256= + HMAC-SHA256 от {timestamp}.{raw body} с секретом вебхука |
X-Mistket-Delivery | ID доставки, удобен для логирования |
Проверка на PHP:
$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_MISTKET_TIMESTAMP'] ?? '';
$got = $_SERVER['HTTP_X_MISTKET_SIGNATURE'] ?? '';
$exp = 'sha256=' . hash_hmac('sha256', $ts . '.' . $raw, $webhookSecret);
if (!hash_equals($exp, $got) || abs(time() - (int) $ts) > 300) {
http_response_code(401); exit;
}
$event = json_decode($raw, true); Используйте сравнение за постоянное время (hash_equals в PHP, hmac.compare_digest в Python, crypto.timingSafeEqual в Node.js) и отклоняйте устаревшие метки времени, чтобы блокировать повторные отправки. Подробнее о самом примитиве — в статье HMAC в Википедии.
Пример тела вебхука
Подтверждённый платёж приходит компактным JSON-документом. Чаще всего вам понадобятся событие, ID заказа, статус, а также ожидаемая и полученная суммы:
POST https://yourstore.com/webhooks/mistket
X-Mistket-Event: invoice.confirmed
X-Mistket-Signature: sha256=…
{ "event": "invoice.confirmed", "data": {
"order_id": "2041", "status": "confirmed",
"pay_amount": "184.5", "paid_amount": "184.5",
"pay_currency": "USDT", "network": "TRC20" } } Сохраняйте pay_currency и network вместе с заказом. Они пригодятся для бухгалтерии и для общения с поддержкой в будущем.
Проверка в Node.js и Python
Та же проверка на двух других популярных языках:
// Node.js (Express with express.raw for this route)
const exp = 'sha256=' + crypto.createHmac('sha256', secret)
.update(ts + '.' + rawBody).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(exp), Buffer.from(sig));
# Python
exp = 'sha256=' + hmac.new(secret.encode(), f'{ts}.{raw}'.encode(),
hashlib.sha256).hexdigest()
ok = hmac.compare_digest(exp, sig) В обоих случаях обязательно читайте сырое тело запроса. Многие фреймворки автоматически парсят JSON; после парсинга и повторной сериализации байты уже не совпадают с подписью.
Локальное тестирование
Вебхукам нужен публичный HTTPS URL, поэтому локальный ноутбук не может получать их напрямую. Два практичных варианта: заранее развернуть обработчик на staging-сервере или временно открыть локальный порт через туннелирующий инструмент. Создайте небольшие счета с callback на staging, затем изучите логи доставки в панели мерчанта, чтобы увидеть, что именно было отправлено и что ответил ваш сервер.
Постарайтесь во время тестирования хотя бы раз вызвать каждый тип события: paid, confirmed, underpaid и expired. Когда каждая ветка обработчика отработала на реальном вебхуке, в продакшене вас мало что удивит, а вы будете точно знать, как выглядят логи доставки, если что-то пойдёт не так.
Шаг 4: обработка каждого статуса
Тело вебхука содержит ID заказа, статус, ожидаемую сумму (pay_amount), полученную сумму (paid_amount), валюту и сеть. Сопоставьте каждому событию действие:
| Событие | Значение | Типичное действие |
|---|---|---|
invoice.paid | Перевод обнаружен, подтверждения в процессе | Показать «платёж получен, подтверждается» |
invoice.confirmed | Нужное число подтверждений достигнуто | Отметить оплаченным и выполнить заказ |
invoice.underpaid | Ниже вашего допуска | Ждать доплаты или связаться с клиентом |
invoice.overpaid | Больше ожидаемого | Выполнить заказ; решить, что делать с разницей |
invoice.expired | Нет валидного платежа вовремя | Освободить товар, оставить заказ неоплаченным |
Допуск недоплаты, частичные платежи, которые в сумме дают итог, и поздние платежи в пределах льготного окна обрабатывает mistKET; ваш код реагирует только на конечный результат.
Надёжность: повторы и идемпотентность
Если ваш эндпоинт недоступен или возвращает ошибку, вебхуки отправляются повторно с нарастающей задержкой в течение нескольких часов. Значит, иногда вы получите одно и то же событие дважды. Сделайте обработчик идемпотентным по ID заказа:
- Быстро отвечайте 2xx, а тяжёлую работу выполняйте в очереди.
- Перед исполнением проверяйте, не отмечен ли заказ уже оплаченным.
- Логируйте ID доставки и событие, чтобы отслеживать проблемы; в панели также есть логи доставки вебхуков.
Чек-лист безопасности
Интеграция API для приема криптоплатежей работает с деньгами, поэтому относитесь к ней как к любому другому платёжному коду:
- Храните API-секрет и секрет вебхука только на сервере — никогда во фронтенд-коде или мобильных приложениях.
- Ограничьте доступ к API списком разрешённых IP в панели.
- Отклоняйте запросы вне короткого окна по метке времени.
- Настройте срок действия счёта в соответствии с логикой резервирования товара.
- Храните суммы как строки или decimal, никогда как float.
Что дальше
Вот и вся интеграция API для приема криптоплатежей: один подписанный запрос, один проверенный вебхук и карта статусов. Тот же процесс с точки зрения не-разработчика описан в статье как принимать криптовалюту на сайте. Делаете бота, а не сайт? Читайте приём криптоплатежей в Telegram-боте. Запросите API-ключи, подав заявку через Telegram @mistnetwork, посмотрите пример в разделе для разработчиков и управляйте ключами через вход для мерчантов.


