← 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.