indrajitghosh20006/Igstore_01botPublic Β· Bot Template
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
commands/_onWebKeyReceive.js
javascript Β· 304 lines
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}