mansuriamaan803/SANJEEVFFSTORE_botPublic · Bot Template
AIThis bot is a commerce platform for selling digital products, primarily focused on FreeFire accounts and related services. It provides admin tools for managing products, categories, stock, reseller roles, and a balance system for user payments. Users can browse products, apply coupons, and check their balance through an interactive interface with premium emojis and inline keyboards.
Commercecommercestoreproductsresellerbalancecoupon
102 commands0 envUpdated 12d agoCreated Aug 26, 2026
commands/_onWebKeyReceive.js
javascript · 257 lines
1/**#command2name: /onWebKeyReceive3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12try { 13 // Parse response safely only if content exists14 var response = null;15 if (typeof content === "string" && content.trim() !== "") {16 try {17 response = JSON.parse(content);18 } catch (e) {19 // Keep response as null if JSON parsing fails20 }21 }22 23 var userId = user.telegramid;24 var chatId = chat.chatid;25 26 // 🔄 PRODUCT DATA ACCURACY CORE (DYNAMIC)27 var dataOptions = options || {}; 28 29 // 🆔 1. PRODUCT ID LAYER (Added for flawless API requests)30 var prodId = dataOptions.prod_id || dataOptions.id || dataOptions.product_id || User.getProperty("last_pending_prod_id") || null;31 32 // 2. Raw options fallback mechanisms33 var rawProdName = dataOptions.prod_name || dataOptions.product || dataOptions.name || User.getProperty("last_pending_prod_name") || "Product";34 var planDays = String(dataOptions.plan_days || dataOptions.days || User.getProperty("last_pending_plan_days") || "1");35 var pDaysNumOnly = planDays.replace(/[^0-9]/g, "").trim(); 36 var planUnit = dataOptions.plan_unit || User.getProperty("last_pending_plan_unit") || "day";37 var unitLabelWordW = (planUnit === "hour") ? (Number(pDaysNumOnly) === 1 ? "Hour" : "Hours") :38 (planUnit === "minute") ? (Number(pDaysNumOnly) === 1 ? "Minute" : "Minutes") :39 (Number(pDaysNumOnly) === 1 ? "Day" : "Days");40 var durationDisplayW = pDaysNumOnly + " " + unitLabelWordW;41 42 // 3. Database validation layer to completely kill the "Product" fallback string bug43 var productList = Bot.getProperty("stored_products") || [];44 var prodName = rawProdName.trim(); 45 46 // ⚡ DEEP ADVANCED DATABASE SEARCH MATCH (Matches by ID first if available, then name)47 if (productList.length > 0) {48 var checkTerm = prodName.toLowerCase();49 var foundMatch = false;50 51 for (var i = 0; i < productList.length; i++) {52 var dbItem = productList[i];53 var dbName = dbItem.name ? dbItem.name.trim() : "";54 var dbId = dbItem.id || null;55 56 // If ID matches directly, use it!57 if (prodId && dbId && String(prodId) === String(dbId)) {58 prodName = dbName;59 foundMatch = true;60 break;61 }62 63 if (!dbName) continue;64 65 if (dbName.toLowerCase() === checkTerm || 66 (checkTerm !== "product" && (checkTerm.indexOf(dbName.toLowerCase()) > -1 || dbName.toLowerCase().indexOf(checkTerm) > -1))) {67 prodName = dbName; 68 if (dbId) { prodId = dbId; } // Backfill ID if name matched69 foundMatch = true;70 break;71 }72 }73 74 if (!foundMatch || prodName.toLowerCase() === "product") {75 var lastPending = User.getProperty("last_pending_prod_name");76 if (lastPending && lastPending.toLowerCase() !== "product") {77 prodName = lastPending.trim();78 } else if (productList.length === 1) {79 prodName = productList[0].name.trim();80 if (productList[0].id) { prodId = productList[0].id; }81 }82 }83 }84 85 var price = Number(dataOptions.price) || Number(User.getProperty("last_pending_price")) || 0;86 var firstName = dataOptions.first_name || user.first_name || "User";87 var usernameText = user.username ? "@" + user.username : "No Username";88 var currentWalletBal = Libs.ResourcesLib.userRes("balance").value().toFixed(2);89 90 var generatedKey = null;91 var isApiDelivery = false;92 var isBackupUsed = false;93 94 var cleanProdNameUpper = prodName.trim().toUpperCase();95 var manualKeysStorageKey = "manual_keys_" + cleanProdNameUpper + "_" + pDaysNumOnly;96 var backupStockKey = "stock_" + prodName.trim() + "_" + pDaysNumOnly + "_Day";97 98 // ⚡ STEP 1: FORCE CHECK MANUAL STOCK (CRITICAL OVERRIDE)99 var manualStock = Bot.getProperty(manualKeysStorageKey);100 101 if (!manualStock || (Array.isArray(manualStock) && manualStock.length === 0)) {102 manualStock = Bot.getProperty(backupStockKey);103 isBackupUsed = true;104 }105 106 if (typeof manualStock === "string" && manualStock.trim() !== "") {107 try {108 manualStock = JSON.parse(manualStock);109 } catch(err) {110 manualStock = manualStock.split("\n").map(function(k) { return k.trim(); }).filter(Boolean);111 }112 }113 114 if (Array.isArray(manualStock) && manualStock.length > 0) {115 generatedKey = manualStock.shift(); 116 117 if (isBackupUsed) {118 Bot.setProperty(backupStockKey, manualStock, "json");119 var mainStock = Bot.getProperty(manualKeysStorageKey) || [];120 if (typeof mainStock === "string") { mainStock = mainStock.split("\n").map(function(k) { return k.trim(); }).filter(Boolean); }121 if (Array.isArray(mainStock)) {122 var idx = mainStock.indexOf(generatedKey);123 if (idx > -1) { mainStock.splice(idx, 1); }124 Bot.setProperty(manualKeysStorageKey, mainStock, "json");125 }126 } else {127 Bot.setProperty(manualKeysStorageKey, manualStock, "json");128 var backupStock = Bot.getProperty(backupStockKey) || [];129 if (typeof backupStock === "string") { backupStock = backupStock.split("\n").map(function(k) { return k.trim(); }).filter(Boolean); }130 if (Array.isArray(backupStock)) {131 var idx = backupStock.indexOf(generatedKey);132 if (idx > -1) { backupStock.splice(idx, 1); }133 Bot.setProperty(backupStockKey, backupStock, "json");134 }135 }136 }137 138 // ⚡ STEP 2: FALLBACK TO API KEYS (IF NO MANUAL STOCK WAS FOUND)139 if (!generatedKey && response && response.status === "success") {140 generatedKey = response.key || response.code || response.serial;141 if (generatedKey) {142 isApiDelivery = true;143 }144 }145 146 // STEP 3: SUCCESS DELIVERY MECHANICS147 if (generatedKey) {148 Libs.ResourcesLib.userRes("balance").add(-price);149 150 var pastSpent = Bot.getProperty("total_spent_by_" + userId) || 0;151 Bot.setProperty("total_spent_by_" + userId, Number(pastSpent) + price, "number");152 153 var userKeysHistory = User.getProperty("my_purchased_keys") || [];154 userKeysHistory.push({155 product: prodName,156 product_id: prodId,157 days: pDaysNumOnly,158 price: price,159 key: generatedKey,160 date: new Date().toLocaleDateString()161 });162 User.setProperty("my_purchased_keys", userKeysHistory, "json");163 164 var remainingBal = Libs.ResourcesLib.userRes("balance").value().toFixed(2);165 166 var updateLinkForKey = Bot.getProperty("update_channel_link");167 var keyDeliveryButtons = [[{ text: "📋 Copy Key", copy_text: { text: generatedKey } }]];168 if (updateLinkForKey) {169 keyDeliveryButtons.push([{ text: "📥 Join Updates", url: updateLinkForKey, style: "primary", icon_custom_emoji_id: "6091571559233755994" }]);170 }171 keyDeliveryButtons.push([{ text: "Back to Menu", callback_data: "/back", style: "primary", icon_custom_emoji_id: "5893163582194978381" }]);172 var keyDeliveryMarkup = JSON.stringify({ inline_keyboard: keyDeliveryButtons });173 174 var deliverText = "<blockquote>" +175 "<tg-emoji emoji-id='5350447674971660988'>✅</tg-emoji> <b>PURCHASE SUCCESSFUL!</b>\n\n" +176 "<tg-emoji emoji-id='6147767796097884213'>📦</tg-emoji> <b>Product:</b> <code>" + prodName + "</code>\n" +177 "<tg-emoji emoji-id='6284816251143331422'>🗝</tg-emoji> <b>Validity:</b> <code>" + durationDisplayW + "</code>\n" +178 "<tg-emoji emoji-id='5352825278672412291'>👆</tg-emoji> <b>Your Key:</b> <code>" + generatedKey + "</code>\n\n" +179 "━━━━━ <tg-emoji emoji-id='6147934084346682063'>#⃣</tg-emoji> <b>BALANCE DETAILS</b> ━━━━━\n" +180 "<tg-emoji emoji-id='6195037488898121775'>✨</tg-emoji> <b>Total Invest:</b> ₹" + price.toFixed(2) + "\n" +181 "<tg-emoji emoji-id='5409048419211682843'>💵</tg-emoji> <b>New Wallet Balance:</b> ₹" + remainingBal + "\n\n" +182 "<i>Enjoy your purchase. <tg-emoji emoji-id='6057881002540274780'>🥳</tg-emoji></i>" +183 "</blockquote>";184 185 // ✅ FIX: "Processing your order..." wala purana message ab delete ho jaata186 // hai, taaki chat me sirf final key-delivery message rahe.187 try {188 var procMsgId = Bot.getProperty("gen_msg_id_" + userId) || User.getProperty("gen_msg_id_" + userId);189 if (procMsgId) {190 Api.deleteMessage({ chat_id: chatId, message_id: Number(procMsgId) });191 Bot.setProperty("gen_msg_id_" + userId, null, "string");192 User.setProperty("gen_msg_id_" + userId, null, "string");193 }194 } catch (cleanupErr) {}195 196 Api.sendMessage({197 chat_id: chatId,198 text: deliverText,199 parse_mode: "HTML",200 reply_markup: keyDeliveryMarkup201 });202 203 var adminId = "8963001413"; 204 var deliveryMethodLabel = isApiDelivery ? "API" : "MANUAL STOCK";205 var adminMsg = "🔔 <b>NEW PURCHASE DELIVERED (" + deliveryMethodLabel + ")</b> ✔️\n\n" +206 "👤 <b>Buyer:</b> " + firstName + " (<code>" + userId + "</code>)\n" +207 "📦 <b>Product:</b> " + prodName + " (ID: " + (prodId || "N/A") + ")\n" +208 "⏳ <b>Plan:</b> " + durationDisplayW + "\n" +209 "💸 <b>Price Deducted:</b> ₹" + price.toFixed(2) + "\n" +210 "💳 <b>User Remaining Bal:</b> ₹" + remainingBal + "\n" +211 "🔑 <b>Key:</b> <code>" + generatedKey + "</code>";212 213 Api.sendMessage({ chat_id: adminId, text: adminMsg, parse_mode: "HTML" });214 215 User.setProperty("last_pending_price", null);216 User.setProperty("last_pending_prod_name", null);217 User.setProperty("last_pending_plan_days", null);218 User.setProperty("last_pending_prod_id", null);219 User.setProperty("last_pending_plan_unit", null);220 221 } else {222 // STEP 4: BOTH FAILED (System goes into error notification mode)223 Api.sendMessage({224 chat_id: chatId,225 text: "⏳ <b>Wait some time admin will stock refill soon</b>\n<i>Your funds were not deducted.</i>",226 parse_mode: "HTML"227 });228 229 var webBalance = "Low/Empty";230 var websiteErrorReason = "Website API Empty Response / Down";231 232 if (response) {233 webBalance = response.balance || response.website_balance || "Low/Empty";234 websiteErrorReason = response.msg || response.message || "Low Balance / Out of Stock";235 }236 237 var alertAdminId = "8963001413";238 var lowBalanceAdminMsg = "⚠️ <b>LOW BALANCE IN WEBSITE / API ERROR</b>\n" +239 "━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" +240 "🛒 <b>PRODUCT DETAILS:</b>\n" +241 "📦 <b>Product Name:</b> <code>" + prodName + "</code>\n" +242 "🆔 <b>Product ID:</b> <code>" + (prodId || "Not Passed") + "</code>\n" +243 "⏳ <b>Days:</b> <code>" + pDaysNumOnly + " Days</code>\n" +244 "💰 <b>Your Balance Website:</b> <code>" + webBalance + "</code>\n" +245 "ℹ️ <b>API Reason:</b> <code>" + websiteErrorReason + "</code>\n\n" +246 "👤 <b>USER DETAILS:</b>\n" +247 "🗣 <b>User Name:</b> " + usernameText + "\n" +248 "📛 <b>Name:</b> " + firstName + "\n" +249 "🆔 <b>User ID:</b> <code>" + userId + "</code>\n" +250 "💳 <b>Available Balance (User Wallet):</b> ₹" + currentWalletBal + "\n\n" +251 "📌 <i>Action Required: Please refill your website API or add/deliver the key manually to this user!</i>";252 253 Api.sendMessage({ chat_id: alertAdminId, text: lowBalanceAdminMsg, parse_mode: "HTML" });254 }255} catch (e) {256 Bot.sendMessage("❌ Error executing delivery pipeline: " + e.message);257}