Налаштування прийому платежів у 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, щоб виключити помилки в моніторингу та автоматизувати облік.