indrajitghosh20006/Igstore_01botPublic Β· Bot Template

ProfileTelegram

AIThe bot provides an admin interface for a digital store, allowing the owner or co‑admins to add balances, products, plans, and categories. It supports payment workflows via UPI and Binance Pay, automatically generating QR codes and handling manual approval of deposits. The code patches inline keyboards to use premium emoji icons and includes helper functions for user and bot properties. Overall, it serves as a commerce management tool for a Telegram-based storefront.

Commercestoreadminbalanceproductplancategory
170 commands0 envUpdated 7h agoCreated Oct 30, 2026
Back to folder

commands/_onQR.js

javascript Β· 230 lines

Raw
1/**#command2name: /onQR3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12/**#command13name: /onQR14answer: 15keyboard: 16parse_mode: markdown17aliases: 18allow_only_group: false19need_reply: false20case_insensitive: false21is_web: 022#command**/23 24try {25  if (!content) { 26    Bot.sendMessage("❌ Error: No response received from server.");27    return; 28  }29 30  var res = (typeof content === "object") ? content : JSON.parse(content);31 32  if (res && res.order_id && (res.qr_url || res.checkout_url || res.upi_intent)) {33    res = { status: "success", data: { order_id: res.order_id, qr_url: res.qr_url, checkout_url: res.checkout_url, upi_id: res.upi_id, upi_intent: res.upi_intent, amount: res.amount || res.payable_amount, expires_at_ist: res.expires_at_ist || res.expires_at || "5 Minutes" } };34  }35 36  if (!res || res.status != "success" || !res.data) {37    Api.sendMessage({38      chat_id: chat.chatid,39      text: "<tg-emoji emoji-id='6219547832169273793'>❌</tg-emoji> <b>QR Generation Failed /</b>",40      parse_mode: "HTML"41    });42    return;43  }44 45  var order_id = res.data.order_id;46  var gatewayQr = res.data.qr_url;47  var upiId = String(res.data.upi_id || res.data.vpa || res.data.upi || "").trim();48  var upiIntent = String(res.data.upi_intent || res.data.upiIntent || "").trim();49  var expire = res.data.expires_at_ist ? res.data.expires_at_ist : "5 Minutes";50  51  var userId = user.telegramid;52  53  var deposit_amount = res.data.payable_amount || res.data.amount ||54                       Bot.getProperty("pending_pay_amount_" + userId) || 55                       User.getProperty("pending_pay_amount_" + userId) || 56                       Bot.getProperty("deposit_amount_" + userId) || 57                       User.getProperty("deposit_amount") || 58                       "0";59 60  var apiAmount = res.data.payable_amount || res.data.amount;61  if (apiAmount !== undefined && apiAmount !== null && apiAmount !== "") {62    deposit_amount = apiAmount;63    User.setProperty("deposit_amount", String(apiAmount), "string");64    User.setProperty("pending_pay_amount_" + userId, String(apiAmount), "string");65  }66 67  var finalAmount = parseFloat(deposit_amount);68  if (isNaN(finalAmount) || finalAmount <= 0) {69    finalAmount = 0.00; 70  }71 72  // Use a standards-based UPI QR for better cross-app compatibility (including73  // PhonePe). The gateway VPA/order are preserved; the gateway QR remains a74  // fallback if the response does not contain a VPA.75  // Telegram can reject some gateway-hosted QR files as DOCUMENT_INVALID.76  // Prefer a standard PNG generated from the gateway's exact UPI intent.77  var qr = "";78  if (upiIntent) {79    qr = "https://api.qrserver.com/v1/create-qr-code/?size=700x700&margin=10&data=" + encodeURIComponent(upiIntent);80  } else {81    qr = gatewayQr;82  }83  if (!qr && upiId && finalAmount > 0) {84    var upiUri = "upi://pay?pa=" + encodeURIComponent(upiId) +85      "&am=" + encodeURIComponent(finalAmount.toFixed(2)) +86      "&cu=INR&tr=" + encodeURIComponent(String(order_id)) +87      "&tn=" + encodeURIComponent(String(order_id));88    qr = "https://api.qrserver.com/v1/create-qr-code/?size=700x700&margin=10&data=" + encodeURIComponent(upiUri);89  }90  if (!qr) {91    Bot.sendMessage("❌ Error: QR Code link missing from API response.");92    return;93  }94 95  var gatewayMsg = "<blockquote><tg-emoji emoji-id='6100170496077204999'>πŸ“‹</tg-emoji> <b>Instructions</b></blockquote>\n" +96    "β€’ Scan the QR using any UPI app.\n" +97    "β€’ Pay the exact amount shown below.\n" +98    "β€’ Wait a few seconds after payment.\n" +99    "β€’ Tap <b>Verify Payment</b> below.\n\n" +100    "🧾 <b>Order ID:</b> <code>" + order_id + "</code>\n" +101    "<tg-emoji emoji-id='6312263493051489212'>πŸ’°</tg-emoji> <b>Amount:</b> β‚Ή<code>" + finalAmount.toFixed(2) + "</code>\n" +102    "<tg-emoji emoji-id='6100657257605763582'>⏳</tg-emoji> <b>Expires:</b> <code>" + expire + "</code>\n\n" +103    "<tg-emoji emoji-id='6102856637343600044'>βœ…</tg-emoji> <i>Your balance will be credited automatically after successful verification.</i>";104 105  var inlineButtons = [106    [107      {108        text: "Verify Payment",109        callback_data: "/check " + order_id,110        style: "success",111        icon_custom_emoji_id: "6102856637343600044"112      }113    ],114    [115      {116        text: "Cancel",117        callback_data: "/cancel_topup " + order_id,118        style: "danger",119        icon_custom_emoji_id: "6219547832169273793"120      }121    ]122  ];123 124  // ⚑ SPEED FIX: QR photo pehle bhejo taaki user ko turant dikhe, "Generating..."125  // wala purana message uske baad (background me) delete karo β€” pehle ye ulta126  // tha (pehle delete, fir photo), jisse QR dikhne me extra gap lagta tha.127  var genMsgId = null;128  try {129    genMsgId = Bot.getProperty("gen_msg_id_" + userId) || User.getProperty("gen_msg_id_" + userId);130  } catch (genErr) {}131 132  var sentQrMsg;133  try {134    sentQrMsg = Api.sendPhoto({135      chat_id: chat.chatid,136      photo: qr,137      caption: gatewayMsg,138      parse_mode: "HTML",139      reply_markup: JSON.stringify({ inline_keyboard: inlineButtons })140    });141  } catch (photoErr) {142    var fallbackQr = "";143    if (upiId && finalAmount > 0) {144      var fallbackUpiUri = "upi://pay?pa=" + encodeURIComponent(upiId) +145        "&am=" + encodeURIComponent(finalAmount.toFixed(2)) +146        "&cu=INR&tr=" + encodeURIComponent(String(order_id)) +147        "&tn=" + encodeURIComponent(String(order_id));148      fallbackQr = "https://api.qrserver.com/v1/create-qr-code/?size=700x700&margin=10&data=" + encodeURIComponent(fallbackUpiUri);149    }150    if (fallbackQr && fallbackQr !== qr) {151      try {152        sentQrMsg = Api.sendPhoto({153          chat_id: chat.chatid,154          photo: fallbackQr,155          caption: gatewayMsg,156          parse_mode: "HTML",157          reply_markup: JSON.stringify({ inline_keyboard: inlineButtons })158        });159      } catch (fallbackErr) {160        Bot.sendMessage("❌ QR image Telegram ko accept nahi hui. Payment order bana hua hai; thodi der baad retry karein.", { parse_mode: "HTML" });161        return;162      }163    } else {164      Bot.sendMessage("❌ QR image URL available nahi hai. Payment order bana hua hai; thodi der baad retry karein.", { parse_mode: "HTML" });165      return;166    }167  }168 169  if (genMsgId) {170    try { Api.deleteMessage({ chat_id: chat.chatid, message_id: genMsgId }); } catch (delGenErr) {}171    Bot.setProperty("gen_msg_id_" + userId, null, "string");172    User.setProperty("gen_msg_id_" + userId, null, "string");173  }174 175  var qrMsgId = null;176  try {177    if (sentQrMsg) {178      if (sentQrMsg.result && sentQrMsg.result.message_id) {179        qrMsgId = sentQrMsg.result.message_id;180      } else if (sentQrMsg.message_id) {181        qrMsgId = sentQrMsg.message_id;182      }183    }184 185    if (qrMsgId) {186      Bot.setProperty("qr_msg_id_" + userId, qrMsgId, "string");187      User.setProperty("qr_msg_id_" + userId, qrMsgId, "string");188    }189 190    if (order_id) {191      // Bind the payable amount to this specific gateway order.192      // This is the amount verification must later enforce.193      var lockedOrderAmount = parseFloat(finalAmount);194      if (!isNaN(lockedOrderAmount) && lockedOrderAmount > 0) {195        User.setProperty("pay_order_amount_" + order_id, lockedOrderAmount, "number");196        Bot.setProperty("pay_order_amount_" + order_id, lockedOrderAmount, "number");197      }198 199      Bot.setProperty("qr_order_id_" + userId, order_id, "string");200      User.setProperty("qr_order_id_" + userId, order_id, "string");201      User.setProperty("pending_order_id", order_id, "string");202 203      // βœ… Ye "watch id" hai β€” expiry callback isse compare karega ki order abhi bhi wahi hai ya resolve ho chuka204      Bot.setProperty("qr_watch_order_" + userId, order_id, "string");205      User.setProperty("qr_watch_order_" + userId, order_id, "string");206    }207 208    Bot.setProperty("qr_caption_" + userId, gatewayMsg, "string");209    User.setProperty("qr_caption_" + userId, gatewayMsg, "string");210    Bot.setProperty("qr_buttons_" + userId, JSON.stringify(inlineButtons), "string");211    User.setProperty("qr_buttons_" + userId, JSON.stringify(inlineButtons), "string");212 213    var nowTs = String(new Date().getTime());214    Bot.setProperty("qr_created_ts_" + userId, nowTs, "string");215    User.setProperty("qr_created_ts_" + userId, nowTs, "string");216 217    Bot.setProperty("verifying_lock_" + userId, false, "boolean");218    User.setProperty("verifying_lock_" + userId, false, "boolean");219 220    // Verification is started by the Verify Payment button to avoid recursive command chains.221  } catch (saveErr) {}222 223  // QR remains visible until payment is verified or user cancels it.224  // valid rehta hai jab tak user khud "Cancel" na dabaye ya payment verify225  // na ho jaaye. Order kabhi background me apne aap "expire" nahi hoga β€”226  // sirf manual Cancel button se hi QR vanish hoga (see /cancel_topup).227 228} catch (err) {229  Bot.sendMessage("⚠️ System Error: " + err.message);230}