Telegram Mini App

টেলিগ্রাম মিনি অ্যাপ এ পেমেন্ট গেটওয়ে ইন্সটল

৫টা স্টেপে আপনার Telegram bot বা Mini App থেকে bKash, Nagad, কার্ড — সব accept করুন। কোনো PCI compliance, কোনো মার্চেন্ট অ্যাকাউন্ট লাগবে না।

bKashNagadRocketCardUSDT
0

শুরুর আগে যা লাগবে

  • একটা FastPay Global অ্যাকাউন্ট → Sign up → Brand তৈরি → API Keys
  • Node.js ১৮+ সার্ভার (Express / Fastify / যেকোনো ফ্রেমওয়ার্ক)
  • HTTPS public URL (production এ লাগবে — ngrok দিয়ে dev এ test করতে পারেন)
  • Telegram BotFather থেকে bot toke এবং Mini App URL register করা
bash
# .env
FASTPAYGLOBAL_PUBLIC_KEY=pk_live_xxxxxxxxxxxxxxxx
FASTPAYGLOBAL_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxx
TELEGRAM_BOT_TOKEN=123456:ABC-your-bot-token
PUBLIC_URL=https://yourshop.example.com
1

BotFather এ Bot + Mini App তৈরি

text
1. Telegram এ @BotFather খুলুন
2. /newbot → bot এর নাম + username দিন
3. টোকেন কপি করুন → .env এ TELEGRAM_BOT_TOKEN বসান
4. /newapp → bot সিলেক্ট → Mini App URL দিন (https://yourshop.example.com)
5. /setmenubutton → bot সিলেক্ট → Mini App এর URL আবার দিন

Mini App এর URL আপনার hosted React/HTML অ্যাপ — যেখানে পেমেন্ট বাটন থাকবে।

2

সার্ভারে Payment তৈরির endpoint বানান

Public Key শুধু সার্ভারে — কখনো ফ্রন্টএন্ডে expose করবেন না। Frontend আপনার server কে call করবে, server FastPay Global কে call করবে।

javascript
// server/checkout.js — Node.js / Express
import express from "express";
const router = express.Router();

router.post("/api/checkout", async (req, res) => {
  const { amount, orderId, chatId, customer } = req.body;

  const r = await fetch("https://fastpayglobal.app/api/public/create-payment", {
    method: "POST",
    headers: {
      "content-type": "application/json",
      "x-public-key": process.env.FASTPAYGLOBAL_PUBLIC_KEY,
    },
    body: JSON.stringify({
      amount,                    // BDT (টাকা) — × 100 করবেন না
      currency: "BDT",
      orderId,
      customer,                  // { name?, email?, phone? }
      metadata: {
        telegramChatId: chatId,  // webhook এ ফেরত আসবে
        redirectUrl: `${process.env.PUBLIC_URL}/orders/${orderId}`,
      },
    }),
  });

  const data = await r.json();   // { id, hostedUrl, expiresAt, status }
  res.json({ payUrl: data.hostedUrl, paymentId: data.id });
});

export default router;
amount BDT তে পাঠান — × 100 করবেন না। FastPay Global নিজেই paisa এ convert করে। ভুল করলে customer ১০০ গুণ বেশি charge হবে।
3a

Bot থেকে Pay বাটন পাঠান

সবচেয়ে সহজ পদ্ধতি — আপনার bot এ /buy command এ inline keyboard পাঠান। Telegram web_app বাটন ক্লিকে hosted payment page Mini App হিসেবে খোলে।

javascript
// bot.js — grammY / node-telegram-bot-api
bot.command("buy", async (ctx) => {
  // 1. সার্ভারে payment তৈরি
  const { payUrl } = await fetch(`${PUBLIC_URL}/api/checkout`, {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({
      amount: 500,
      orderId: `ORD-${Date.now()}`,
      chatId: ctx.chat.id,
    }),
  }).then((r) => r.json());

  // 2. ইনলাইন বাটন সহ মেসেজ
  await ctx.reply("🛒 Premium Plan — ৳500", {
    reply_markup: {
      inline_keyboard: [[
        { text: "💳 Pay with bKash / Nagad", web_app: { url: payUrl } },
      ]],
    },
  });
});
3b

অথবা — Mini App এর ভিতর থেকে

ইতিমধ্যে Mini App থাকলে Telegram এর native MainButton ব্যবহার করুন — সবচেয়ে UX-friendly। পেমেন্ট পেজ tg.openLink() দিয়ে খুলুন, কারণ bKash/Nagad SSO Mini App embedded view তে কখনো block হয়।

javascript
// CheckoutButton.jsx — React inside Telegram Mini App
import { useEffect } from "react";

export default function CheckoutButton({ amount, orderId }) {
  const tg = window.Telegram?.WebApp;

  useEffect(() => {
    tg?.ready();
    tg?.expand();
    tg?.MainButton.setText(`💳 Pay ৳${amount}`).show();

    const handler = async () => {
      tg.MainButton.showProgress();
      const { payUrl } = await fetch("/api/checkout", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({
          amount,
          orderId,
          chatId: tg.initDataUnsafe?.user?.id,
        }),
      }).then((r) => r.json());

      tg.MainButton.hideProgress();
      tg.openLink(payUrl);   // tg.openLink — bKash/Nagad SSO ঠিকঠাক কাজ করে
    };

    tg.MainButton.onClick(handler);
    return () => {
      tg.MainButton.offClick(handler);
      tg.MainButton.hide();
    };
  }, [amount, orderId]);

  return null;
}
4

