indrajitghosh20006/Testseller_01botPublic · Bot Template
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
commands/_execute_id_buy.js
javascript · 286 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 === "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}