← Guides
Playbook Dans Construire des produits intermediate · 24 min de lecture · Mis à jour 11 avr. 2026

Paiements bot, de bout en bout

Un guide sans raccourci pour accepter les paiements via un bot Telegram — Stars pour digital, fiat pour physique, refunds, webhooks, et les pièges que personne ne documente.

Exemple de monétisation bot dans Telegram
Une interaction bot prix-Stars — tout le flow de paiement se passe inline, pas de redirects. Source : press kit telegram.org.

Les paiements bot Telegram sont le checkout le plus simple sur internet. Pas de champs de carte, pas de redirects, pas de SCA dance — l’utilisateur tape Pay, confirme avec biométrie, fini.

Voici la version ennuyeuse et complète : chaque appel d’API Bot dont vous avez vraiment besoin, dans l’ordre, avec les cas d’erreur.

01

Choisir votre provider

Stars — pas de setup, juste utiliser currency: "XTR". Les fonds atterrissent dans le wallet Stars de votre bot. Fiat — parler à @BotFather → Payments et connecter un provider (Stripe, Smart Glocal, YooKassa, Tranzzo, selon géographie). Vous obtiendrez un provider token à passer dans les invoices.

Pour 99% des produits digitaux, démarrez avec Stars et sautez la fiat dance entièrement.

core.telegram.org Vue d’ensemble paiements bot ↗
02

Envoyer une invoice

Le chemin le plus simple est sendInvoice directement dans un chat :

await fetch(`https://api.telegram.org/bot${TOKEN}/sendInvoice`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    chat_id: userId,
    title: "Plan Pro, mensuel",
    description: "Accès illimité pendant 30 jours.",
    payload: `pro_${userId}_${Date.now()}`,
    currency: "XTR",
    prices: [{ label: "Pro", amount: 250 }],
  }),
});

payload est votre clé d’idempotence privée — ne l’exposez jamais à l’utilisateur, mettez-y toujours assez pour identifier la commande de votre côté.

Pour les Mini Apps, utilisez createInvoiceLink à la place, puis appelez WebApp.openInvoice(url) côté client.

03

Gérer pre-checkout

Telegram vous envoie un update pre_checkout_query avant de débiter. Vous devez répondre dans 10 secondes, ou le paiement auto-fail.

// dans votre handler d'updates
if (update.pre_checkout_query) {
  const ok = await canFulfill(update.pre_checkout_query.invoice_payload);
  await fetch(`https://api.telegram.org/bot${TOKEN}/answerPreCheckoutQuery`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      pre_checkout_query_id: update.pre_checkout_query.id,
      ok,
      error_message: ok ? undefined : "Plus de stock — désolé.",
    }),
  });
}

Utilisez ce hook pour : re-valider le stock, vérifier la fraude, confirmer que l’utilisateur n’est pas banni, locker l’inventaire.

04

Accorder les droits sur successful_payment

Après débit, vous recevez message.successful_payment sur le même chat. Le payload est votre clé d’idempotence — dédupez dessus.

if (update.message?.successful_payment) {
  const sp = update.message.successful_payment;
  await db.transaction(async (tx) => {
    const exists = await tx.payment.findUnique({ where: { payload: sp.invoice_payload } });
    if (exists) return;
    await tx.payment.create({ data: { ...sp, userId: update.message.chat.id } });
    await grantEntitlement(update.message.chat.id, sp.invoice_payload);
  });
  await sendMessage(update.message.chat.id, "Paiement reçu — vous êtes dedans. Tapez /start pour commencer.");
}

Telegram retry successful_payment jusqu’à ce que vous ack — votre handler doit être idempotent ou vous accordez l’accès deux fois.

05

Refunds

Stars : refundStarPayment(user_id, telegram_payment_charge_id). Entièrement programmatique. Fiat : refund via le dashboard de votre provider (Stripe etc.) ; Telegram ne proxy pas les refunds fiat.

Construisez une commande admin /refund <order_id> dès le J1. Sans ça, vous ferez du SQL manuel dans une semaine.

06

Subscriptions récurrentes

Deux patterns :

Stars subscriptions (recommandé) — passez subscription_period: 2592000 (30 jours) sur l’invoice. Telegram facture l’utilisateur automatiquement chaque période. Vous recevez un successful_payment à chaque cycle.

Récurrent manuel — schedulez vos propres rappels de renouvellement, envoyez une fresh invoice à chaque cycle. Plus de boulot, mais vous contrôlez les retries, le dunning, les périodes de grâce.

Pour produits SaaS-like, les Stars subscriptions sont parfaites. Pour B2B haut-ticket, faites du récurrent manuel avec fiat.

Une démo code de bout en bout

Si vous préférez voir l’implémentation end-to-end avant de lire le reste, ce tutoriel tiers montre un flow complet de paiement Stars dans une Mini App :

Tutoriel indépendant en anglais. Walkthrough de createInvoiceLink, openInvoice et du handler successful_payment dans le code.

Checklist production

  • Handler successful_payment idempotent.
  • SLO 10s sur answerPreCheckoutQuery.
  • Commande admin refund.
  • Vérif secret webhook sur chaque update entrant (X-Telegram-Bot-Api-Secret-Token).
  • Table ledger séparée de votre logique business — chaque Stars/cents in et out, immutable.
  • Job de réconciliation quotidien comparant getStarTransactions à votre ledger.

Cette dernière vous sauvera le jour où un successful_payment retry vers un bot que vous avez redéployé sans idempotence.

Restez dans la boucle

Un email court quand quelque chose d'utile sort. Pas de pixels de tracking, pas d'upsell.