Webhook receive করে অর্ডার update + user কে notify

পেমেন্ট সফল হলে FastPay Global আপনার webhook URL এ POST করবে। Signature verify করে অর্ডার paid mark করুন এবং customer কে Telegram এ confirmation পাঠান।

javascript
// server/fastpayglobal-webhook.js
import express from "express";
import crypto from "crypto";
const router = express.Router();

// IMPORTANT: express.raw() — express.json() এর আগে mount করুন
router.post(
  "/api/fastpayglobal-webhook",
  express.raw({ type: "application/json" }),
  async (req, res) => {
    const sig = req.header("x-paysol-signature") || "";
    const parts = Object.fromEntries(sig.split(",").map((p) => p.trim().split("=")));
    const ts = parts.t, v1 = parts.v1;
    if (!ts || !v1) return res.status(401).send("Missing signature");

    // Replay protection (5 min)
    if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) {
      return res.status(401).send("Stale");
    }

    const expected = crypto
      .createHmac("sha256", process.env.FASTPAYGLOBAL_WEBHOOK_SECRET)
      .update(`${ts}.${req.body.toString("utf8")}`)
      .digest("hex");

    if (!crypto.timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(v1, "hex"))) {
      return res.status(401).send("Invalid signature");
    }

    const event = JSON.parse(req.body.toString("utf8"));

    if (event.type === "payment.succeeded") {
      const chatId = event.data.metadata?.telegramChatId;

      // ✅ অর্ডার update + customer কে notify
      await Order.findOneAndUpdate(
        { _id: event.data.orderId, status: { $ne: "paid" } },
        { $set: { status: "paid", trxId: event.data.trxId, paidAt: new Date() } }
      );

      if (chatId) {
        await fetch(
          `https://api.telegram.org/bot${process.env.TELEGRAM_BOT_TOKEN}/sendMessage`,
          {
            method: "POST",
            headers: { "content-type": "application/json" },
            body: JSON.stringify({
              chat_id: chatId,
              text: `✅ পেমেন্ট সফল! TrxID: ${event.data.trxId}`,
            }),
          }
        );
      }
    }

    res.json({ received: true });
  }
);

export default router;
express.raw() অবশ্যই express.json() এর আগে mount করতে হবে — না হলে raw body পাবেন না, signature mismatch হবে।

এরপর Dashboard → Webhooks → endpoint URL register করুন: https://yourshop.example.com/api/fastpayglobal-webhook

Production checklist

  • Public Key সার্ভারে — frontend এ কখনো না
  • amount BDT তে — × 100 করবেন না
  • redirectUrl metadata এর ভিতরে, top-level এ না
  • Webhook signature verify (HMAC-SHA256, timing-safe compare)
  • Replay protection — 5 মিনিটের পুরোনো event reject
  • Order update idempotent — একই paymentId দুবার এলে double-process না
  • HTTPS — Telegram webhook ও Mini App উভয়ের জন্য বাধ্যতামূলক

আরও দরকার? API Reference এ সব endpoint, SDK Library তে PHP/Python/Node.js helpers, Web Integration এ সাধারণ ওয়েবসাইট setup।