Приём USDT в сети TON за 5 минут
Пошаговая инструкция: создаём магазин, генерируем API-ключ, выставляем счёт через curl и подтверждаем оплату вебхуком.
- Опубликовано
- 27 авг. 2026 г.
- Время чтения
- 4 мин чтения
- Обновлено
- 12 сент. 2026 г.
Содержание
Эта инструкция проведёт вас от чистого аккаунта Paysell до рабочей интеграции: магазин, API-ключ, счёт, созданный через curl, оплата покупателем на готовой странице и вебхук, который помечает заказ оплаченным в вашей системе.
Шаг 1. Создайте магазин#
Зарегистрируйтесь и создайте магазин в кабинете. Магазин — это сущность, к которой привязаны API-ключи, счета и баланс; большинству мерчантов хватает одного магазина, но их можно создать несколько, если вы работаете под разными брендами.
Магазин может принимать платежи сразу. Фоновая проверка идёт параллельно с обычной работой, но затрагивает только вывод средств, а не входящие платежи, — поэтому тестировать можно сразу.
Важно: ключ боевой с первой минуты — отдельного тестового окружения нет, и это экономит время: вы сразу проверяете тот же путь, по которому пойдут настоящие заказы. Тестируйте небольшими реальными суммами: доли TON достаточно, чтобы увидеть весь процесс целиком.
Шаг 2. Создайте API-ключ#
В настройках магазина сгенерируйте API-ключ. Он показывается ровно один раз, поэтому сразу скопируйте его в менеджер секретов или .env-файл — повторно Paysell его не покажет. Ключи выглядят как sk_live_... и передаются в заголовке Authorization как bearer-токен.
Шаг 3. Создайте счёт через curl#
Каждый платёж начинается со счёта. Вот полный пример для счёта на 25 USDT:
curl -X POST https://paysell.me/api/merchant/v1/invoices \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"asset": "USDT_TON",
"amount": "25",
"order_id": "order-1042"
}'
Обратите внимание: amount — это строка, а не число, — так мы избегаем проблем с округлением при работе с числами с плавающей точкой. order_id — ваш собственный идентификатор; Paysell не требует конкретного формата, важна только уникальность, понятная вам самим.
Ответ выглядит так:
{
"invoice_id": "inv_8f3ka92ldk",
"payment_url": "https://paysell.me/pay/inv_8f3ka92ldk",
"address": "UQCabcdefghijklmnopqrstuvwxyz0123456789ABCD",
"asset": "USDT_TON",
"amount": "25",
"amount_minor": 25000000,
"status": "pending",
"expires_at": "2026-08-27T11:00:00Z"
}
amount_minor — сумма в минимальных единицах: у USDT 6 знаков после запятой, поэтому 25 USDT — это 25000000. У TON — 9 знаков. По умолчанию счёт действует 2 часа (этот срок можно настроить от 1 минуты до 24 часов); сократить или увеличить его можно параметром ttl_minutes.
Шаг 4. Откройте payment_url#
Отправьте покупателя на payment_url — страницу по адресу /pay/{invoice_id} — например, сразу после оформления заказа. На странице показан QR-код и deep link, который открывает Tonkeeper, MyTonWallet или другой TON-кошелёк с уже заполненными суммой и адресом, а также обратный отсчёт до истечения счёта.
Если покупатель отправит меньше указанной суммы, счёт перейдёт в статус underpaid и останется открытым ещё 24 часа, чтобы он мог доплатить. Если отправит больше — вся сумма зачислится вам, а счёт получит статус overpaid. Если он вообще отправит не тот актив, средства всё равно зачислятся на баланс, но исходный счёт останется открытым.
Шаг 5. Получите вебхук#
Когда платёж включён в мастерчейн TON плюс ещё три блока и сверен со вторым источником данных — примерно через минуту после оплаты — Paysell отправляет вебхук payment.credited (или payment.rejected, если что-то пошло не так) на указанный вами эндпоинт.
Каждый запрос вебхука содержит такие заголовки:
| Заголовок | Назначение |
|---|---|
X-Paysell-Event | Тип события, например payment.credited |
X-Paysell-Event-Id | Уникальный ID события — для защиты от дублей |
X-Paysell-Timestamp | Unix-время, когда запрос был подписан |
X-Paysell-Signature | HMAC-подпись в формате sha256=<hex> |
Всегда проверяйте подпись, прежде чем доверять телу вебхука. Минимальный пример на Node.js:
const crypto = require("crypto");
function verifyPaysellWebhook(rawBody, headers, secret) {
const timestamp = headers["x-paysell-timestamp"];
const signature = (headers["x-paysell-signature"] || "").replace("sha256=", "");
const age = Math.abs(Date.now() / 1000 - Number(timestamp));
if (age > 300) {
throw new Error("Timestamp too old — possible replay");
}
const expected = crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
const isValid = crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(signature, "hex")
);
if (!isValid) throw new Error("Invalid signature");
return true;
}
Используйте rawBody — тело запроса без парсинга — а не заново сериализованный JSON-объект, иначе подпись не совпадёт. Отклоняйте всё, что старше 300 секунд, и используйте X-Paysell-Event-Id, чтобы игнорировать дубли, если повтор придёт уже после того, как вы обработали событие.
Важно: если ваш эндпоинт недоступен или отвечает ошибкой, Paysell повторяет отправку с паузами: 1 минута, 5 минут, 15 минут, 1 час, 6 часов, затем 24 часа — после чего попытки прекращаются. Пропущенное событие всегда можно переотправить из кабинета.
Шаг 6. Пометьте заказ оплаченным#
В обработчике вебхука найдите заказ по order_id (или invoice_id), убедитесь, что сумма совпадает с ожидаемой — не забывайте, что суммы в теле вебхука указаны целыми числами в минимальных единицах, — и обновите статус заказа. Отвечайте кодом 2xx быстро; медленные операции (письма с подтверждением, обновление остатков) выполняйте уже после подтверждения получения вебхука.
Вот и весь процесс: создать магазин, сгенерировать ключ, выставить счёт, дать покупателю оплатить на готовой странице и обновить заказ по проверенному вебхуку. Все статусы счетов, эндпоинты списков и детали по каждому полю — в полной документации по API.
Начните принимать USDT и TON
Кабинет, ключ API и готовая страница оплаты — 0,2% с платежа, без абонентской платы.
Создать аккаунт