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/_onWebKeyReceive.js

javascript Β· 304 lines

Raw
1/**#command2name: /onWebKeyReceive3answer: 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 53try { 54  // Parse response safely only if content exists55  var response = null;56  if (typeof content === "string" && content.trim() !== "") {57    try {58      response = JSON.parse(content);59    } catch (e) {60      // Keep response as null if JSON parsing fails61    }62  }63 64  var userId = user.telegramid;65  var chatId = chat.chatid;66 67  // πŸ”„ PRODUCT DATA ACCURACY CORE (DYNAMIC)68  var dataOptions = options || {}; 69  70  // πŸ†” 1. PRODUCT ID LAYER (Added for flawless API requests)71  var prodId = dataOptions.prod_id || dataOptions.id || dataOptions.product_id || User.getProperty("last_pending_prod_id") || null;72 73  // 2. Raw options fallback mechanisms74  var rawProdName = dataOptions.prod_name || dataOptions.product || dataOptions.name || User.getProperty("last_pending_prod_name") || "Product";75  var planDays = String(dataOptions.plan_days || dataOptions.days || User.getProperty("last_pending_plan_days") || "1");76  var pDaysNumOnly = planDays.replace(/[^0-9]/g, "").trim(); 77  var planUnit = dataOptions.plan_unit || User.getProperty("last_pending_plan_unit") || "day";78  var unitLabelWordW = (planUnit === "hour") ? (Number(pDaysNumOnly) === 1 ? "Hour" : "Hours") :79                        (planUnit === "minute") ? (Number(pDaysNumOnly) === 1 ? "Minute" : "Minutes") :80                        (Number(pDaysNumOnly) === 1 ? "Day" : "Days");81  var durationDisplayW = pDaysNumOnly + " " + unitLabelWordW;82 83  // 3. Database validation layer to completely kill the "Product" fallback string bug84  var productList = Bot.getProperty("stored_products") || [];85  var prodName = rawProdName.trim(); 86 87  // ⚑ DEEP ADVANCED DATABASE SEARCH MATCH (Matches by ID first if available, then name)88  if (productList.length > 0) {89    var checkTerm = prodName.toLowerCase();90    var foundMatch = false;91 92    for (var i = 0; i < productList.length; i++) {93      var dbItem = productList[i];94      var dbName = dbItem.name ? dbItem.name.trim() : "";95      var dbId = dbItem.id || null;96      97      // If ID matches directly, use it!98      if (prodId && dbId && String(prodId) === String(dbId)) {99        prodName = dbName;100        foundMatch = true;101        break;102      }103 104      if (!dbName) continue;105      106      if (dbName.toLowerCase() === checkTerm || 107          (checkTerm !== "product" && (checkTerm.indexOf(dbName.toLowerCase()) > -1 || dbName.toLowerCase().indexOf(checkTerm) > -1))) {108        prodName = dbName; 109        if (dbId) { prodId = dbId; } // Backfill ID if name matched110        foundMatch = true;111        break;112      }113    }114 115    if (!foundMatch || prodName.toLowerCase() === "product") {116      var lastPending = User.getProperty("last_pending_prod_name");117      if (lastPending && lastPending.toLowerCase() !== "product") {118        prodName = lastPending.trim();119      } else if (productList.length === 1) {120        prodName = productList[0].name.trim();121        if (productList[0].id) { prodId = productList[0].id; }122      }123    }124  }125 126  var price = Number(dataOptions.price) || Number(User.getProperty("last_pending_price")) || 0;127  var firstName = dataOptions.first_name || user.first_name || "User";128  var usernameText = user.username ? "@" + user.username : "No Username";129  var currentWalletBal = Libs.ResourcesLib.userRes("balance").value().toFixed(2);130 131  var generatedKey = null;132  var isApiDelivery = false;133  var isBackupUsed = false;134 135  var cleanProdNameUpper = prodName.trim().toUpperCase();136  var manualKeysStorageKey = "manual_keys_" + cleanProdNameUpper + "_" + pDaysNumOnly;137  var backupStockKey = "stock_" + prodName.trim() + "_" + pDaysNumOnly + "_Day";138  139  // ⚑ STEP 1: FORCE CHECK MANUAL STOCK (CRITICAL OVERRIDE)140  var manualStock = Bot.getProperty(manualKeysStorageKey);141 142  if (!manualStock || (Array.isArray(manualStock) && manualStock.length === 0)) {143    manualStock = Bot.getProperty(backupStockKey);144    isBackupUsed = true;145  }146 147  if (typeof manualStock === "string" && manualStock.trim() !== "") {148    try {149      manualStock = JSON.parse(manualStock);150    } catch(err) {151      manualStock = manualStock.split("\n").map(function(k) { return k.trim(); }).filter(Boolean);152    }153  }154 155  if (Array.isArray(manualStock) && manualStock.length > 0) {156    generatedKey = manualStock.shift(); 157    158    if (isBackupUsed) {159      Bot.setProperty(backupStockKey, manualStock, "json");160      var mainStock = Bot.getProperty(manualKeysStorageKey) || [];161      if (typeof mainStock === "string") { mainStock = mainStock.split("\n").map(function(k) { return k.trim(); }).filter(Boolean); }162      if (Array.isArray(mainStock)) {163        var idx = mainStock.indexOf(generatedKey);164        if (idx > -1) { mainStock.splice(idx, 1); }165        Bot.setProperty(manualKeysStorageKey, mainStock, "json");166      }167    } else {168      Bot.setProperty(manualKeysStorageKey, manualStock, "json");169      var backupStock = Bot.getProperty(backupStockKey) || [];170      if (typeof backupStock === "string") { backupStock = backupStock.split("\n").map(function(k) { return k.trim(); }).filter(Boolean); }171      if (Array.isArray(backupStock)) {172        var idx = backupStock.indexOf(generatedKey);173        if (idx > -1) { backupStock.splice(idx, 1); }174        Bot.setProperty(backupStockKey, backupStock, "json");175      }176    }177  }178 179  // ⚑ STEP 2: FALLBACK TO API KEYS (IF NO MANUAL STOCK WAS FOUND)180  if (!generatedKey && response && (response.status === "success" || response.ok === true)) {181    generatedKey = response.key || response.code || response.serial;182    if (generatedKey) {183      isApiDelivery = true;184      // Preserve server-side order metadata for history/admin logs.185      User.setProperty("last_api_order_id", String(response.order_id || ""), "string");186      User.setProperty("last_api_expires_at", String(response.expires_at || ""), "string");187    }188  }189 190  // STEP 3: SUCCESS DELIVERY MECHANICS191  if (generatedKey) {192    Libs.ResourcesLib.userRes("balance").add(-price);193 194    var pastSpent = Bot.getProperty("total_spent_by_" + userId) || 0;195    Bot.setProperty("total_spent_by_" + userId, Number(pastSpent) + price, "number");196 197 198    var userKeysHistory = User.getProperty("my_purchased_keys") || [];199    userKeysHistory.push({200      product: prodName,201      product_id: prodId,202      days: pDaysNumOnly,203      price: price,204      key: generatedKey,205      date: new Date().toLocaleDateString()206    });207    User.setProperty("my_purchased_keys", userKeysHistory, "json");208 209    var remainingBal = Libs.ResourcesLib.userRes("balance").value().toFixed(2);210    211    var updateLinkForKey = Bot.getProperty("update_channel_link");212    var keyDeliveryButtons = [[{ text: "πŸ“‹ Copy Key", copy_text: { text: generatedKey } }]];213    if (updateLinkForKey) {214      keyDeliveryButtons.push([{ text: "πŸ“₯ Join Updates", url: updateLinkForKey, style: "primary", icon_custom_emoji_id: "6091571559233755994" }]);215    }216    keyDeliveryButtons.push([{ text: "Back to Menu", callback_data: "/back", style: "primary", icon_custom_emoji_id: "5893163582194978381" }]);217    var keyDeliveryMarkup = JSON.stringify({ inline_keyboard: keyDeliveryButtons });218 219    var deliverText = "<blockquote>" +220                      "<tg-emoji emoji-id='5350447674971660988'>βœ…</tg-emoji> <b>PURCHASE SUCCESSFUL!</b>\n\n" +221                      "<tg-emoji emoji-id='6147767796097884213'>πŸ“¦</tg-emoji> <b>Product:</b> <code>" + prodName + "</code>\n" +222                      "<tg-emoji emoji-id='6284816251143331422'>πŸ—</tg-emoji> <b>Validity:</b> <code>" + durationDisplayW + "</code>\n" +223                      "<tg-emoji emoji-id='5352825278672412291'>πŸ‘†</tg-emoji> <b>Your Key:</b> <code>" + generatedKey + "</code>\n\n" +224                      "━━━━━ <tg-emoji emoji-id='6147934084346682063'>#⃣</tg-emoji> <b>BALANCE DETAILS</b> ━━━━━\n" +225                      "<tg-emoji emoji-id='6195037488898121775'>✨</tg-emoji> <b>Total Invest:</b> β‚Ή" + price.toFixed(2) + "\n" +226                      "<tg-emoji emoji-id='5409048419211682843'>πŸ’΅</tg-emoji> <b>New Wallet Balance:</b> β‚Ή" + remainingBal + "\n\n" +227                      "<i>Enjoy your purchase. <tg-emoji emoji-id='6057881002540274780'>πŸ₯³</tg-emoji></i>" +228                      "</blockquote>";229                      230    // βœ… FIX: "Processing your order..." wala purana message ab delete ho jaata231    // hai, taaki chat me sirf final key-delivery message rahe.232    try {233      var procMsgId = Bot.getProperty("gen_msg_id_" + userId) || User.getProperty("gen_msg_id_" + userId);234      if (procMsgId) {235        Api.deleteMessage({ chat_id: chatId, message_id: Number(procMsgId) });236        Bot.setProperty("gen_msg_id_" + userId, null, "string");237        User.setProperty("gen_msg_id_" + userId, null, "string");238      }239    } catch (cleanupErr) {}240 241    Api.sendMessage({242      chat_id: chatId,243      text: deliverText,244      parse_mode: "HTML",245      reply_markup: keyDeliveryMarkup246    });247 248    var adminId = "7839151435"; 249    var deliveryMethodLabel = isApiDelivery ? "API" : "MANUAL STOCK";250    var adminMsg = "πŸ”” <b>NEW PURCHASE DELIVERED (" + deliveryMethodLabel + ")</b> βœ”οΈ\n\n" +251                   "πŸ‘€ <b>Buyer:</b> " + firstName + " (<code>" + userId + "</code>)\n" +252                   "πŸ“¦ <b>Product:</b> " + prodName + " (ID: " + (prodId || "N/A") + ")\n" +253                   "⏳ <b>Plan:</b> " + durationDisplayW + "\n" +254                   "πŸ’Έ <b>Price Deducted:</b> β‚Ή" + price.toFixed(2) + "\n" +255                   "πŸ’³ <b>User Remaining Bal:</b> β‚Ή" + remainingBal + "\n" +256                   "πŸ”‘ <b>Key:</b> <code>" + generatedKey + "</code>" +257                   (isApiDelivery && response && response.order_id ? "\n🧾 <b>API Order:</b> <code>" + response.order_id + "</code>" : "") +258                   (isApiDelivery && response && response.expires_at ? "\n⏳ <b>Expires:</b> <code>" + response.expires_at + "</code>" : "");259                   260    Api.sendMessage({ chat_id: adminId, text: adminMsg, parse_mode: "HTML" });261 262    User.setProperty("last_pending_price", null);263    User.setProperty("last_pending_prod_name", null);264    User.setProperty("last_pending_plan_days", null);265    User.setProperty("last_pending_prod_id", null);266    User.setProperty("last_pending_plan_unit", null);267 268  } else {269    // STEP 4: BOTH FAILED (System goes into error notification mode)270    Api.sendMessage({271      chat_id: chatId,272      text: "⏳ <b>Wait some time admin will stock refill soon</b>\n<i>Your funds were not deducted.</i>",273      parse_mode: "HTML"274    });275 276    var webBalance = "Low/Empty";277    var websiteErrorReason = "Website API Empty Response / Down";278    279    if (response) {280      webBalance = response.balance || response.website_balance || "Low/Empty";281      websiteErrorReason = response.msg || response.message || "Low Balance / Out of Stock";282    }283 284    var alertAdminId = "7839151435";285    var lowBalanceAdminMsg = "⚠️ <b>LOW BALANCE IN WEBSITE / API ERROR</b>\n" +286                             "━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" +287                             "πŸ›’ <b>PRODUCT DETAILS:</b>\n" +288                             "πŸ“¦ <b>Product Name:</b> <code>" + prodName + "</code>\n" +289                             "πŸ†” <b>Product ID:</b> <code>" + (prodId || "Not Passed") + "</code>\n" +290                             "⏳ <b>Days:</b> <code>" + pDaysNumOnly + " Days</code>\n" +291                             "πŸ’° <b>Your Balance Website:</b> <code>" + webBalance + "</code>\n" +292                             "ℹ️ <b>API Reason:</b> <code>" + websiteErrorReason + "</code>\n\n" +293                             "πŸ‘€ <b>USER DETAILS:</b>\n" +294                             "πŸ—£ <b>User Name:</b> " + usernameText + "\n" +295                             "πŸ“› <b>Name:</b> " + firstName + "\n" +296                             "πŸ†” <b>User ID:</b> <code>" + userId + "</code>\n" +297                             "πŸ’³ <b>Available Balance (User Wallet):</b> β‚Ή" + currentWalletBal + "\n\n" +298                             "πŸ“Œ <i>Action Required: Please refill your website API or add/deliver the key manually to this user!</i>";299 300    Api.sendMessage({ chat_id: alertAdminId, text: lowBalanceAdminMsg, parse_mode: "HTML" });301  }302} catch (e) {303  Bot.sendMessage("❌ Error executing delivery pipeline: " + e.message);304}