ashoksarande3/ASHOK_HACK_STORE_BOTPublic ยท Bot Template
AIThis bot operates as a commercial storefront for selling Free Fire game hacks and cheats via UPI QR code payments. It features a dynamic pricing system with separate normal and reseller prices, product plans with flexible durations (days, hours, minutes), and a reseller program requiring a one-time upgrade fee. The bot handles payment verification through QR code generation and expiry tracking, user verification via Telegram contact sharing, and admin tools for stock management, plan creation, and ownership transfer. It includes a balance system, maintenance mode, and Telegram Stars payment fallback. The codebase uses TeleBotHost's TBL JavaScript APIs (Bot, Api, HTTP, db properties, Libs) for all logic.
commands/_confirm_buyitem.js
javascript ยท 310 lines
1/**#command2name: /confirm_buyitem3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12// =========================================================13// โ
ACTUAL PURCHASE EXECUTION โ runs after user taps "Confirm" on the14// premium confirmation screen, OR automatically right after a shortfall15// QR payment is verified (see _onCheck.js), so key delivery is fully automatic.16// =========================================================17 18try {19 var productList = Bot.getProperty("stored_products") || [];20 var chatId = chat.chatid;21 var userId = user.telegramid;22 23 var parts = params ? String(params).trim().split(" ") : [];24 var prodIdx = Number(parts[0]);25 var planIdx = Number(parts[1]);26 27 var product = productList[prodIdx];28 if (!product || !product.plans || !product.plans[planIdx]) {29 Api.sendMessage({ chat_id: chatId, text: "โ Product or Plan configuration missing!" });30 return;31 }32 33 var plan = product.plans[planIdx];34 var planUnit = plan.unit || "day";35 var isReseller = Bot.getProperty("is_reseller_" + userId) === true;36 37 var cleanProdName = product.name.trim().toUpperCase();38 var cleanPlanDays = String(plan.days).replace(/[^0-9.]/g, "").trim();39 var unitLabelWord = (planUnit === "hour") ? (Number(cleanPlanDays) === 1 ? "Hour" : "Hours") :40 (planUnit === "minute") ? (Number(cleanPlanDays) === 1 ? "Minute" : "Minutes") :41 (Number(cleanPlanDays) === 1 ? "Day" : "Days");42 var durationDisplay = plan.durationDisplay || (cleanPlanDays + " " + unitLabelWord);43 44 var priceKeySuffix = (planUnit === "day") ? cleanPlanDays : (cleanPlanDays + "_" + planUnit);45 var normalKey = "price_normal_" + cleanProdName + "_" + priceKeySuffix;46 var resellerKey = "price_reseller_" + cleanProdName + "_" + priceKeySuffix;47 48 var adminNormalPrice = Bot.getProperty(normalKey);49 var adminResellerPrice = Bot.getProperty(resellerKey);50 51 var currentNormal = (adminNormalPrice !== undefined && adminNormalPrice !== null) ? adminNormalPrice : plan.normal_price;52 var currentReseller = (adminResellerPrice !== undefined && adminResellerPrice !== null) ? adminResellerPrice : plan.reseller_price;53 54 var originalPrice = isReseller ? Number(currentReseller) : Number(currentNormal);55 var price = originalPrice;56 57 var planSpecificDiscKey = "auto_discount_" + cleanProdName + "_" + cleanPlanDays + "_" + planUnit.toUpperCase();58 var productWideDiscKey = "auto_discount_" + cleanProdName + "_ALL";59 var autoDiscountPercent = Bot.getProperty(planSpecificDiscKey) || Bot.getProperty(productWideDiscKey) || Bot.getProperty("auto_discount_global") || 0;60 61 // ๐ Apply coupon discount (if any was applied for this exact prod/plan) โ coupon overrides auto-discount62 var appliedCouponCode = User.getProperty("applied_coupon_" + prodIdx + "_" + planIdx);63 var couponDiscountPercent = 0;64 if (appliedCouponCode) {65 var couponRec0 = Bot.getProperty("coupon_" + appliedCouponCode);66 if (couponRec0 && couponRec0.discountPercent) {67 couponDiscountPercent = couponRec0.discountPercent;68 price = Number((originalPrice * (1 - couponDiscountPercent / 100)).toFixed(2));69 }70 User.setProperty("applied_coupon_" + prodIdx + "_" + planIdx, null, "string");71 } else if (autoDiscountPercent > 0) {72 couponDiscountPercent = autoDiscountPercent;73 price = Number((originalPrice * (1 - autoDiscountPercent / 100)).toFixed(2));74 }75 76 // ๐ก๏ธ Safety re-check: balance abhi bhi sufficient hai ya nahi (race-condition guard)77 var unifiedBal = (function () {78 var resBal = 0;79 try { resBal = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (e) {}80 var bonusBal = Number(Bot.getProperty("balance" + userId) || 0);81 return resBal + bonusBal;82 })();83 84 if (unifiedBal < price) {85 Api.sendMessage({86 chat_id: chatId,87 text: "โ ๏ธ <b>Balance abhi kam hai.</b> Kripya phir se try karein.",88 parse_mode: "HTML"89 });90 return;91 }92 93 // =====================================================94 // ๐ STEP 0 โ MANUAL STOCK FIRST CHECK (โ
NEW)95 // Agar admin ne manually koi key already daal rakhi hai, to wahi seedha96 // deliver karo aur PAID EXTERNAL API ko bilkul call hi mat karo โ taaki97 // "1 available key ke liye 2 keys spend" (1 manual + 1 wasted API buy)98 // wala bug kabhi na ho. API sirf tabhi call hoga jab manual stock khaali ho.99 // =====================================================100 var pDaysNumOnly = cleanPlanDays;101 var manualKeysStorageKey = "manual_keys_" + cleanProdName + "_" + pDaysNumOnly;102 var backupStockKey = "stock_" + product.name.trim() + "_" + pDaysNumOnly + "_Day";103 var isBackupUsed = false;104 105 var manualStock = Bot.getProperty(manualKeysStorageKey);106 if (!manualStock || (Array.isArray(manualStock) && manualStock.length === 0)) {107 manualStock = Bot.getProperty(backupStockKey);108 isBackupUsed = true;109 }110 if (typeof manualStock === "string" && manualStock.trim() !== "") {111 try {112 manualStock = JSON.parse(manualStock);113 } catch (err) {114 manualStock = manualStock.split("\n").map(function (k) { return k.trim(); }).filter(Boolean);115 }116 }117 118 if (Array.isArray(manualStock) && manualStock.length > 0) {119 var generatedKey = manualStock.shift();120 121 if (isBackupUsed) {122 Bot.setProperty(backupStockKey, manualStock, "json");123 var mainStock = Bot.getProperty(manualKeysStorageKey) || [];124 if (typeof mainStock === "string") { mainStock = mainStock.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }125 if (Array.isArray(mainStock)) {126 var idx1 = mainStock.indexOf(generatedKey);127 if (idx1 > -1) { mainStock.splice(idx1, 1); }128 Bot.setProperty(manualKeysStorageKey, mainStock, "json");129 }130 } else {131 Bot.setProperty(manualKeysStorageKey, manualStock, "json");132 var backupStock2 = Bot.getProperty(backupStockKey) || [];133 if (typeof backupStock2 === "string") { backupStock2 = backupStock2.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }134 if (Array.isArray(backupStock2)) {135 var idx2 = backupStock2.indexOf(generatedKey);136 if (idx2 > -1) { backupStock2.splice(idx2, 1); }137 Bot.setProperty(backupStockKey, backupStock2, "json");138 }139 }140 141 // ๐ฐ Deduct balance + record purchase (same accounting as API path)142 Libs.ResourcesLib.userRes("balance").add(-price);143 var pastSpent2 = Bot.getProperty("total_spent_by_" + userId) || 0;144 Bot.setProperty("total_spent_by_" + userId, Number(pastSpent2) + price, "number");145 146 var keysHistory2 = User.getProperty("my_purchased_keys") || [];147 keysHistory2.push({148 product: String(product.name).trim(),149 product_id: product.id || null,150 days: pDaysNumOnly,151 price: price,152 key: generatedKey,153 date: new Date().toLocaleDateString()154 });155 User.setProperty("my_purchased_keys", keysHistory2, "json");156 157 var remainingBal2 = Libs.ResourcesLib.userRes("balance").value().toFixed(2);158 159 // โ
NEW: Key ke saath automatic "Join Updates" button attach hota hai (agar admin ne link set kiya ho)160 var updateLinkForKey = Bot.getProperty("update_channel_link");161 var keyDeliveryButtons = [[{ text: "๐ Copy Key", copy_text: { text: generatedKey } }]];162 if (updateLinkForKey) {163 keyDeliveryButtons.push([{ text: "๐ฅ Join Updates", url: updateLinkForKey, style: "primary", icon_custom_emoji_id: "6091571559233755994" }]);164 }165 keyDeliveryButtons.push([{ text: "Back to Menu", callback_data: "/back", style: "primary", icon_custom_emoji_id: "5893163582194978381" }]);166 var keyDeliveryMarkup = JSON.stringify({ inline_keyboard: keyDeliveryButtons });167 168 var deliverText2 = "<blockquote>" +169 "<tg-emoji emoji-id='5350447674971660988'>โ
</tg-emoji> <b>PURCHASE SUCCESSFUL!</b>\n\n" +170 "<tg-emoji emoji-id='6147767796097884213'>๐ฆ</tg-emoji> <b>Product:</b> <code>" + String(product.name).trim() + "</code>\n" +171 "<tg-emoji emoji-id='6284816251143331422'>๐</tg-emoji> <b>Validity:</b> <code>" + durationDisplay + "</code>\n" +172 "<tg-emoji emoji-id='5352825278672412291'>๐</tg-emoji> <b>Your Key:</b> <code>" + generatedKey + "</code>\n\n" +173 "โโโโโ <tg-emoji emoji-id='6147934084346682063'>#โฃ</tg-emoji> <b>BALANCE DETAILS</b> โโโโโ\n" +174 "<tg-emoji emoji-id='6195037488898121775'>โจ</tg-emoji> <b>Total Invest:</b> โน" + price.toFixed(2) + "\n" +175 "<tg-emoji emoji-id='5409048419211682843'>๐ต</tg-emoji> <b>New Wallet Balance:</b> โน" + remainingBal2 + "\n\n" +176 "<i>Enjoy your purchase. <tg-emoji emoji-id='6057881002540274780'>๐ฅณ</tg-emoji></i>" +177 "</blockquote>";178 179 if (request && request.message) {180 try {181 Api.editMessageText({182 chat_id: String(chatId),183 message_id: Number(request.message.message_id),184 text: deliverText2,185 parse_mode: "HTML",186 reply_markup: keyDeliveryMarkup187 });188 } catch (e) {189 Api.sendMessage({ chat_id: chatId, text: deliverText2, parse_mode: "HTML", reply_markup: keyDeliveryMarkup });190 }191 } else {192 Api.sendMessage({ chat_id: chatId, text: deliverText2, parse_mode: "HTML", reply_markup: keyDeliveryMarkup });193 }194 195 var adminId3 = "8660373585";196 Api.sendMessage({197 chat_id: adminId3,198 text: "๐ <b>NEW PURCHASE DELIVERED (MANUAL STOCK)</b> โ๏ธ\n\n" +199 "๐ค <b>Buyer:</b> " + (user.first_name || "User") + " (<code>" + userId + "</code>)\n" +200 "๐ฆ <b>Product:</b> " + String(product.name).trim() + "\n" +201 "โณ <b>Plan:</b> " + durationDisplay + "\n" +202 "๐ธ <b>Price Deducted:</b> โน" + price.toFixed(2) + "\n" +203 "๐ณ <b>User Remaining Bal:</b> โน" + remainingBal2 + "\n" +204 "๐ <b>Key:</b> <code>" + generatedKey + "</code>\n\n" +205 "<i>โ
Manual stock se deliver hui โ external paid API call SKIP ki gayi.</i>",206 parse_mode: "HTML"207 });208 209 var qId0 = request ? (request.id || (request.callback_query && request.callback_query.id)) : null;210 if (qId0) {211 try { Api.answerCallbackQuery({ callback_query_id: String(qId0), text: "โ
Key Delivered!", show_alert: false }); } catch (e) {}212 }213 214 return; // ๐ซ STOP โ external API bilkul call nahi hui215 }216 217 var webProductId = String(product.id || "PID_ID").trim();218 var prodNameLower = String(product.name).toLowerCase();219 220 var durationParam = (planUnit === "hour") ? (cleanPlanDays + " Hour" + (Number(cleanPlanDays) === 1 ? "" : "s")) :221 (planUnit === "minute") ? (cleanPlanDays + " Minute" + (Number(cleanPlanDays) === 1 ? "" : "s")) :222 cleanPlanDays + " Days";223 var rawPlanName = plan.name || plan.title || plan.name_on_website || "";224 225 if (rawPlanName.trim() !== "" && isNaN(rawPlanName)) {226 durationParam = rawPlanName.trim();227 } else {228 if (prodNameLower.indexOf("pato") > -1) {229 durationParam = cleanPlanDays + " DaYs All Colours Mix";230 } else if (prodNameLower.indexOf("prime") > -1 || prodNameLower.indexOf("hook") > -1) {231 durationParam = (cleanPlanDays === "7") ? "7 Days NonRoot" : cleanPlanDays + " Days Nonroot";232 } else if (prodNameLower.indexOf("nonroot") > -1 || prodNameLower.indexOf("non root") > -1) {233 durationParam = cleanPlanDays + " DaYs NONROOT";234 } else if (prodNameLower.indexOf("all android") > -1 || prodNameLower.indexOf("mix") > -1) {235 durationParam = cleanPlanDays + " DaYs All Colours Mix";236 } else {237 durationParam = cleanPlanDays + " Days";238 }239 }240 241 var postFieldsString = "api_key=" + encodeURIComponent("4047db881702c80259f417e2283aea5b") +242 "&action=" + encodeURIComponent("buy") +243 "&product_id=" + encodeURIComponent(webProductId) +244 "&duration=" + encodeURIComponent(durationParam);245 246 var apiHeaders = {247 "Content-Type": "application/x-www-form-urlencoded",248 "x-master-key": "4047db881702c80259f417e2283aea5b"249 };250 251 User.setProperty("last_pending_price", Number(price), "number");252 User.setProperty("last_pending_prod_id", webProductId, "string");253 User.setProperty("last_pending_prod_name", String(product.name).trim(), "string");254 User.setProperty("last_pending_plan_days", cleanPlanDays, "string");255 User.setProperty("last_pending_plan_unit", planUnit, "string");256 257 var queryId = request ? (request.id || (request.callback_query && request.callback_query.id)) : null;258 259 var processingText = "<tg-emoji emoji-id='6147936236125298267'>โณ</tg-emoji> <b>Processing your order... please wait!</b>";260 if (request && request.message) {261 try {262 Api.editMessageText({263 chat_id: String(chatId),264 message_id: Number(request.message.message_id),265 text: processingText,266 parse_mode: "HTML"267 });268 // โ
FIX: is "Processing..." message ka ID save karo taaki key deliver269 // hone par ye delete ho jaaye โ pehle ye chat me hamesha stuck rehta tha.270 Bot.setProperty("gen_msg_id_" + userId, request.message.message_id, "string");271 User.setProperty("gen_msg_id_" + userId, request.message.message_id, "string");272 } catch (e) {273 var pm1 = Api.sendMessage({ chat_id: chatId, text: processingText, parse_mode: "HTML" });274 try {275 var pmid1 = (pm1 && pm1.result && pm1.result.message_id) ? pm1.result.message_id : (pm1 && pm1.message_id ? pm1.message_id : null);276 if (pmid1) { Bot.setProperty("gen_msg_id_" + userId, pmid1, "string"); User.setProperty("gen_msg_id_" + userId, pmid1, "string"); }277 } catch (e2) {}278 }279 } else {280 var pm2 = Api.sendMessage({ chat_id: chatId, text: processingText, parse_mode: "HTML" });281 try {282 var pmid2 = (pm2 && pm2.result && pm2.result.message_id) ? pm2.result.message_id : (pm2 && pm2.message_id ? pm2.message_id : null);283 if (pmid2) { Bot.setProperty("gen_msg_id_" + userId, pmid2, "string"); User.setProperty("gen_msg_id_" + userId, pmid2, "string"); }284 } catch (e2) {}285 }286 287 HTTP.post({288 url: "https://xyzcheats.com/api/reseller_v1.php",289 body: postFieldsString,290 headers: apiHeaders,291 success: "/onWebKeyReceive",292 error: "/onWebKeyError"293 });294 295 if (queryId) {296 try {297 Api.answerCallbackQuery({298 callback_query_id: String(queryId),299 text: "โณ Processing your order... Please wait!",300 show_alert: false301 });302 } catch (e) {}303 }304 305} catch (e) {306 var errChatId = (typeof chat !== "undefined" && chat && chat.chatid) ? chat.chatid : null;307 if (errChatId) {308 try { Api.sendMessage({ chat_id: errChatId, text: "โ <b>Error:</b> <code>" + e.message + "</code>", parse_mode: "HTML" }); } catch (fatal) {}309 }310}