Ketmus
Esc

Сценарии интеграции

Telegram-бот

Приём криптоплатежей в Telegram-боте и Mini App: подписки, доступ к каналам и цифровые товары.

Боту не нужен сайт: счёт создаёт бэкенд бота, клиент оплачивает по кнопке со ссылкой, а Ketmus присылает вебхук, по которому бот выдаёт доступ и пишет пользователю.

Схема

  1. 1

    Пользователь отправляет /buy

    Бот создаёт счёт и кладёт telegram_user_id в metadata.

  2. 2

    Бот присылает кнопку

    Inline-кнопка с pay_url открывает платёжную страницу во встроенном браузере Telegram.

  3. 3

    Пользователь оплачивает

    Удобнее всего — в TON или USDT в сети TON через Telegram Wallet или Tonkeeper.

  4. 4

    Бот получает вебхук

    По invoice.paid бот выдаёт доступ и отправляет сообщение пользователю из metadata.telegram_user_id.

Пример на Python (aiogram)

# bot.py — aiogram 3
import os
import aiohttp
from aiogram import Bot, Dispatcher, F
from aiogram.filters import Command
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message

API = "https://app.ketmus.com/api/merchant/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['KETMUS_API_KEY']}"}

bot = Bot(os.environ["BOT_TOKEN"])
dp = Dispatcher()


@dp.message(Command("buy"))
async def buy(message: Message):
    payload = {
        "amount": 9.99,
        "currency": "USD",
        "order_id": f"tg-{message.from_user.id}-{message.message_id}",
        "description": "Подписка Premium на 30 дней",
        "metadata": {"telegram_user_id": message.from_user.id, "plan": "premium_30d"},
        "callback_url": "https://bot.example.com/webhooks/ketmus",
        "return_url": "https://t.me/your_bot",
    }
    async with aiohttp.ClientSession(headers=HEADERS) as session:
        async with session.post(f"{API}/invoices", json=payload) as response:
            data = await response.json()

    if "invoice" not in data:
        await message.answer("Не удалось создать счёт, попробуйте позже.")
        print("Ketmus error:", data.get("error"))
        return

    invoice = data["invoice"]
    keyboard = InlineKeyboardMarkup(inline_keyboard=[[InlineKeyboardButton(text="Оплатить криптовалютой", url=invoice["pay_url"])]])
    await message.answer("Счёт на 9.99 USD создан. Оплатите в течение часа:", reply_markup=keyboard)

Пример на Node.js (grammY)

// bot.ts — grammY
import { Bot, InlineKeyboard } from 'grammy'

const bot = new Bot(process.env.BOT_TOKEN!)

bot.command('buy', async (ctx) => {
  const response = await fetch('https://app.ketmus.com/api/merchant/v1/invoices', {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.KETMUS_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({
      amount: 9.99,
      currency: 'USD',
      order_id: `tg-${ctx.from!.id}-${ctx.msg.message_id}`,
      description: 'Подписка Premium на 30 дней',
      metadata: { telegram_user_id: ctx.from!.id, plan: 'premium_30d' },
      rails: ['usdt_ton', 'ton', 'usdt_tron'],
      callback_url: 'https://bot.example.com/webhooks/ketmus',
    }),
  })
  const data = await response.json()
  if (!response.ok) {
    console.error('Ketmus error:', data.error)
    return ctx.reply('Не удалось создать счёт, попробуйте позже.')
  }
  const { invoice } = data

  await ctx.reply('Счёт на 9.99 USD создан. Оплатите в течение часа:', {
    reply_markup: new InlineKeyboard().url('Оплатить криптовалютой', invoice.pay_url),
  })
})

bot.start()

Telegram Mini App

В Mini App счёт тоже создаёт ваш сервер: передайте ему initData, проверьте подпись Telegram, создайте счёт и откройте pay_url через Telegram.WebApp.openLink.

// Внутри Telegram Mini App: счёт создаёт ваш сервер, а не клиент
const { url } = await fetch('/api/checkout', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'X-Telegram-Init-Data': Telegram.WebApp.initData },
  body: JSON.stringify({ plan: 'premium_30d' }),
}).then((r) => r.json())

Telegram.WebApp.openLink(url) // платёжная страница откроется во встроенном браузере

Советы

  • Ограничьте монеты параметром rails, например ["usdt_ton", "ton", "usdt_tron"] — для аудитории Telegram это самые быстрые и дешёвые сети.
  • Кнопка «Оплатить» всегда ведёт на pay_url, в том числе для СБП. Не ставьте на неё ссылку qr.nspk.ru из payment_uri: на странице Ketmus покупатель видит, через кого платит, видит сумму, таймер и статус, а потом возвращается в бота. → Оплата по СБП
  • Для пополнения баланса в боте используйте статические адреса с customer_id = Telegram ID пользователя.
  • Передайте return_url: "https://t.me/your_bot", чтобы после оплаты пользователь вернулся в бота.
  • API-ключ хранится только на сервере бота — не встраивайте его в Mini App.