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
ProfileTelegram
102 commands0 envUpdated 12d agoCreated Aug 26, 2026
Back to folder

commands/_execute_id_buy.js

javascript · 292 lines

Raw
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}