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.

Commercefreefiregame-hacksupi-paymentsqr-codesreseller-systemdynamic-pricing
ProfileTelegram
102 commands0 envUpdated 16d agoCreated Aug 22, 2026
Back to folder

commands/_confirm_buyitem.js

javascript ยท 310 lines

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