Вход в кабинет

Как принимать USDT: что нужно со стороны инфраструктуры

USDT — самый популярный стейблкоин, но у него нет единственной сети. Один и тот же тикер выпущен сразу в нескольких блокчейнах, и с точки зрения инфраструктуры это разные токены с разными правилами проверки. Разберём, что нужно сервису, чтобы принимать USDT корректно, а не полагаться на удачу.

USDT — это несколько токенов с одним тикером

Самые распространённые варианты — USDT в сети TRON (стандарт TRC-20), в Ethereum (ERC-20) и в BNB Smart Chain (BEP-20). Встречаются и другие сети. Внешне для пользователя это один и тот же доллар, но технически — разные контракты на разных нодах, с разной адресацией и разными правилами газа. Адрес, выпущенный в одной сети, не имеет смысла в другой: одинаковый формат адреса ещё не значит совместимость.

У различий есть и практическое следствие для отправителя: чтобы вывести USDT из сети, нужна нативная монета этой же сети на оплату комиссии — TRX для TRC-20, ETH для ERC-20, BNB для BEP-20. Если клиент по ошибке отправил перевод не в ту сеть, у него часто просто не окажется монеты для оплаты комиссии на вывод, и без ручного вмешательства перевод зависает. Отсюда правило: сервис должен явно указывать сеть рядом с каждым адресом и не полагаться на то, что клиент сам разберётся.

Почему сеть нельзя определить по одному адресу

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

Как технически проверить входящий перевод

Для сетей с виртуальной машиной, совместимой с Ethereum, — самой Ethereum и BNB Smart Chain — перевод токена виден как событие Transfer в логах контракта; его можно получить методом eth_getLogs или подпиской на новые блоки.

TRON устроен иначе: вместо JSON-RPC там HTTP REST API с именованными путями. Баланс адреса по TRC-20 контракту обычно проверяют вызовом wallet/triggerconstantcontract, а не чтением логов. Пример такого запроса — на странице TRON API и на посвящённой именно USDT-TRC20 странице USDT TRC-20 API.

проверка перевода USDT-TRC20
# tron — имя ноды для примера, точное название — в личном кабинете
curl -X POST https://nodes-api.cryptosafe.pro/proxy/tron/wallet/triggerconstantcontract \
  -H "Authorization: <ваш-ключ>" \
  -H "Content-Type: application/json" \
  -d '{"owner_address":"<адрес-владельца>","contract_address":"<адрес-контракта-USDT>","function_selector":"balanceOf(address)","parameter":"<encoded-адрес>"}'

Важная деталь: HTTP-прокси не присылает уведомления сам — он только отвечает на запрос, который отправили вы. Значит, отслеживание входящих переводов строится на регулярном опросе ноды: сервис периодически проверяет баланс адреса или последние блоки и сравнивает результат с тем, что видел в прошлый раз. Частоту опроса каждый сервис подбирает сам, исходя из того, насколько быстро нужно замечать новые переводы.

Подтверждения перед тем, как считать перевод окончательным

Перевод, который только что появился в мемпуле или попал в последний блок, ещё может быть отменён при реорганизации цепочки. Поэтому перед тем, как зачислить сумму клиенту, сервис обычно ждёт несколько подтверждений — сколько именно, зависит от конкретной сети и её скорости финализации. Подробно про логику ожидания и реорганизации — в статье «Мониторинг транзакций».

Что показывать клиенту, пока перевод не подтверждён

Между «нода увидела перевод» и «перевод можно засчитать» проходит время, и это стоит явно отражать в интерфейсе, а не оставлять клиента в неведении. Обычно выделяют три состояния: перевод не найден (клиент ещё не отправил или сеть его не увидела), перевод найден, но подтверждений пока недостаточно, и перевод подтверждён окончательно. Явный статус снижает число обращений в поддержку с вопросом «а где мои деньги» — люди видят, что перевод уже замечен и просто ждёт финализации.

Что для этого нужно от доступа к ноде

С точки зрения интеграции всё сводится к обычному HTTP-запросу: нода определяется по имени в адресе, а ключ передаётся в заголовке Authorization без изменения тела запроса и без парсинга прокси. Ключ можно привязать к IP-адресам ваших серверов — тогда даже при утечке ключа запрос с чужого адреса не пройдёт. Если сервис работает сразу в нескольких сетях с USDT, для каждой из них используется свой путь — например, /proxy/tron или адрес, указанный на странице Ethereum RPC для ERC-20-варианта.

Если для вашего сервиса ещё не решён вопрос, поднимать ли собственную инфраструктуру или пользоваться готовым доступом, — этот выбор подробно разобран в статье о приватных и публичных RPC-нодах.

Нужен доступ к нодам для приёма USDT?

Напишите, в каких сетях работаете — откроем доступ в личный кабинет, вы выпустите ключ и подключите проверку переводов.

Вход в кабинет