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 8h agoCreated Oct 30, 2026
Back to folder

commands/_viewprod.js

javascript Β· 267 lines

Raw
1/**#command2name: /viewprod3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12// PREMIUM BUTTON ICONS13(function(){14  try {15    if (!JSON.__premiumPatched) {16      var __origStringify = JSON.stringify;17      JSON.stringify = function(value, replacer, space) {18        try {19          if (value && value.inline_keyboard && Array.isArray(value.inline_keyboard)) {20            var premiumIds = [21              "6143444134125379822",22              "6091379307907652768",23              "6147534454819661264",24              "6147817325660741985",25              "6235683689292897318",26              "6102856637343600044"27            ];28            var rows = value.inline_keyboard.map(function(row, ri) {29              if (!Array.isArray(row)) return row;30              return row.map(function(btn, bi) {31                if (!btn || typeof btn !== "object") return btn;32                var copy = {};33                for (var k in btn) copy[k] = btn[k];34                if (!copy.icon_custom_emoji_id) copy.icon_custom_emoji_id = premiumIds[(ri + bi) % premiumIds.length];35                return copy;36              });37            });38            var cloned = {};39            for (var key in value) cloned[key] = value[key];40            cloned.inline_keyboard = rows;41            return __origStringify.call(JSON, cloned, replacer, space);42          }43        } catch (e) {}44        return __origStringify.call(JSON, value, replacer, space);45      };46      JSON.__premiumPatched = true;47    }48  } catch (e) {}49})();50 51 52 53// =========================================================54// πŸ“¦ Shows a product's plans (Step 2 of the buy flow)55// βœ… CRITICAL BUG FIX: pehle "<tg-emoji emoji-id='X'></tg-emoji>" ek EMPTY56// tag tha (koi fallback character nahi) β€” Telegram ka HTML parser aise57// malformed tg-emoji tag par POORA MESSAGE hi reject kar deta hai. Isi58// wajah se product par click karne par plan-list screen kabhi aati hi nahi59// thi β€” poora buy flow yahi pe tootta tha!60// βœ… Photo-message-edit bug bhi fix, aur missing else-branch (fresh send)61// bhi add kiya.62// =========================================================63 64try {65 66  // πŸ›  PANEL MAINTENANCE GUARD67  // Re-check at every purchase/payment stage so an admin can switch a panel68  // OFF even if a user already opened the checkout screen.69  function isPanelUnderMaintenance(product) {70    if (!product) return false;71    var mKey = "panel_maintenance_" +72      String(product.id || product.name || "").toUpperCase().replace(/[^A-Z0-9_-]/g, "_");73    return Bot.getProperty(mKey) === true;74  }75 76  var productList = Bot.getProperty("stored_products") || [];77  var callbackId = request ? request.id : null;78  var chatId = chat.chatid;79  var messageId = request && request.message ? request.message.message_id : (request ? request.message_id : null);80  var isPhotoMsg = !!(request && request.message && request.message.photo);81 82  var userId = user.telegramid;83  var isReseller = Bot.getProperty("is_reseller_" + userId) === true;84 85  var productIndex = params ? params.trim() : "";86  if (productIndex === "") {87    var cbData = request && request.callback_query ? request.callback_query.data : "";88    productIndex = cbData.replace("/viewprod ", "").replace("viewprod ", "");89  }90 91  var selectedProduct = productList[Number(productIndex)];92 93  if (selectedProduct) {94    var viewMaintKey = "panel_maintenance_" +95      String(selectedProduct.id || selectedProduct.name || productIndex).toUpperCase().replace(/[^A-Z0-9_-]/g, "_");96    if (Bot.getProperty(viewMaintKey) === true) {97      var viewMaintText = "πŸ›  <b>PANEL UNDER MAINTENANCE</b>\n\n" +98        "πŸ“¦ <b>Panel:</b> <code>" + String(selectedProduct.name || "Product") + "</code>\n\n" +99        "⏳ Is panel par purchase temporarily disabled hai. Please try again later.";100      if (callbackId) {101        try { Api.answerCallbackQuery({ callback_query_id: String(callbackId), text: "πŸ›  Panel is under maintenance", show_alert: true }); } catch (e) {}102      }103      if (messageId) {104        try {105          Api.editMessageText({106            chat_id: chatId,107            message_id: Number(messageId),108            text: viewMaintText,109            parse_mode: "HTML",110            reply_markup: JSON.stringify({ inline_keyboard: [[111              { text: "⬅️ Back to Shop", callback_data: "/buy_hack", style: "danger", icon_custom_emoji_id: "5893163582194978381" }112            ]] })113          });114        } catch (e) {115          Api.sendMessage({ chat_id: chatId, text: viewMaintText, parse_mode: "HTML" });116        }117      } else {118        Api.sendMessage({ chat_id: chatId, text: viewMaintText, parse_mode: "HTML" });119      }120      return;121    }122  }123 124  if (!selectedProduct) {125    if (callbackId) {126      try { Api.answerCallbackQuery({ callback_query_id: String(callbackId), text: "⚠️ Product not found!", show_alert: true }); } catch (e) {}127    }128    return;129  }130 131  var planButtons = [];132  var planLines = [];133  var plans = selectedProduct.plans || [];134 135  if (plans.length === 0) {136    plans = [137      { days: "1", unit: "day", durationDisplay: "1 Day", normal_price: "79", reseller_price: "65" },138      { days: "7", unit: "day", durationDisplay: "7 Days", normal_price: "350", reseller_price: "300" }139    ];140  }141 142  // User-specific price is resolved here for the exact Telegram member.143  // Global normal/reseller prices remain untouched.144  for (var j = 0; j < plans.length; j++) {145    var plan = plans[j];146    var planUnit = plan.unit || "day";147 148    var cleanProdName = selectedProduct.name.trim().toUpperCase();149    var cleanPlanDays = String(plan.days).replace(/[^0-9.]/g, "").trim();150 151    var priceKeySuffix = (planUnit === "day") ? cleanPlanDays : (cleanPlanDays + "_" + planUnit);152    var normalKey = "price_normal_" + cleanProdName + "_" + priceKeySuffix;153    var resellerKey = "price_reseller_" + cleanProdName + "_" + priceKeySuffix;154 155    var adminNormalPrice = Bot.getProperty(normalKey);156    var adminResellerPrice = Bot.getProperty(resellerKey);157 158    var currentNormal = (adminNormalPrice !== undefined && adminNormalPrice !== null) ? adminNormalPrice : plan.normal_price;159    var currentReseller = (adminResellerPrice !== undefined && adminResellerPrice !== null) ? adminResellerPrice : plan.reseller_price;160 161    var baseDisplayPrice = isReseller ? Number(currentReseller) : Number(currentNormal);162    var memberPriceKey = "member_custom_price_" + userId + "_" + cleanProdName.replace(/[^A-Z0-9_-]/g, "_") + "_" + ((planUnit === "day") ? cleanPlanDays : (cleanPlanDays + "_hour"));163    var memberCustomPrice = Bot.getProperty(memberPriceKey);164    var hasMemberCustomPrice = memberCustomPrice !== undefined && memberCustomPrice !== null && isFinite(Number(memberCustomPrice));165    var displayPrice = hasMemberCustomPrice ? Number(memberCustomPrice) : baseDisplayPrice;166 167    var unitLabelWord = (planUnit === "hour") ? (Number(cleanPlanDays) === 1 ? "HOUR" : "HOURS") :168                         (planUnit === "minute") ? (Number(cleanPlanDays) === 1 ? "MINUTE" : "MINUTES") :169                         (Number(cleanPlanDays) === 1 ? "DAY" : "DAYS");170    var dayLabel = plan.durationDisplay || (cleanPlanDays + " " + unitLabelWord);171 172    // Live manual stock count is isolated by Product + Duration + Unit.173    var stockProductSlug = cleanProdName.replace(/[^A-Z0-9_-]/g, "_");174    var stockStorageKey = "manual_keys_" + stockProductSlug + "_" + cleanPlanDays + "_" + planUnit;175    var liveStock = Bot.getProperty(stockStorageKey) || [];176    if (!Array.isArray(liveStock)) liveStock = [];177 178    // Backward compatibility for old Day-only manual stock.179    if (liveStock.length === 0 && planUnit === "day") {180      var legacyStock = Bot.getProperty("manual_keys_" + cleanProdName + "_" + cleanPlanDays) || [];181      if (Array.isArray(legacyStock)) liveStock = legacyStock;182    }183 184    // Stock is tracked internally for delivery, but deliberately hidden from the customer UI.185    // Price β†’ duration, using the requested custom emoji ID.186    var priceEmoji = "<tg-emoji emoji-id='6147565374289220368'>πŸ’²</tg-emoji>";187    var durationEmoji = "<tg-emoji emoji-id='6147565374289220368'>⏱️</tg-emoji>";188    planLines.push(189      priceEmoji + " <b>β‚Ή" + Number(displayPrice).toFixed(2) + "</b>  β€”  " +190      durationEmoji + " <b>" + dayLabel.toUpperCase() + "</b>" +191      (hasMemberCustomPrice ? "  πŸ‘€" : "")192    );193 194    // Buttons stay tied to the exact panel/plan/member-specific price.195    // Do not expose stock count on the customer-facing button.196    planButtons.push([197      {198        text: dayLabel.toUpperCase() + " β€” β‚Ή" + Number(displayPrice).toFixed(2),199        callback_data: "/buyitem " + productIndex + " " + j,200        style: "success",201        icon_custom_emoji_id: "6147565374289220368"202      }203    ]);204  }205 206  // βœ… NEW: Back button ab is product ki category wali list par le jaata hai207  // (Android Root / Android Non Root), generic /buy_hack (category-select) par nahi.208  var backCategory = selectedProduct.category ? String(selectedProduct.category).toLowerCase() : "both";209  var backCallback = (backCategory === "root") ? "/buy_hack_cat root" : (backCategory === "iphone") ? "/buy_hack_cat iphone" : "/buy_hack_cat nonroot";210 211  // Demo videos, when configured by admin, appear at the bottom of the plan list.212  var demoVideosForProduct = Array.isArray(selectedProduct.demo_videos) ? selectedProduct.demo_videos : [];213  if (demoVideosForProduct.length > 0) {214    planButtons.push([215      {216        text: "πŸŽ₯ Demo Video (" + demoVideosForProduct.length + ")",217        callback_data: "/demo_view " + String(productIndex),218        style: "primary"219      }220    ]);221  }222 223  planButtons.push([224    {225      text: "Back to Shop",226      callback_data: backCallback,227      style: "danger",228      icon_custom_emoji_id: "5893163582194978381"229    }230  ]);231 232  // βœ… FIX: empty tg-emoji tag hata diya β€” ab sirf plain product emoji text hai233  var planText =234    "<blockquote>πŸ›’ <b>" + selectedProduct.name.toUpperCase() + "</b> πŸ›’</blockquote>\n\n" +235    "<blockquote>πŸ‘‘ <b>Your Account Tier: " + (isReseller ? "RESELLER" : "USER") + "</b></blockquote>\n\n" +236    "πŸ›’ <b>Choose your access plan:</b>\n\n" +237    planLines.join("\n") + "\n\n" +238    "<blockquote>πŸ‘‡ <i>Tap any plan below to continue</i></blockquote>";239 240 241  var replyMarkupStr = JSON.stringify({ inline_keyboard: planButtons });242 243  if (messageId) {244    if (isPhotoMsg) {245      try { Api.deleteMessage({ chat_id: chatId, message_id: messageId }); } catch (e) {}246      Api.sendMessage({ chat_id: chatId, text: planText, parse_mode: "HTML", reply_markup: replyMarkupStr });247    } else {248      Api.editMessageText({249        chat_id: chatId,250        message_id: Number(messageId),251        text: planText,252        parse_mode: "HTML",253        reply_markup: replyMarkupStr254      });255    }256  } else {257    // βœ… FIX: pehle is case me kuch bhejta hi nahi tha258    Api.sendMessage({ chat_id: chatId, text: planText, parse_mode: "HTML", reply_markup: replyMarkupStr });259  }260 261  if (callbackId) {262    try { Api.answerCallbackQuery({ callback_query_id: String(callbackId) }); } catch (e) {}263  }264 265} catch (err) {266  Bot.sendMessage("⚠️ View Product Error: " + err.message, { parse_mode: "HTML" });267}