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/_execute_id_buy.js
javascript · 292 lines
1/**#command2name: /execute_id_buy3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12// =========================================================13// 🛒 COMMAND = /execute_id_buy14// STATUS: FIXED - Real QR HTTP call + FF ID flow tracking for delivery after QR pay15// =========================================================16 17try {18 if (!params || typeof params !== "string") return;19 20 let data = params.split(" ");21 let rawType = data[0] ? data[0].toLowerCase().trim() : "";22 let actionState = data[1] ? data[1].toLowerCase().trim() : "";23 24 // Safe Callback Query ID & Context Extraction25 let queryId = request.id || (request.callback_query && request.callback_query.id);26 let userId = user.telegramid.toString().trim(); 27 let chatID = chat.chatid;28 29 // ===================================================30 // 👑 DYNAMIC PRICING SYSTEM & CATEGORY RESOLVER31 // ===================================================32 let rawResellers = Bot.getProperty("resellers_list");33 let resellers = [];34 35 if (rawResellers) {36 if (Array.isArray(rawResellers)) {37 resellers = rawResellers;38 } else if (typeof rawResellers === "string") {39 try { resellers = JSON.parse(rawResellers); } catch(e) { resellers = rawResellers.split(","); }40 } else if (typeof rawResellers === "object") {41 resellers = rawResellers.resellers || rawResellers.list || rawResellers.users || Object.values(rawResellers);42 }43 }44 if (!Array.isArray(resellers)) { resellers = []; }45 46 // Check if User is Reseller OR Admin47 let isReseller = resellers.map(function(id) {48 return id ? id.toString().toLowerCase().trim() : "";49 }).includes(userId) || (userId === "8963001413");50 51 let finalCost = 0;52 let stockData = [];53 let displayTypeName = "";54 let isDynamicCategory = false;55 let isGeneralCategory = false;56 let selectedCat = null;57 58 // ✅ FIX: BJS getProperty doesn't reliably take a default 2nd arg — use || [] pattern everywhere59 let fbCategories = Bot.getProperty("fb_categories") || [];60 if (!Array.isArray(fbCategories)) { fbCategories = []; }61 62 if (rawType.startsWith("fb_")) {63 isDynamicCategory = true;64 let targetCatId = rawType.replace("fb_", "").trim();65 66 for (let i = 0; i < fbCategories.length; i++) {67 if (fbCategories[i].id === targetCatId) {68 selectedCat = fbCategories[i];69 break;70 }71 }72 73 if (!selectedCat) {74 if (queryId) Api.answerCallbackQuery({ callback_query_id: String(queryId), text: "❌ Category deleted!", show_alert: true });75 return;76 }77 78 if (isReseller && selectedCat.reseller_price !== undefined && selectedCat.reseller_price !== "") {79 finalCost = Number(selectedCat.reseller_price);80 } else {81 finalCost = Number(selectedCat.price || 0);82 }83 stockData = selectedCat.stock_list || [];84 displayTypeName = selectedCat.name;85 } else if (rawType == "fb" || rawType == "google") {86 let priceRes = parseFloat(Bot.getProperty("price_res_" + rawType) || 0);87 let priceNorm = parseFloat(Bot.getProperty("price_norm_" + rawType) || 0);88 finalCost = isReseller ? priceRes : priceNorm;89 stockData = Bot.getProperty("ff_stock_" + rawType) || [];90 displayTypeName = rawType.toUpperCase();91 } else {92 var categories = Bot.getProperty("ff_categories") || {};93 if (!categories[rawType]) {94 if (queryId) Api.answerCallbackQuery({ callback_query_id: String(queryId), text: "❌ Invalid Product!", show_alert: true });95 return;96 }97 isGeneralCategory = true;98 selectedCat = categories[rawType];99 100 if (isReseller) {101 if (selectedCat.reseller_price !== undefined && selectedCat.reseller_price !== "" && selectedCat.reseller_price !== null && Number(selectedCat.reseller_price) > 0) {102 finalCost = Number(selectedCat.reseller_price);103 } else if (selectedCat.price !== undefined && selectedCat.price !== "" && selectedCat.price !== null) {104 finalCost = Number(selectedCat.price); 105 } else {106 finalCost = Number(selectedCat.normal_price || 0);107 }108 } else {109 finalCost = Number(selectedCat.normal_price || selectedCat.price || 0);110 }111 112 let fallbackStock = Bot.getProperty("ff_stock_" + rawType) || [];113 stockData = (selectedCat.stock_list && selectedCat.stock_list.length > 0) ? selectedCat.stock_list : fallbackStock;114 displayTypeName = selectedCat.name;115 }116 117 // Out of stock hard block check118 if (!stockData || stockData.length === 0) {119 if (queryId) {120 Api.answerCallbackQuery({121 callback_query_id: String(queryId),122 text: "❌ Stock is empty! Cannot process purchase.",123 show_alert: true124 });125 } else {126 Api.sendMessage({ chat_id: chatID, text: "❌ Out of stock items cannot be processed." });127 }128 return;129 }130 131 // Wallet engine balance extraction sequence132 var userRes = Libs.ResourcesLib.userRes("balance");133 var bonusBal = Bot.getProperty("balance" + userId) || 0;134 var unifiedTotalBalance = Number(userRes.value()) + Number(bonusBal);135 136 // 🚨 INSUFFICIENT BALANCE SYSTEM -> REDIRECT TO QR WITH SHORTAGE AMOUNT137 if (unifiedTotalBalance < finalCost) {138 var needToPay = finalCost - unifiedTotalBalance;139 140 // Save details for QR generation pipeline141 User.setProperty("buy_price", finalCost, "number");142 User.setProperty("buy_needpay", needToPay, "number");143 User.setProperty("buy_prod_name", displayTypeName, "string");144 145 // ✅ FIX: Tag this purchase as an FF-ID stock-based flow so /onBuyCheck146 // knows to deliver from local stock instead of the plan-based external API147 User.setProperty("buy_flow_type", "ffid", "string");148 User.setProperty("buy_ffid_rawtype", rawType, "string");149 User.setProperty("buy_ffid_is_reseller", isReseller ? true : false, "boolean");150 151 if (queryId) {152 Api.answerCallbackQuery({ 153 callback_query_id: String(queryId), 154 text: "⚠️ Balance low! Generating QR for ₹" + needToPay + "...", 155 show_alert: true 156 });157 }158 159 // ✅ FIX: Actually call the payment server for a QR instead of directly160 // triggering /onBuyQR (which needs a real HTTP response in `content`)161 var targetUrl = "https://fampay.anujbots.xyz/qr.php?upi=" + encodeURIComponent("mansuri-sarfaraz@fam") + "&amount=" + encodeURIComponent(needToPay);162 163 Api.sendMessage({164 chat_id: chatID,165 text: "<b>📉 Requesting QR from server...\n<code>" + targetUrl + "</code></b>",166 parse_mode: "HTML"167 });168 169 HTTP.get({170 url: targetUrl,171 success: "/onBuyQR",172 error: "/onBuyQR"173 });174 return;175 }176 177 // Deduct balanced values systematically178 if (bonusBal >= finalCost) {179 Bot.setProperty("balance" + userId, bonusBal - finalCost, "number");180 } else {181 var remainingDeduction = finalCost - bonusBal;182 Bot.setProperty("balance" + userId, 0, "number");183 userRes.remove(remainingDeduction);184 }185 186 // Shift asset entry from inventory safely187 var accountExtracted = stockData.shift();188 189 // Stock data save back logic190 if (isDynamicCategory && selectedCat) {191 selectedCat.stock_list = stockData;192 Bot.setProperty("fb_categories", fbCategories, "json");193 } else if (isGeneralCategory && selectedCat) {194 selectedCat.stock_list = stockData;195 var categories = Bot.getProperty("ff_categories") || {};196 categories[rawType] = selectedCat;197 Bot.setProperty("ff_categories", categories, "json");198 Bot.setProperty("ff_stock_" + rawType, stockData, "json");199 } else {200 Bot.setProperty("ff_stock_" + rawType, stockData, "json");201 }202 203 // ===================================================204 // ⚡ CRITICAL SPLIT & BOUNDARY ISOLATION205 // ===================================================206 var fullRawString = String(accountExtracted || "").trim();207 var emailData = fullRawString;208 var passwordData = "No Password Found";209 210 if (fullRawString.indexOf("|") !== -1) {211 var lastPipeIndex = fullRawString.lastIndexOf("|");212 var firstPart = fullRawString.substring(0, lastPipeIndex).trim();213 var secondPart = fullRawString.substring(lastPipeIndex + 1).trim();214 215 if (firstPart.indexOf(" ") !== -1) {216 var spaceParts = firstPart.split(" ");217 emailData = spaceParts[spaceParts.length - 1].trim();218 } else {219 emailData = firstPart;220 }221 passwordData = secondPart;222 }223 224 // ===================================================225 // 💾 AUTOMATIC HISTORY STORAGE ENGINE226 // ===================================================227 let purchasedKeys = User.getProperty("my_purchased_keys") || [];228 if (!Array.isArray(purchasedKeys)) { purchasedKeys = []; }229 230 let currentDate = new Date().toLocaleDateString('en-IN', { timeZone: 'Asia/Kolkata' });231 purchasedKeys.push({232 productName: displayTypeName,233 cost: finalCost.toString(),234 key: emailData + (passwordData !== "No Password Found" ? " | " + passwordData : ""),235 days: "Permanent", 236 date: currentDate237 });238 User.setProperty("my_purchased_keys", purchasedKeys, "json");239 240 // ===================================================241 // ⭐ COMPACT USER DISPLAY LOGIC242 // ===================================================243 var deliveryText = 244 "┏━━━━━━━━━━━━━━━━━━━━━━━━┓\n" +245 "┃ <tg-emoji emoji-id='6267140231632262769'>❤️🔥</tg-emoji> <b>PURCHASE SUCCESSFUL!</b> <tg-emoji emoji-id='6267140231632262769'>❤️🔥</tg-emoji> ┃\n" +246 "┗━━━━━━━━━━━━━━━━━━━━━━━━┛\n\n" +247 "<tg-emoji emoji-id='5463172695132745432'>📦</tg-emoji> <b>Item:</b> <code>" + displayTypeName + "</code>\n" +248 "<tg-emoji emoji-id='6267068789146260253'>💰</tg-emoji> <b>Paid:</b> <code>₹" + finalCost + "</code> " + (isReseller ? "<b>(Reseller)</b>" : "") + "\n" +249 "━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +250 "<tg-emoji emoji-id='6145572393499762737'>👤</tg-emoji> <b>ACCOUNT DETAILS:</b>\n\n" +251 "<tg-emoji emoji-id='6041705726206808304'>🚀</tg-emoji> <b>Email:</b> <code>" + emailData + "</code>\n" +252 "<tg-emoji emoji-id='5902002809573740949'>🔒</tg-emoji> <b>Password:</b> <code>" + passwordData + "</code>\n" +253 "━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +254 "<tg-emoji emoji-id='5210956306952758910'>⚠️</tg-emoji> <i>Copy details instantly.</i>";255 256 Api.sendMessage({257 chat_id: chatID,258 text: deliveryText,259 parse_mode: "HTML"260 });261 262 if (queryId) {263 Api.answerCallbackQuery({264 callback_query_id: String(queryId),265 text: "✅ Released Successfully!",266 show_alert: false267 });268 }269 270 // ===================================================271 // 🔔 COMPACT ADMIN NOTIFICATION PIPELINE272 // ===================================================273 var adminLogChannel = "8963001413"; 274 var adminNotificationMsg = 275 "<blockquote><tg-emoji emoji-id='5447644880824181073'>⚠️</tg-emoji> <b>NEW ORDER ALERT</b>" + (isReseller ? " [RESELLER]" : "") + "</blockquote>\n" +276 "👤 <b>User:</b> <a href='tg://user?id=" + userId + "'>" + user.first_name + "</a> (<code>" + userId + "</code>)\n" +277 "📦 <b>Item:</b> <code>" + displayTypeName + "</code>\n" +278 "💰 <b>Revenue:</b> <code>₹" + finalCost + "</code>\n" +279 "⚡ <b>Stock Left:</b> <code>" + stockData.length + " units</code>\n\n" +280 "🖥 <b>ACCOUNT DETAILS:</b>\n" +281 "➔ <b>Email:</b> <code>" + emailData + "</code>\n" +282 "➔ <b>Password:</b> <code>" + passwordData + "</code>";283 284 Api.sendMessage({285 chat_id: adminLogChannel,286 text: adminNotificationMsg,287 parse_mode: "HTML"288 });289 290} catch(e) {291 Bot.sendMessage("Critical Execution Failure Module Error: " + e.message);292}