pnxh2371/Ankit_mods_store_botPublic ยท Bot Template

ProfileTelegram

AI๐€ษดแด‹ษชแด› ๐Œแดแด…๊œฑ ๐’แด›แดส€แด‡ ๐Ÿ› appears to be a Telegram automation bot. Commands include /*, /addbal, /addbal_all, /addbal_binance, /addbal_binance_approve, /addbal_binance_paid, /addbal_upi, /addcat_id. Observed in code: messaging, http, libs, keyboards, payments.

Utilityutility
133 commands0 envUpdated 7h agoCreated Sep 10, 2026
Back to folder

commands/_confirm_buyitem.js

javascript ยท 423 lines

Raw
1/**#command2name: /confirm_buyitem3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12function resolveApiDuration(plan, cleanPlanDays, planUnit, productNameOverride) {13  // IMPORTANT: Keep the admin/API duration name exactly as entered.14  // The product-specific day ranges below are used only when the stored plan15  // contains a plain numeric Day duration; this lets 1-30 Day plans target16  // the exact website/API names requested by the admin without changing any17  // other product data or purchase logic.18  var raw = String((plan && (plan.api_duration || plan.name_on_website || plan.durationDisplay || plan.name || plan.title)) || "").replace(/\s+/g, " ").trim();19 20  // Already-custom API labels (including casing/suffixes) must pass through unchanged.21  if (raw && !/^[0-9]+(?:\.[0-9]+)?\s*(day|days)$/i.test(raw)) {22    return raw;23  }24 25  var dayMatch = raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(day|days)$/i);26  var n = dayMatch ? dayMatch[1] : String(cleanPlanDays || "1");27  var productName = String(productNameOverride || (plan && (plan.product_name || plan.productName || plan.product || plan.category)) || "").trim().toLowerCase();28 29  // If product name is not stored on the plan, the caller's raw API label is30  // still preserved above. Generic numeric Day plans remain "N Days".31  if (/pc\s*aim\s*silent/.test(productName)) return n + " Day Pc Aim Silent";32  if (/pc\s*modmenu\s*x86/.test(productName)) return n + " Day Pc Modmenu x86";33  if (/pc\s*bypass\s*\+\s*silent/.test(productName) || /bypass\s*\+\s*silent/.test(productName)) return n + " Days Pc Bypass + Silent";34  if (/nonroot/.test(productName) && !/root\s*\+\s*nonroot/.test(productName)) return n + " DaYS NONROOT";35  if (/pc\s*aimkill/.test(productName) || /aimkill/.test(productName)) return n + " DaYS PC AIMKILL";36  if (/root\s*\+\s*nonroot/.test(productName)) return n + " DaYs Root + Nonroot";37  if (/fluo?rite\s*ff/.test(productName)) return n + " DAYs FluoRite FF";38  if (/\broot\b/.test(productName)) return n + " DaYs ROOT";39  if (/all\s*colou?rs\s*mix/.test(productName)) return n + " DaYs All Colours Mix";40  if (/\bbasic\b/.test(productName)) return n + " DaYs Basic";41  if (/\bpro\b/.test(productName)) return n + " DaYs PRO";42  if (/\bsafe\b/.test(productName)) return n + " DaYs SAFE";43  if (/\bbrutal\b/.test(productName)) return n + " DaYs BRUTAL";44 45  // Hours/minutes are preserved exactly; no existing API duration is removed.46  var gh = raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(hour|hours)$/i);47  if (gh) return gh[1] + " Hours";48  var gm = raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(minute|minutes)$/i);49  if (gm) return gm[1] + (Number(gm[1]) === 1 ? " Minute" : " Minutes");50 51  return raw || n + " Days";52}53 54 55// =========================================================56// โœ… ACTUAL PURCHASE EXECUTION โ€” runs after user taps "Confirm" on the57// premium confirmation screen, OR automatically right after a shortfall58// QR payment is verified (see _onCheck.js), so key delivery is fully automatic.59// =========================================================60 61try {62  var productList = Bot.getProperty("stored_products") || [];63  var chatId = chat.chatid;64  var userId = user.telegramid;65 66  var parts = params ? String(params).trim().split(" ") : [];67  var prodIdx = Number(parts[0]);68  var planIdx = Number(parts[1]);69 70  var product = productList[prodIdx];71  if (!product || !product.plans || !product.plans[planIdx]) {72    Api.sendMessage({ chat_id: chatId, text: "โŒ Product or Plan configuration missing!" });73    return;74  }75 76  var plan = product.plans[planIdx];77  var planUnit = plan.unit || "day";78  var isReseller = Bot.getProperty("is_reseller_" + userId) === true;79 80  var cleanProdName = product.name.trim().toUpperCase();81  var cleanPlanDays = String(plan.days).replace(/[^0-9.]/g, "").trim();82  var unitLabelWord = (planUnit === "hour") ? (Number(cleanPlanDays) === 1 ? "Hour" : "Hours") :83                       (planUnit === "minute") ? (Number(cleanPlanDays) === 1 ? "Minute" : "Minutes") :84                       (Number(cleanPlanDays) === 1 ? "Day" : "Days");85  var durationDisplay = plan.durationDisplay || (cleanPlanDays + " " + unitLabelWord);86 87  var priceKeySuffix = (planUnit === "day") ? cleanPlanDays : (cleanPlanDays + "_" + planUnit);88  var normalKey = "price_normal_" + cleanProdName + "_" + priceKeySuffix;89  var resellerKey = "price_reseller_" + cleanProdName + "_" + priceKeySuffix;90 91  var adminNormalPrice = Bot.getProperty(normalKey);92  var adminResellerPrice = Bot.getProperty(resellerKey);93 94  var currentNormal = (adminNormalPrice !== undefined && adminNormalPrice !== null) ? adminNormalPrice : plan.normal_price;95  var currentReseller = (adminResellerPrice !== undefined && adminResellerPrice !== null) ? adminResellerPrice : plan.reseller_price;96 97  var originalPrice = isReseller ? Number(currentReseller) : Number(currentNormal);98  var price = originalPrice;99 100  var planSpecificDiscKey = "auto_discount_" + cleanProdName + "_" + cleanPlanDays + "_" + planUnit.toUpperCase();101  var productWideDiscKey = "auto_discount_" + cleanProdName + "_ALL";102  var autoDiscountPercent = Bot.getProperty(planSpecificDiscKey) || Bot.getProperty(productWideDiscKey) || Bot.getProperty("auto_discount_global") || 0;103 104  // ๐ŸŽŸ Apply coupon discount (if any was applied for this exact prod/plan) โ€” coupon overrides auto-discount105  var appliedCouponCode = User.getProperty("applied_coupon_" + prodIdx + "_" + planIdx);106  var couponDiscountPercent = 0;107  if (appliedCouponCode) {108    var couponRec0 = Bot.getProperty("coupon_" + appliedCouponCode);109    if (couponRec0 && couponRec0.discountPercent) {110      couponDiscountPercent = couponRec0.discountPercent;111      price = Number((originalPrice * (1 - couponDiscountPercent / 100)).toFixed(2));112    }113    User.setProperty("applied_coupon_" + prodIdx + "_" + planIdx, null, "string");114  } else if (autoDiscountPercent > 0) {115    couponDiscountPercent = autoDiscountPercent;116    price = Number((originalPrice * (1 - autoDiscountPercent / 100)).toFixed(2));117  }118 119  // ๐Ÿ›ก๏ธ Safety re-check: balance abhi bhi sufficient hai ya nahi (race-condition guard)120  var unifiedBal = (function () {121    var resBal = 0;122    try { resBal = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (e) {}123    var bonusBal = Number(Bot.getProperty("balance" + userId) || 0);124    return resBal + bonusBal;125  })();126 127  if (unifiedBal < price) {128    Api.sendMessage({129      chat_id: chatId,130      text: "โš ๏ธ <b>Balance abhi kam hai.</b> Kripya phir se try karein.",131      parse_mode: "HTML"132    });133    return;134  }135 136  // =====================================================137  // ๐Ÿ”‘ STEP 0 โ€” MANUAL STOCK FIRST CHECK (โœ… NEW)138  // Agar admin ne manually koi key already daal rakhi hai, to wahi seedha139  // deliver karo aur PAID EXTERNAL API ko bilkul call hi mat karo โ€” taaki140  // "1 available key ke liye 2 keys spend" (1 manual + 1 wasted API buy)141  // wala bug kabhi na ho. API sirf tabhi call hoga jab manual stock khaali ho.142  // =====================================================143  var pDaysNumOnly = cleanPlanDays;144  var manualKeysStorageKey = "manual_keys_" + cleanProdName + "_" + pDaysNumOnly;145  var backupStockKey = "stock_" + product.name.trim() + "_" + pDaysNumOnly + "_Day";146  var isBackupUsed = false;147 148  var manualStock = Bot.getProperty(manualKeysStorageKey);149  if (!manualStock || (Array.isArray(manualStock) && manualStock.length === 0)) {150    manualStock = Bot.getProperty(backupStockKey);151    isBackupUsed = true;152  }153  if (typeof manualStock === "string" && manualStock.trim() !== "") {154    try {155      manualStock = JSON.parse(manualStock);156    } catch (err) {157      manualStock = manualStock.split("\n").map(function (k) { return k.trim(); }).filter(Boolean);158    }159  }160 161  if (Array.isArray(manualStock) && manualStock.length > 0) {162    var generatedKey = manualStock.shift();163 164    if (isBackupUsed) {165      Bot.setProperty(backupStockKey, manualStock, "json");166      var mainStock = Bot.getProperty(manualKeysStorageKey) || [];167      if (typeof mainStock === "string") { mainStock = mainStock.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }168      if (Array.isArray(mainStock)) {169        var idx1 = mainStock.indexOf(generatedKey);170        if (idx1 > -1) { mainStock.splice(idx1, 1); }171        Bot.setProperty(manualKeysStorageKey, mainStock, "json");172      }173    } else {174      Bot.setProperty(manualKeysStorageKey, manualStock, "json");175      var backupStock2 = Bot.getProperty(backupStockKey) || [];176      if (typeof backupStock2 === "string") { backupStock2 = backupStock2.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }177      if (Array.isArray(backupStock2)) {178        var idx2 = backupStock2.indexOf(generatedKey);179        if (idx2 > -1) { backupStock2.splice(idx2, 1); }180        Bot.setProperty(backupStockKey, backupStock2, "json");181      }182    }183 184    // ๐Ÿ’ฐ Deduct balance + record purchase (same accounting as API path)185    Libs.ResourcesLib.userRes("balance").add(-price);186    var pastSpent2 = Bot.getProperty("total_spent_by_" + userId) || 0;187    Bot.setProperty("total_spent_by_" + userId, Number(pastSpent2) + price, "number");188 189    // ๐ŸŽ REFER & EARN โ€” referrer bonus jab referred friend PEHLI baar purchase kare190    try {191      var referredByBuy2 = User.getProperty("referred_by");192      if (referredByBuy2 && !User.getProperty("ref_buy_bonus_given")) {193        var refBonusBuy2 = Number(Bot.getProperty("refer_earn_buy_amount"));194        if (isNaN(refBonusBuy2)) refBonusBuy2 = 2;195        if (refBonusBuy2 > 0) {196          Libs.ResourcesLib.anotherUserRes("balance", referredByBuy2).add(refBonusBuy2);197          var pastEarnBuy2 = Number(Bot.getProperty("refer_earnings_" + referredByBuy2) || 0);198          Bot.setProperty("refer_earnings_" + referredByBuy2, pastEarnBuy2 + refBonusBuy2, "number");199          try {200            Api.sendMessage({201              chat_id: referredByBuy2,202              text: "<blockquote>๐Ÿ’ธ <b>Referral Bonus!</b>\n\nAapke referred friend ne pehli purchase ki โ€” aapko โ‚น" + refBonusBuy2.toFixed(2) + " mile hain!</blockquote>",203              parse_mode: "HTML"204            });205          } catch (e) {}206        }207        User.setProperty("ref_buy_bonus_given", true, "boolean");208      }209    } catch (e) {}210 211    var keysHistory2 = User.getProperty("my_purchased_keys") || [];212    keysHistory2.push({213      product: String(product.name).trim(),214      product_id: product.id || null,215      days: pDaysNumOnly,216      price: price,217      key: generatedKey,218      date: new Date().toLocaleDateString()219    });220    User.setProperty("my_purchased_keys", keysHistory2, "json");221 222    var remainingBal2 = Libs.ResourcesLib.userRes("balance").value().toFixed(2);223 224    // โœ… NEW: Key ke saath automatic "Join Updates" button attach hota hai (agar admin ne link set kiya ho)225    var updateLinkForKey = Bot.getProperty("update_channel_link");226    var keyDeliveryButtons = [[{ text: "๐Ÿ“‹ Copy Key", copy_text: { text: generatedKey } }]];227    if (updateLinkForKey) {228      keyDeliveryButtons.push([{ text: "๐Ÿ“ฅ Join Updates", url: updateLinkForKey, style: "primary", icon_custom_emoji_id: "6091571559233755994" }]);229    }230    keyDeliveryButtons.push([{ text: "Back to Menu", callback_data: "/back", style: "default", icon_custom_emoji_id: "5893163582194978381" }]);231    var keyDeliveryMarkup = JSON.stringify({ inline_keyboard: keyDeliveryButtons });232 233    var deliverText2 = "<blockquote>" +234      "<tg-emoji emoji-id='5350447674971660988'>โœ…</tg-emoji> <b>PURCHASE SUCCESSFUL!</b>\n\n" +235      "<tg-emoji emoji-id='6147767796097884213'>๐Ÿ“ฆ</tg-emoji> <b>Product:</b> <code>" + String(product.name).trim() + "</code>\n" +236      "<tg-emoji emoji-id='6284816251143331422'>๐Ÿ—</tg-emoji> <b>Validity:</b> <code>" + durationDisplay + "</code>\n" +237      "<tg-emoji emoji-id='5352825278672412291'>๐Ÿ‘†</tg-emoji> <b>Your Key:</b> <code>" + generatedKey + "</code>\n\n" +238      "โ”โ”โ”โ”โ” <tg-emoji emoji-id='6147934084346682063'>#โƒฃ</tg-emoji> <b>BALANCE DETAILS</b> โ”โ”โ”โ”โ”\n" +239      "<tg-emoji emoji-id='6195037488898121775'>โœจ</tg-emoji> <b>Total Invest:</b> โ‚น" + price.toFixed(2) + "\n" +240      "<tg-emoji emoji-id='5409048419211682843'>๐Ÿ’ต</tg-emoji> <b>New Wallet Balance:</b> โ‚น" + remainingBal2 + "\n\n" +241      "<i>Enjoy your purchase. <tg-emoji emoji-id='6057881002540274780'>๐Ÿฅณ</tg-emoji></i>" +242      "</blockquote>";243 244    if (request && request.message) {245      try {246        Api.editMessageText({247          chat_id: String(chatId),248          message_id: Number(request.message.message_id),249          text: deliverText2,250          parse_mode: "HTML",251          reply_markup: keyDeliveryMarkup252        });253      } catch (e) {254        Api.sendMessage({ chat_id: chatId, text: deliverText2, parse_mode: "HTML", reply_markup: keyDeliveryMarkup });255      }256    } else {257      Api.sendMessage({ chat_id: chatId, text: deliverText2, parse_mode: "HTML", reply_markup: keyDeliveryMarkup });258    }259 260    var adminId3 = "6182067327";261    Api.sendMessage({262      chat_id: adminId3,263      text: "๐Ÿ”” <b>NEW PURCHASE DELIVERED (MANUAL STOCK)</b> โœ”๏ธ\n\n" +264            "๐Ÿ‘ค <b>Buyer:</b> " + (user.first_name || "User") + " (<code>" + userId + "</code>)\n" +265            "๐Ÿ“ฆ <b>Product:</b> " + String(product.name).trim() + "\n" +266            "โณ <b>Plan:</b> " + durationDisplay + "\n" +267            "๐Ÿ’ธ <b>Price Deducted:</b> โ‚น" + price.toFixed(2) + "\n" +268            "๐Ÿ’ณ <b>User Remaining Bal:</b> โ‚น" + remainingBal2 + "\n" +269            "๐Ÿ”‘ <b>Key:</b> <code>" + generatedKey + "</code>\n\n" +270            "<i>โœ… Manual stock se deliver hui โ€” external paid API call SKIP ki gayi.</i>",271      parse_mode: "HTML"272    });273 274    var qId0 = request ? (request.id || (request.callback_query && request.callback_query.id)) : null;275    if (qId0) {276      try { Api.answerCallbackQuery({ callback_query_id: String(qId0), text: "โœ… Key Delivered!", show_alert: false }); } catch (e) {}277    }278 279    return; // ๐Ÿšซ STOP โ€” external API bilkul call nahi hui280  }281 282  var webProductId = String(product.id || "PID_ID").trim();283  var prodNameLower = String(product.name).toLowerCase();284 285  var durationParam = resolveApiDuration(plan, cleanPlanDays, planUnit, product && product.name);286 287  // =====================================================288  // ๐Ÿ”Œ MULTI-API SYSTEM289  // Admin can add/update/select multiple reseller APIs.290  // The active API is used for external purchases.291  // =====================================================292  var apiRegistry = Bot.getProperty("api_registry") || {};293  var activeApiId = Bot.getProperty("active_reseller_api");294  var selectedApi = activeApiId ? apiRegistry[activeApiId] : null;295 296  // Backward-compatible bootstrap from the existing API configuration.297  if (!selectedApi) {298    selectedApi = {299      id: "default",300      name: "Default Reseller API",301      url: "https://bantibhaiya.com/api/reseller_v1.php",302      api_key: "5d655f6da12d22c618747031c78421ac",303      master_key: "a7f3e8b2c9d1f4a6b8c2d5e9f1a3b6c8",304      mode: "reseller_v1",305      android_required: false,306      enabled: true307    };308    apiRegistry.default = selectedApi;309    Bot.setProperty("api_registry", apiRegistry, "json");310    Bot.setProperty("active_reseller_api", "default", "string");311  }312 313  if (selectedApi.enabled === false) {314    Api.sendMessage({chat_id: chatId, text: "โŒ Selected API is disabled. Admin ko /apiset se another API select karna hoga."});315    return;316  }317 318  var webProductId = String(product.id || "PID_ID").trim();319  var prodNameLower = String(product.name).toLowerCase();320 321  var durationParam = resolveApiDuration(plan, cleanPlanDays, planUnit, product && product.name);322 323  // Product-level API override is supported: product.api_id.324  var productApiId = product.api_id ? String(product.api_id).trim() : "";325  if (productApiId && apiRegistry[productApiId] && apiRegistry[productApiId].enabled !== false) {326    selectedApi = apiRegistry[productApiId];327    activeApiId = productApiId;328  }329 330  var postFields = {331    api_key: selectedApi.api_key || "",332    action: "buy",333    product_id: webProductId,334    duration: durationParam335  };336 337  // Device-bound APIs can require android_id. The value may be saved by338  // your existing product/user flow as android_id_<USER_ID>.339  var savedAndroidId = User.getProperty("android_id") || User.getProperty("android_id_" + userId) ||340                       Bot.getProperty("android_id_" + userId) || "";341  if (selectedApi.android_required) {342    if (!savedAndroidId) {343      Api.sendMessage({344        chat_id: chatId,345        text: "โš ๏ธ <b>Android ID required</b>\nIs API/product ke liye Android ID zaroori hai. Pehle user ka Android ID save karein.",346        parse_mode: "HTML"347      });348      return;349    }350    postFields.android_id = String(savedAndroidId);351  } else if (savedAndroidId) {352    // Optional APIs may also accept it.353    postFields.android_id = String(savedAndroidId);354  }355 356  var apiHeaders = {357    "Content-Type": "application/x-www-form-urlencoded"358  };359  if (selectedApi.master_key) apiHeaders["x-master-key"] = selectedApi.master_key;360 361  var postFieldsString = Object.keys(postFields).map(function(k) {362    return encodeURIComponent(k) + "=" + encodeURIComponent(postFields[k]);363  }).join("&");364 365  User.setProperty("last_pending_price", Number(price), "number");366  User.setProperty("last_pending_prod_id", webProductId, "string");367  User.setProperty("last_pending_prod_name", String(product.name).trim(), "string");368  User.setProperty("last_pending_plan_days", cleanPlanDays, "string");369  User.setProperty("last_pending_plan_unit", planUnit, "string");370  User.setProperty("last_pending_api_id", String(selectedApi.id || activeApiId || ""), "string");371 372  var queryId = request ? (request.id || (request.callback_query && request.callback_query.id)) : null;373 374  var processingText = "<tg-emoji emoji-id='6147936236125298267'>โณ</tg-emoji> <b>Processing your order... please wait!</b>";375  if (request && request.message) {376    try {377      Api.editMessageText({378        chat_id: String(chatId),379        message_id: Number(request.message.message_id),380        text: processingText,381        parse_mode: "HTML"382      });383      Bot.setProperty("gen_msg_id_" + userId, request.message.message_id, "string");384      User.setProperty("gen_msg_id_" + userId, request.message.message_id, "string");385    } catch (e) {386      var pm1 = Api.sendMessage({ chat_id: chatId, text: processingText, parse_mode: "HTML" });387      try {388        var pmid1 = (pm1 && pm1.result && pm1.result.message_id) ? pm1.result.message_id : (pm1 && pm1.message_id ? pm1.message_id : null);389        if (pmid1) { Bot.setProperty("gen_msg_id_" + userId, pmid1, "string"); User.setProperty("gen_msg_id_" + userId, pmid1, "string"); }390      } catch (e2) {}391    }392  } else {393    var pm2 = Api.sendMessage({ chat_id: chatId, text: processingText, parse_mode: "HTML" });394    try {395      var pmid2 = (pm2 && pm2.result && pm2.result.message_id) ? pm2.result.message_id : (pm2 && pm2.message_id ? pm2.message_id : null);396      if (pmid2) { Bot.setProperty("gen_msg_id_" + userId, pmid2, "string"); User.setProperty("gen_msg_id_" + userId, pmid2, "string"); }397    } catch (e2) {}398  }399 400  HTTP.post({401    url: selectedApi.url,402    body: postFieldsString,403    headers: apiHeaders,404    success: "/onWebKeyReceive",405    error: "/onWebKeyError"406  });407 408  if (queryId) {409    try {410      Api.answerCallbackQuery({411        callback_query_id: String(queryId),412        text: "โณ Processing your order... Please wait!",413        show_alert: false414      });415    } catch (e) {}416  }417 418} catch (e) {419  var errChatId = (typeof chat !== "undefined" && chat && chat.chatid) ? chat.chatid : null;420  if (errChatId) {421    try { Api.sendMessage({ chat_id: errChatId, text: "โŒ <b>Error:</b> <code>" + e.message + "</code>", parse_mode: "HTML" }); } catch (fatal) {}422  }423}