Как настроить прием платежей в TON: TON Connect, Jetton, автоматизация

TON — не Ethereum с другим RPC. Асинхронная модель транзакций и древовидная структура сообщений ломают интуицию разработчика. Когда пользователь отправляет нативный TON на ваш адрес — это одна транзакция. Когда Jetton (USDT на TON) — цепочка из трёх: transfer → internal message → notification. Ошибк

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1450
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1308
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1003
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1269
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    717
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1008

TON — не Ethereum с другим RPC. Асинхронная модель транзакций и древовидная структура сообщений ломают интуицию разработчика. Когда пользователь отправляет нативный TON на ваш адрес — это одна транзакция. Когда Jetton (USDT на TON) — цепочка из трёх: transfer → internal message → notification. Ошибка в мониторинге ведёт к потерянным платежам и головной боли с возвратами.

Недавно к нам обратился проект с 5000 ежедневных Jetton-платежей. После аудита их системы мы выявили, что они не учитывали bounced-транзакции, и 2% платежей зачислялись ошибочно. Мы перестроили архитектуру на уникальные адреса и Gasless-релей, сократив потери до нуля. Мы настраиваем приём платежей под ключ: пишите, оценим проект и подберём оптимальную архитектуру за один день.

Как принимать нативный TON и Jetton

Нативный TON

Генерируем уникальный адрес или используем один адрес с comment (memo) для идентификации. Мониторинг через TON Center API или TonAPI:

import { TonClient } from '@ton/ton'; import { Address } from '@ton/core'; const client = new TonClient({ endpoint: 'https://toncenter.com/api/v2/jsonRPC', apiKey: process.env.TONCENTER_API_KEY, }); async function checkIncomingTransactions( address: string, lastLt: string // last known logical time ) { const addr = Address.parse(address); const transactions = await client.getTransactions(addr, { limit: 20, lt: lastLt, archival: false, }); for (const tx of transactions) { // Только входящие, не bounce if (tx.inMessage && tx.inMessage.info.type === 'internal') { const info = tx.inMessage.info; const value = info.value.coins; // в nanoTON const comment = tx.inMessage.body; // текстовый комментарий // Матчим комментарий с нашим payment ID console.log(`Received: ${value} nanoTON, comment: ${comment}`); } } } 

Важно: проверяем bounce флаг и bounced флаг. Bounced транзакция означает возврат — не засчитываем.

Jetton (USDT, USDC, NOT)

Jetton Transfer сложнее: пользователь отправляет сообщение своему JettonWallet, который шлёт внутреннее сообщение к контракту получателя, а тот — transfer_notification на адрес получателя. В forward_ton_amount закладываем сумму для уведомления, в forward_payload — payment ID:

transfer_notification#7362d09c query_id: uint64 amount: coins // количество Jetton sender: MsgAddress // адрес отправителя forward_payload: ^Cell // наш custom payload (payment ID) 

Мониторим не основной адрес, а JettonWallet нашего адреса:

// Получаем адрес нашего JettonWallet для USDT async function getJettonWalletAddress( ownerAddress: string, jettonMasterAddress: string ): Promise<string> { const master = client.open( JettonMaster.create(Address.parse(jettonMasterAddress)) ); const walletAddr = await master.getWalletAddress( Address.parse(ownerAddress) ); return walletAddr.toString(); } // USDT на TON mainnet const USDT_MASTER = 'EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'; 

Что выбрать: уникальные адреса или comment?

Характеристика Комментарий (memo) Уникальный адрес
Сложность реализации Низкая Средняя (HD wallet)
Ошибки пользователя 1-3% забывают комментарий 0%
Сводка средств Не требуется Требуется sweep
Мониторинг Один адрес Много адресов
Рекомендация До 100 платежей/день От 1000 платежей/день

Comment/Memo идентификация

Один адрес, пользователь указывает comment (payment ID). Просто, но требует UX — объяснить необходимость комментария. Ошибка = потерянный платёж (нужен manual reconciliation).

Уникальный адрес на каждый платёж

Генерируем HD wallet (BIP39 + нестандартная деривация). Каждый заказ — отдельный адрес. Никаких комментариев, нет ошибок, простой мониторинг:

import { mnemonicToPrivateKey } from '@ton/crypto'; import { WalletContractV4 } from '@ton/ton'; async function derivePaymentAddress( masterMnemonic: string[], orderIndex: number ): Promise<string> { const keyPair = await mnemonicToPrivateKey(masterMnemonic); const wallet = WalletContractV4.create({ publicKey: keyPair.publicKey, workchain: 0, walletId: 698983191 + orderIndex, // уникальный subwalletId }); return wallet.address.toString({ bounceable: false }); } 

Минус: нужно сводить средства на основной адрес (sweep).

Polling или Webhook?

Метод Задержка Нагрузка Сложность
Polling (TON Center) ~5-30 сек Средняя Низкая
Webhook (TON Center) ~1-2 сек Низкая Средняя
WebSocket (TonAPI) ~0.5 сек Низкая Высокая
Собственная нода ~0 сек Очень высокая Очень высокая

Для продакшена — TonAPI + WebSocket, с fallback через polling. Self-hosted нода оправдана при миллионах транзакций в день.

Gasless и bounce: частые проблемы

Gasless

Gasless позволяет пользователю платить без баланса TON для комиссии. Это критично для Jetton-платежей: чтобы отправить USDT, нужен TON на газ. Сервис покрывает комиссию через релей. Настраиваем релей через TON Connect или контракт-релей. Gasless повышает конверсию на 15-30% в мобильных приложениях.

Bounce

Если не фильтровать bounced транзакции, вы можете зачислить платёж, который на самом деле не дошёл. В TON bounce — нормальное явление: контракт получателя может отвергнуть сообщение. Проверяйте bounced флаг в теле сообщения. Для Jetton дополнительно отслеживайте transfer_notification — его отсутствие тоже признак неудачи.

Этапы настройки приёма платежей TON

  1. Анализ — оценка нагрузки, типов активов (TON, Jetton), выбор архитектуры.
  2. Выбор метода идентификации — comment или уникальные адреса.
  3. Разработка мониторинга — интеграция с TON Center / TonAPI, обработка webhook/WebSocket.
  4. Интеграция с бэкендом — маппинг транзакций на заказы, обработка ошибок.
  5. Тестирование на testnet — использование бота для раздачи тестовых TON и Sandbox от Blueprint.
  6. Деплой — настройка продакшен-среды, мониторинг и алерты.

Сроки и стоимость

Сроки настройки базовой схемы — от 2 до 4 недель. Стоимость рассчитывается индивидуально в зависимости от сложности: количества активов, нагрузки и необходимости Gasless-релея. Получите консультацию по архитектуре — свяжитесь для оценки проекта.

Типичные ошибки при приёме TON

  • Игнорирование bounced-транзакций — зачисление несостоявшихся платежей.
  • Мониторинг основного адреса вместо JettonWallet — пропуск Jetton-платежей.
  • Использование только polling без fallback — потеря транзакций при высокой нагрузке.
  • Отсутствие тестирования на testnet — ошибки в продакшене.
  • Неучёт асинхронности — попытка синхронно ждать ответа от контракта.

Тестирование и деплой

Testnet: используем бота для раздачи тестовых TON. API endpoint https://testnet.toncenter.com/api/v2/jsonRPC. Для локальной разработки — Sandbox от Blueprint: эмулятор TVM без сети. Модель асинхронных сообщений требует особого подхода к тестированию. Закажите настройку приёма платежей TON, чтобы исключить ошибки в мониторинге и автоматизировать учёт.