API Helmer
Принимайте USDT (BEP-20) на своём сайте. Ваш сервер создаёт платёж запросом к нашему API — мы выдаём адрес приёма, отслеживаем оплату в блокчейне и отправляем подписанный вебхук. Контракт совместим с Heleket: если у вас уже есть интеграция Heleket/Cryptomus — смена базового URL достаточно.
Базовый URL
https://hlm-3112d825.duskyr.com/v1
Аутентификация
Каждый запрос подписывается. В заголовках передаются merchant (ваш UUID мерчанта) и sign. Подпись считается от СЫРОГО тела запроса:
sign = md5( base64(тело_запроса) + api_key )
UUID мерчанта и API-ключ — в кабинете, раздел «API-ключи». Ключ секретный, не публикуйте его в клиентском коде.
Пример подписи (PHP)
$data = json_encode($payload);
$sign = md5(base64_encode($data) . $apiKey);
$headers = [
"merchant: " . $merchantUuid,
"sign: " . $sign,
"Content-Type: application/json",
];
Пример подписи (Python)
import base64, hashlib, json, httpx
body = json.dumps(payload).encode()
sign = hashlib.md5(base64.b64encode(body) + api_key.encode()).hexdigest()
httpx.post(f"{BASE}/v1/payment", content=body, headers={
"merchant": merchant_uuid,
"sign": sign,
"Content-Type": "application/json",
})
Формат ответа
Успешный ответ: state = 0 и объект/массив result. Все денежные суммы — строками (не числами с плавающей точкой).
{
"state": 0,
"result": { ... }
}
Ошибки
При ошибке: state = 1. Доменные ошибки содержат message, ошибки валидации — errors с полями.
{ "state": 1, "message": "Payment not found" }
{ "state": 1, "errors": { "date_from": ["validation.regex"] } }
Создать платёж
POST/v1/payment
Создаёт инвойс и возвращает адрес приёма + ссылку на страницу оплаты. Идемпотентно по order_id: повторный запрос с тем же order_id вернёт существующий инвойс.
Параметры
| Поле | Тип | Описание |
| amount* | string | Сумма в валюте currency |
| currency | string | USD/EUR/RUB (фиат) или USDT. По умолчанию USDT |
| order_id | string | Ваш ид заказа (для идемпотентности) |
| url_callback | string | URL для вебхука о статусе платежа |
| url_return | string | Куда вернуть покупателя с checkout |
| url_success | string | Куда вернуть после успешной оплаты |
| additional_data | string | Произвольная метка (вернём в вебхуке) |
Запрос
curl https://hlm-3112d825.duskyr.com/v1/payment \
-X POST \
-H "merchant: 8b03432e-385b-4670-8d06-064591096795" \
-H "sign: <md5-подпись>" \
-H "Content-Type: application/json" \
-d '{
"amount": "10.00",
"currency": "USD",
"order_id": "ORDER-1024",
"url_callback": "https://your.site/helmer/callback"
}'
Ответ
{
"state": 0,
"result": {
"uuid": "231",
"order_id": "ORDER-1024",
"amount": "10.00758575",
"payment_amount": "0.00000000",
"payer_currency": "USDT",
"network": "bsc",
"address": "0x6767d64FA781B73C19F837ee2373A6aaeecb217F",
"url": "https://hlm-3112d825.duskyr.com/pay/231",
"payment_status": "check",
"expired_at": 1689172103,
"created_at": 1689168503,
"is_final": false,
"merchant_amount": "10.00",
"currency": "USD",
"rate": "0.9992"
}
}
Статус платежа
POST/v1/payment/info
Возвращает текущий статус инвойса по uuid или order_id (одно из двух).
curl https://hlm-3112d825.duskyr.com/v1/payment/info \
-X POST -H "merchant: <uuid>" -H "sign: <sign>" \
-H "Content-Type: application/json" \
-d '{ "order_id": "ORDER-1024" }'
История платежей
POST/v1/payment/list
Список инвойсов с cursor-пагинацией. Опциональные фильтры date_from/date_to (формат YYYY-MM-DD HH:mm:ss). Для следующей страницы передайте ?cursor=nextCursor.
curl "https://hlm-3112d825.duskyr.com/v1/payment/list?cursor=<nextCursor>" \
-X POST -H "merchant: <uuid>" -H "sign: <sign>" \
-H "Content-Type: application/json" \
-d '{ "date_from": "2026-07-01 00:00:00" }'
{
"state": 0,
"result": {
"items": [ { "uuid": "231", "order_id": "ORDER-1024", "status": "paid", ... } ],
"paginate": {
"count": 15,
"hasPages": true,
"nextCursor": "eyJpZCI6MjE2fQ",
"previousCursor": null,
"perPage": 15
}
}
}
Список сервисов
POST/v1/payment/services
Доступные сети/валюты с лимитами и комиссией. Тело — пустой объект {}.
{
"state": 0,
"result": [
{
"network": "BSC",
"currency": "USDT",
"is_available": true,
"is_enabled": true,
"limit": { "min_amount": "0.50000000", "max_amount": "1000000.00000000" },
"commission": { "fee_amount": "0.00", "percent": "0.00" }
}
]
}
Статусы платежа
| Статус | Значение |
| check | Ждём оплату |
| confirm_check | Перевод увиден, ждём подтверждений сети |
| paid | Оплачено полностью |
| wrong_amount | Оплачено меньше суммы |
| cancel | Истёк срок инвойса |
Баланс
POST/v1/balance
Баланс мерчанта. Тело — пустой объект {}.
{
"state": 0,
"result": [
{ "balance": { "merchant": [ { "uuid": "<merchant-uuid>", "balance": "125.40000000", "currency_code": "USDT" } ], "user": [] } }
]
}
Курс валют
GET/v1/exchange-rate/{currency}/list
Текущий курс валюты к USD. Публичный метод (без подписи).
curl https://hlm-3112d825.duskyr.com/v1/exchange-rate/USDT/list
{
"state": 0,
"result": [ { "from": "USDT", "to": "USD", "course": "0.99920700" } ]
}
Формат вебхука
При смене статуса мы отправляем POST на url_callback (или на общий webhook-URL мерчанта). Тело — JSON с деталями платежа. Тип события дублируется в поле type и в заголовке X-Helmer-Event. Поле event_id (и заголовок X-Helmer-Event-Id) используйте для дедупликации — сеть ненадёжна, один вебхук может прийти несколько раз.
Заголовки
X-Helmer-Signature: sha256=2b0f...e4a1
X-Helmer-Timestamp: 1689172103
X-Helmer-Event: payment
X-Helmer-Event-Id: 8b03432e-2f4c-4b0e-9a1d-6f0e5c1b7a90
Content-Type: application/json
Тело
{
"type": "payment",
"event_id": "8b03432e-2f4c-4b0e-9a1d-6f0e5c1b7a90",
"uuid": "231",
"order_id": "ORDER-1024",
"amount": "10.00758575",
"payment_amount": "10.00758575",
"payment_amount_usd": "10.00",
"merchant_amount": "10.00758575",
"commission": "0",
"is_final": true,
"status": "paid",
"from": "0xPayerAddress...",
"txid": "0xTransactionHash...",
"network": "bsc",
"currency": "USD",
"payer_currency": "USDT",
"address": "0x6767d64FA781B73C19F837ee2373A6aaeecb217F",
"additional_data": null
}
Ваш сервер должен ответить 200 OK. При другом ответе/таймауте мы повторяем доставку по расписанию (0, 1, 5, 15, 60, 180, 360, 720 мин от события).
Проверка подписи (HMAC-SHA256)
Подпись вебхука — в заголовке X-Helmer-Signature в виде sha256=<hex>. Считается как HMAC-SHA256 по строке «timestamp.body» ключом webhook_secret (секрет вебхука из кабинета, раздел «Вебхуки»; ротация секрета реально меняет подпись). timestamp — в заголовке X-Helmer-Timestamp (unix-секунды).
signature = HMAC_SHA256( webhook_secret, timestamp + "." + raw_body )
Возьмите сырое тело запроса и заголовок X-Helmer-Timestamp, соберите строку «{timestamp}.{body}», посчитайте HMAC-SHA256 своим webhook_secret и сравните с подписью из заголовка (константное по времени сравнение). Отвергайте вебхуки, где X-Helmer-Timestamp старше ~5 минут (защита от replay).
Пример проверки (PHP)
$secret = getenv("HELMER_WEBHOOK_SECRET");
$body = file_get_contents("php://input");
$timestamp = $_SERVER["HTTP_X_HELMER_TIMESTAMP"] ?? "";
$header = $_SERVER["HTTP_X_HELMER_SIGNATURE"] ?? "";
$expected = hash_hmac("sha256", $timestamp . "." . $body, $secret);
$given = preg_replace("/^sha256=/", "", $header);
if (!hash_equals($expected, $given)) { http_response_code(400); exit; }
if (abs(time() - (int)$timestamp) > 300) { http_response_code(400); exit; }
http_response_code(200);
Пример проверки (Python)
import hashlib, hmac, time
def verify(headers, raw_body: bytes, secret: str) -> bool:
ts = headers.get("X-Helmer-Timestamp", "")
got = headers.get("X-Helmer-Signature", "").removeprefix("sha256=")
expected = hmac.new(
secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, got):
return False
return abs(int(time.time()) - int(ts)) <= 300
Тест вебхука
POST/v1/test-webhook/payment
Отправляет тестовый вебхук на указанный URL, чтобы вы проверили приём и валидацию подписи. В БД ничего не сохраняется. Если передать uuid/order_id — данные возьмутся из реального инвойса.
curl https://hlm-3112d825.duskyr.com/v1/test-webhook/payment \
-X POST -H "merchant: <uuid>" -H "sign: <sign>" \
-H "Content-Type: application/json" \
-d '{
"url_callback": "https://your.site/helmer/callback",
"currency": "USDT",
"network": "bsc",
"status": "paid"
}'
Повторная отправка вебхука
POST/v1/payment/resend
Повторно отправляет вебхук по финализированному инвойсу (paid / wrong_amount). Требуется, чтобы при создании был указан url_callback. Лимит — 10 пересылок на инвойс.
curl https://hlm-3112d825.duskyr.com/v1/payment/resend \
-X POST -H "merchant: <uuid>" -H "sign: <sign>" \
-H "Content-Type: application/json" \
-d '{ "order_id": "ORDER-1024" }'
Готовы подключиться?
Зарегистрируйтесь, получите ключ в кабинете и создайте первый платёж.
Получить API-ключ