indrajitghosh20006/Testseller_01botPublic · Bot Template

ProfileTelegram

AIThis bot provides an admin‑controlled system for managing user balances, products, and reseller roles. It includes commands to add balances (via manual input, Binance Pay, or UPI), approve and credit payments, and set up product listings with categories and pricing. Admins can also add resellers, view reseller info, and manage stock entries. The bot uses built‑in TeleBotHost APIs such as Bot, Api, HTTP, and Libs for database operations and message handling.

Commerceadminbalanceproductresellerpaymentsbinance
138 commands0 envUpdated 17h agoCreated Sep 27, 2026
Back to folder

commands/_execute_id_buy.js

javascript · 286 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 === "7839151435");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 unifiedTotalBalance = Number(userRes.value()) || 0;134 135  // 🚨 INSUFFICIENT BALANCE SYSTEM -> REDIRECT TO QR WITH SHORTAGE AMOUNT136  if (unifiedTotalBalance < finalCost) {137      var needToPay = finalCost - unifiedTotalBalance;138      139      // Save details for QR generation pipeline140      User.setProperty("buy_price", finalCost, "number");141      User.setProperty("buy_needpay", needToPay, "number");142      User.setProperty("buy_prod_name", displayTypeName, "string");143 144      // ✅ FIX: Tag this purchase as an FF-ID stock-based flow so /onBuyCheck145      // knows to deliver from local stock instead of the plan-based external API146      User.setProperty("buy_flow_type", "ffid", "string");147      User.setProperty("buy_ffid_rawtype", rawType, "string");148      User.setProperty("buy_ffid_is_reseller", isReseller ? true : false, "boolean");149 150      if (queryId) {151          Api.answerCallbackQuery({ 152              callback_query_id: String(queryId), 153              text: "⚠️ Balance low! Generating QR for ₹" + needToPay + "...", 154              show_alert: true 155          });156      }157 158      // ✅ FIX: Actually call the payment server for a QR instead of directly159      // triggering /onBuyQR (which needs a real HTTP response in `content`)160      var targetUrl = "https://fampay.anujbots.xyz/qr.php?upi=" + encodeURIComponent(Bot.getProperty("payment_upi_id") || "maidulmidya@fam") + "&amount=" + encodeURIComponent(needToPay);161 162      Api.sendMessage({163          chat_id: chatID,164          text: "<b>📉 Requesting QR from server...\n<code>" + targetUrl + "</code></b>",165          parse_mode: "HTML"166      });167 168      HTTP.get({169          url: targetUrl,170          success: "/onBuyQR",171          error: "/onBuyQR"172      });173      return;174  }175 176  // Deduct balanced values systematically177  // Single wallet deduction — prevents double-balance accounting.178  userRes.remove(finalCost);179 180  // Shift asset entry from inventory safely181  var accountExtracted = stockData.shift();182  183  // Stock data save back logic184  if (isDynamicCategory && selectedCat) {185      selectedCat.stock_list = stockData;186      Bot.setProperty("fb_categories", fbCategories, "json");187  } else if (isGeneralCategory && selectedCat) {188      selectedCat.stock_list = stockData;189      var categories = Bot.getProperty("ff_categories") || {};190      categories[rawType] = selectedCat;191      Bot.setProperty("ff_categories", categories, "json");192      Bot.setProperty("ff_stock_" + rawType, stockData, "json");193  } else {194      Bot.setProperty("ff_stock_" + rawType, stockData, "json");195  }196 197  // ===================================================198  // ⚡ CRITICAL SPLIT & BOUNDARY ISOLATION199  // ===================================================200  var fullRawString = String(accountExtracted || "").trim();201  var emailData = fullRawString;202  var passwordData = "No Password Found";203 204  if (fullRawString.indexOf("|") !== -1) {205      var lastPipeIndex = fullRawString.lastIndexOf("|");206      var firstPart = fullRawString.substring(0, lastPipeIndex).trim();207      var secondPart = fullRawString.substring(lastPipeIndex + 1).trim();208 209      if (firstPart.indexOf(" ") !== -1) {210          var spaceParts = firstPart.split(" ");211          emailData = spaceParts[spaceParts.length - 1].trim();212      } else {213          emailData = firstPart;214      }215      passwordData = secondPart;216  }217 218  // ===================================================219  // 💾 AUTOMATIC HISTORY STORAGE ENGINE220  // ===================================================221  let purchasedKeys = User.getProperty("my_purchased_keys") || [];222  if (!Array.isArray(purchasedKeys)) { purchasedKeys = []; }223  224  let currentDate = new Date().toLocaleDateString('en-IN', { timeZone: 'Asia/Kolkata' });225  purchasedKeys.push({226      productName: displayTypeName,227      cost: finalCost.toString(),228      key: emailData + (passwordData !== "No Password Found" ? " | " + passwordData : ""),229      days: "Permanent", 230      date: currentDate231  });232  User.setProperty("my_purchased_keys", purchasedKeys, "json");233 234  // ===================================================235  // ⭐ COMPACT USER DISPLAY LOGIC236  // ===================================================237  var deliveryText = 238    "┏━━━━━━━━━━━━━━━━━━━━━━━━┓\n" +239    "┃ <tg-emoji emoji-id='6267140231632262769'>❤️‍🔥</tg-emoji> <b>PURCHASE SUCCESSFUL!</b> <tg-emoji emoji-id='6267140231632262769'>❤️‍🔥</tg-emoji> ┃\n" +240    "┗━━━━━━━━━━━━━━━━━━━━━━━━┛\n\n" +241    "<tg-emoji emoji-id='5463172695132745432'>📦</tg-emoji> <b>Item:</b> <code>" + displayTypeName + "</code>\n" +242    "<tg-emoji emoji-id='6267068789146260253'>💰</tg-emoji> <b>Paid:</b> <code>₹" + finalCost + "</code> " + (isReseller ? "<b>(Reseller)</b>" : "") + "\n" +243    "━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +244    "<tg-emoji emoji-id='6145572393499762737'>👤</tg-emoji> <b>ACCOUNT DETAILS:</b>\n\n" +245    "<tg-emoji emoji-id='6041705726206808304'>🚀</tg-emoji> <b>Email:</b> <code>" + emailData + "</code>\n" +246    "<tg-emoji emoji-id='5902002809573740949'>🔒</tg-emoji> <b>Password:</b> <code>" + passwordData + "</code>\n" +247    "━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +248    "<tg-emoji emoji-id='5210956306952758910'>⚠️</tg-emoji> <i>Copy details instantly.</i>";249 250  Api.sendMessage({251      chat_id: chatID,252      text: deliveryText,253      parse_mode: "HTML"254  });255 256  if (queryId) {257      Api.answerCallbackQuery({258          callback_query_id: String(queryId),259          text: "✅ Released Successfully!",260          show_alert: false261      });262  }263 264  // ===================================================265  // 🔔 COMPACT ADMIN NOTIFICATION PIPELINE266  // ===================================================267  var adminLogChannel = "8875810358"; 268  var adminNotificationMsg = 269    "<blockquote><tg-emoji emoji-id='5447644880824181073'>⚠️</tg-emoji> <b>NEW ORDER ALERT</b>" + (isReseller ? " [RESELLER]" : "") + "</blockquote>\n" +270    "👤 <b>User:</b> <a href='tg://user?id=" + userId + "'>" + user.first_name + "</a> (<code>" + userId + "</code>)\n" +271    "📦 <b>Item:</b> <code>" + displayTypeName + "</code>\n" +272    "💰 <b>Revenue:</b> <code>₹" + finalCost + "</code>\n" +273    "⚡ <b>Stock Left:</b> <code>" + stockData.length + " units</code>\n\n" +274    "🖥 <b>ACCOUNT DETAILS:</b>\n" +275    "➔ <b>Email:</b> <code>" + emailData + "</code>\n" +276    "➔ <b>Password:</b> <code>" + passwordData + "</code>";277 278  Api.sendMessage({279      chat_id: adminLogChannel,280      text: adminNotificationMsg,281      parse_mode: "HTML"282  });283 284} catch(e) {285  Bot.sendMessage("Critical Execution Failure Module Error: " + e.message);286}