ayushyadav7970824760/goldensellingstore_botPublic · Bot Template

AIThis Telegram store bot lets customers browse digital products and plans, apply coupons, add funds via UPI, and receive purchased keys. It includes a full admin panel for managing products, reordering items, setting reseller prices, viewing and removing key stock, configuring UPI payment details and update links, and checking user balances. Co-admins and resellers are supported, and support tickets are forwarded to the admin.

Commercedigital_storeadmin_panelupi_paymentsresellercouponskey_stock
ProfileTelegram
146 commands0 envUpdated 2d agoCreated Sep 5, 2026
Back to folder

commands/_start.js

javascript · 1229 lines

Raw
1/**#command2name: /start3answer: 4keyboard: 5parse_mode: markdown6aliases: /START,/Start,/STArt,/stARt7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12try { 13  var adminId = Bot.getProperty("owner_id") || "8477746023";14  var userId = String(user.telegramid);15  // 💳 CANONICAL WALLET: read the live wallet value; NEVER reset a user's16  // stored balance during /start. A restart/re-host must not destroy balances.17 18  // ⭐ TELEGRAM STARS — fallback event detection (payment events may route here19  // generically depending on the platform, so we check and delegate explicitly)20  if (request && request.pre_checkout_query) {21    Bot.run({ command: "/onPreCheckoutQuery" });22    return;23  }24  if (request && request.message && request.message.successful_payment) {25    Bot.run({ command: "/onSuccessfulPayment" });26    return;27  }28  29  // Safe variable fallbacks for BJS environment30  var msgText = (typeof message !== 'undefined' && message) ? message.trim() : "";31  // ✅ FIXED: pehle "data" naam ka ek undefined global variable padha ja raha tha, jo hamesha32  // empty rehta tha — isliye koi bhi callback button jo "/start" call karta tha (jaise "Back to33  // Menu"), silently fail ho jaata tha aur user ko koi response hi nahi milta tha.34  var callbackData = (request && request.callback_query && request.callback_query.data) ? request.callback_query.data : "";35 36  // =====================================================37  // 🛠 MAINTENANCE MODE GATE (✅ NEW)38  // Owner/Co-Admins hamesha through jaate hain; baaki sabko premium screen dikhta hai.39  // =====================================================40  var isMaintenanceOn = Bot.getProperty("maintenance_mode") || false;41  var isOwnerOrCoAdmin = (userId === adminId) || Bot.getProperty("co_admin_" + userId);42 43  if (isMaintenanceOn && !isOwnerOrCoAdmin) {44    Bot.sendMessage(45      "<blockquote><tg-emoji emoji-id='6100657257605763582'>🛠</tg-emoji> <b>BOT UNDER MAINTENANCE</b></blockquote>\n\n" +46      "<i>Hum kuch premium improvements kar rahe hain! Kripya thodi der baad wapas try karein.</i>\n\n" +47      "<tg-emoji emoji-id='6100170496077204999'>👑</tg-emoji> <i>Dhanyawad for your patience!</i>",48      { parse_mode: "HTML" }49    );50    return;51  }52 53  // Main welcome is always shown directly; no extra post-maintenance welcome is injected.54 55  // 📦 PRODUCT DATA IS PERSISTENT56  // Never clear/reset stored_products from /start. Products and their plans are57  // kept in Bot properties so re-hosting the same bot does not wipe the catalog.58  // Admin can explicitly delete products with the product-management commands.59    var currentStep = User.getProperty("add_product_step");60  var isAwaitingBroadcast = User.getProperty("awaiting_broadcast_data");61 62  // 🎨 PREMIUM CUSTOM EMOJIS DEFINITION (Fixed with escaped double quotes)63  var EMJ_VERIFIED_CHECK = "<tg-emoji emoji-id=\"5875465628285931233\">✔️</tg-emoji>";64  var EMJ_CROWN          = "<tg-emoji emoji-id=\"6311975081702597046\">👑</tg-emoji>";65  var EMJ_DROP           = "<tg-emoji emoji-id=\"6080228009439141516\">💧</tg-emoji>";66  var EMJ_CHECK          = "<tg-emoji emoji-id=\"6080214566191505147\">✅</tg-emoji>";67  var EMJ_ROCKET         = "<tg-emoji emoji-id=\"6091571559233755994\">🚀</tg-emoji>";68  var EMJ_RADAR          = "<tg-emoji emoji-id=\"6093591495237967001\">📡</tg-emoji>";69  var EMJ_STAR           = "<tg-emoji emoji-id=\"6093677128295914531\">✨</tg-emoji>";70  var EMJ_RED_DOT        = "<tg-emoji emoji-id=\"6093854128193152827\">🔴</tg-emoji>";71  72  // Access Granted ke liye aapka requested special premium custom emoji73  var EMJ_NEW_ACCESS     = "<tg-emoji emoji-id=\"5875465628285931233\">✔️</tg-emoji>";74 75  // ==========================================76  // 🏠 HELPER: DIRECTLY SEND MAIN SHOP MENU77  // (Bot.runCommand("/menu") is unreliable in BJS -> inline it instead)78  // ==========================================79  function sendMainMenu() {80    try {81      // ✅ FIXED: ab same wallet store se read hoga jo purchase flows use karte hain82      // (Libs.ResourcesLib "balance" resource + admin bonus balance), taaki balance sab jagah same dikhe.83      var userBal = (function() {84        var resBal = 0;85        try { resBal = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (e) {}86        return resBal.toFixed(2);87      })();88 89      // 💎 PREMIUM WELCOME MESSAGE — kept identical to /menu.90      var BOT_DISPLAY_NAME = Bot.getProperty("bot_name") || "GOLDEN SELLING STORE";91      var U = {92        shop: "<tg-emoji emoji-id='5866053971960929280'>🛒</tg-emoji>",93        update: "<tg-emoji emoji-id='5208790878931415568'>🔄</tg-emoji>",94        money: "<tg-emoji emoji-id='5409048419211682843'>💰</tg-emoji>",95        profile: "<tg-emoji emoji-id='6145572393499762737'>⚙️</tg-emoji>",96        refer: "<tg-emoji emoji-id='5823654080584618403'>🔗</tg-emoji>",97        how: "<tg-emoji emoji-id='6192842983948162969'>❗</tg-emoji>",98        support: "<tg-emoji emoji-id='6267129592998270736'>✈️</tg-emoji>",99        gift: "<tg-emoji emoji-id='6194922667242429131'>🎁</tg-emoji>",100        balance: "<tg-emoji emoji-id='5231200819986047254'>💰</tg-emoji>",101        arrow: "<tg-emoji emoji-id='6057415823222379852'>👇</tg-emoji>"102      };103 104      var welcomeMessage =105        "<blockquote>" + U.shop + " <b>" + BOT_DISPLAY_NAME + "</b> " + U.shop + "</blockquote>\n" +106        "➤ ───────────────────\n" +107        "├ " + U.shop + " <b>Buy Now</b> : All Key Purchase &amp; Instant Delivery\n" +108        "├ " + U.update + " <b>Check Update</b> : Check Setup Video And Update Apk\n" +109        "├ " + U.money + " <b>Add Balance</b> : Deposit Balance &amp; Secure Auto-Add Payment System\n" +110        "├ " + U.profile + " <b>My Profile + All History</b> : Check Your Account Information + All History\n" +111        "├ " + U.refer + " <b>Refer And Earn</b> : Share Refer Link &amp; Earn Money\n" +112        "├ " + U.how + " <b>How To Use Bot</b> : View Tutorial And Work This Bot\n" +113        "├ " + U.support + " <b>Support</b> : Bot Problem Fixed For Support Admin\n" +114        "├ " + U.gift + " <b>Daily Gift</b> : Free Spin and win random balance daily, Only one spin every 24 hours.\n" +115        "➤ ───────────────────\n" +116        "<blockquote>" + U.balance + " <b>Your Balance:</b> ₹" + userBal + "</blockquote>\n" +117        "➤ ───────────────────\n" +118        U.arrow + " <b>Select an option from the menu below:</b>";119 120      var MENU_EMOJI = {121    shop: Bot.getProperty("menu_emoji_shop") || "5866053971960929280",122    download: Bot.getProperty("menu_emoji_download") || "5208790878931415568",123    addfund: Bot.getProperty("menu_emoji_addfund") || "5409048419211682843",124    profile: Bot.getProperty("menu_emoji_profile") || "6145572393499762737",125    refer: Bot.getProperty("menu_emoji_refer") || "5823654080584618403",126    how: Bot.getProperty("menu_emoji_how") || "6192842983948162969",127    support: Bot.getProperty("menu_emoji_support") || "6267129592998270736",128    dailygift: Bot.getProperty("menu_emoji_dailygift") || "6194922667242429131",129    proof: Bot.getProperty("menu_emoji_proof") || "5330237710655306682",130    reseller: Bot.getProperty("menu_emoji_reseller") || "6102856637343600044"131  };132 133  // ONE canonical main menu. All entry points (/start, /menu, /back and134  // post-verification) use the same keyboard so the layout never switches.135  var multiColorKeyboard = [136    [{ text: "𝑩𝒖𝒚 𝑵𝒐𝒘", callback_data: "/buy_hack", style: "danger", icon_custom_emoji_id: MENU_EMOJI.shop }],137    [138      { text: "𝑪𝒉𝒆𝒄𝒌 𝑼𝒑𝒅𝒂𝒕𝒆", callback_data: "/download_updates", style: "success", icon_custom_emoji_id: MENU_EMOJI.download },139      { text: "𝑨𝒅𝒅 𝑩𝒂𝒍𝒂𝒏𝒄𝒆", callback_data: "/addfund", style: "primary", icon_custom_emoji_id: MENU_EMOJI.addfund }140    ],141    [{ text: "𝑴𝒚 𝑷𝒓𝒐𝒇𝒊𝒍𝒆 + 𝑨𝒍𝒍 𝑯𝒊𝒔𝒕𝒐𝒓𝒚", callback_data: "/profile", style: "success", icon_custom_emoji_id: MENU_EMOJI.profile }],142    [143      { text: "𝑹𝒆𝒇𝒆𝒓 𝑨𝒏𝒅 𝑬𝒂𝒓𝒏", callback_data: "/refer", style: "success", icon_custom_emoji_id: MENU_EMOJI.refer },144      { text: "𝑯𝒐𝒘 𝑻𝒐 𝑼𝒔𝒆 𝑩𝒐𝒕", callback_data: "/how", style: "primary", icon_custom_emoji_id: MENU_EMOJI.how }145    ],146    [147      { text: "𝑺𝒖𝒑𝒑𝒐𝒓𝒕", callback_data: "/support", style: "danger", icon_custom_emoji_id: MENU_EMOJI.support },148      { text: "𝑫𝒂𝒊𝒍𝒚 𝑮𝒊𝒇𝒕", callback_data: "/dailygift", style: "success", icon_custom_emoji_id: MENU_EMOJI.dailygift }149    ],150    [{ text: "𝑷𝒂𝒚𝒎𝒆𝒏𝒕 𝑷𝒓𝒐𝒐𝒇𝒔", url: (Bot.getProperty("payment_proof_link") || "https://t.me/GaluModz_Proof"), style: "success", icon_custom_emoji_id: MENU_EMOJI.proof }]151  ];152 153  if (Bot.getProperty("reseller_system_enabled") && !Bot.getProperty("is_reseller_" + userId)) {154    multiColorKeyboard.push([155      { text: "𝑹𝒆𝒔𝒆𝒍𝒍𝒆𝒓 𝑼𝒑𝒈𝒓𝒂𝒅𝒆", callback_data: "/reseller_upgrade", style: "success", icon_custom_emoji_id: MENU_EMOJI.reseller }156    ]);157  }158 159      // Optional welcome banner set by /setbanner.160      // Existing menu, maintenance, payment and admin flows remain unchanged.161      var botBanner = Bot.getProperty("bot_banner");162      var finalMarkup = JSON.stringify({ inline_keyboard: multiColorKeyboard });163 164      if (botBanner) {165        Api.sendPhoto({166          chat_id: chat.chatid,167          photo: botBanner,168          caption: welcomeMessage,169          parse_mode: "HTML",170          reply_markup: finalMarkup171        });172      } else {173        Api.sendMessage({174          chat_id: chat.chatid,175          text: welcomeMessage,176          parse_mode: "HTML",177          reply_markup: finalMarkup178        });179      }180    } catch (menuErr) {181      Bot.sendMessage("🛑 <b>Menu Send Error:</b> <code>" + menuErr.message + "</code>", { parse_mode: "HTML" });182    }183  }184 185  // [Auto-Track User] List me user track karne ke liye186  var trackedUsers = Bot.getProperty("all_users_list") || [];187  if (!trackedUsers.includes(userId)) {188    trackedUsers.push(userId);189    Bot.setProperty("all_users_list", trackedUsers, "json");190 191    // ==========================================192    // 🎁 REFER & EARN — capture referral on this user's very first /start193    // Deep link format: https://t.me/<bot>?start=ref<referrerTelegramId>194    // ==========================================195    try {196      var refParam = (typeof params !== "undefined" && params) ? String(params).trim() : "";197      if (refParam.toLowerCase().indexOf("ref") === 0) {198        var referrerId = refParam.substring(3).replace(/[^0-9]/g, "");199        if (referrerId && referrerId !== userId && !User.getProperty("referred_by")) {200          User.setProperty("referred_by", referrerId, "string");201 202          var refList = Bot.getProperty("referrals_of_" + referrerId) || [];203          if (refList.indexOf(userId) === -1) {204            refList.push(userId);205            Bot.setProperty("referrals_of_" + referrerId, refList, "json");206          }207 208          try {209            Api.sendMessage({210              chat_id: referrerId,211              text: "<blockquote><tg-emoji emoji-id='6102856637343600044'>🎉</tg-emoji> <b>New Referral!</b>\n\n" +212                    "<tg-emoji emoji-id='5260399854500191689'>👤</tg-emoji> " + (user && user.first_name ? user.first_name : "A user") +213                    " ne aapke link se bot join kiya hai.\n<i>Jab wo balance add ya purchase karega, aapko bonus milega!</i></blockquote>",214              parse_mode: "HTML"215            });216          } catch (e) {}217        }218      }219    } catch (e) {}220  }221 222  // 🛡️ [ANTI-DUPLICATE CHECK] Agar user already verified hai toh seedhe menu par bhejein223  // ✅ FIXED: pehle sirf exact "msgText === '/start'" ya "callbackData === '/trigger_contact_popup'"224  // match hone par hi menu bhejta tha. Kisi bhi button jo callback_data "/start" call karta tha225  // (jaise cancel-order ke baad "Back to Menu"), us case me match fail ho jaata tha aur user ko226  // koi response nahi milta tha. Ab ye check robust hai — jab tak ye genuinely ek contact-share227  // event nahi hai ya admin ek mid-flow step me nahi hai, verified user ko hamesha menu milega.228  var couponGenStep = User.getProperty("coupon_gen_step");229  var awaitingCouponFor = User.getProperty("awaiting_coupon_for");230  var isAlreadyVerified = Bot.getProperty("verified_" + userId);231  var isContactShareEvent = !!(request && request.contact && request.contact.user_id);232  var isAdminMidFlow = (userId === adminId && (currentStep || isAwaitingBroadcast || couponGenStep ||233    User.getProperty("addbal_step") || User.getProperty("addbalall_step") || User.getProperty("rembal_step") || User.getProperty("checkbal_step") ||234    User.getProperty("set_download_link_step") || User.getProperty("set_payment_upi_step") ||235    User.getProperty("set_payment_binance_step") ||236    User.getProperty("set_dailygift_price_step") || User.getProperty("set_refer_earn_step") ||237    User.getProperty("set_how_link_step") || User.getProperty("set_proof_link_step") || User.getProperty("set_support_link_step") ||238    User.getProperty("give_key_step") || User.getProperty("set_sale_channel_step") || User.getProperty("set_menu_emoji_step") ||239    User.getProperty("set_welcome_message_step") || User.getProperty("rename_product_step") || User.getProperty("set_bot_logo_step"))) ||240    // ✅ FIXED: "Give Key" flow co-admins bhi use kar sakte hain — pehle sirf241    // primary adminId ke liye mid-flow maana jaata tha, isliye key type karte242    // hi ye "already verified" check hit ho kar seedha main menu bhej deta243    // tha aur key kabhi buyer tak deliver hi nahi hoti thi.244    !!(Bot.getProperty("co_admin_" + userId) && User.getProperty("give_key_step"));245  var binanceUtrStep = User.getProperty("binance_utr_step");246  var upiManualUtrStep = User.getProperty("upi_manual_utr_step");247  var supportTicketStep = User.getProperty("support_ticket_step");248  var isUserMidFlow = !!awaitingCouponFor || !!binanceUtrStep || !!upiManualUtrStep || !!supportTicketStep;249 250  // ✅ NEW: User ne jo bhi "/start"/"/START"/"/Start" type kiya, menu aane ke251  // baad us typed command-message ko vanish (delete) kar do — chat clean rahe.252  if (msgText.toLowerCase() === "/start" && request && request.message_id) {253    try { Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message_id }); } catch (delStartErr) {}254  }255 256  if (isAlreadyVerified && !isContactShareEvent && !isAdminMidFlow && !isUserMidFlow) {257    sendMainMenu();258    return;259  }260 261  // ==========================================262  // 🎫 MODULE 5c: SUPPORT — "Open Ticket" flow263  // Koi bhi user "Open Ticket" dabaane ke baad jo bhi likhta hai, wo seedha264  // admin ko forward ho jaata hai — buyer info ke saath.265  // ==========================================266  if (supportTicketStep === "waiting_message" && msgText) {267    User.setProperty("support_ticket_step", null, "string");268 269    var ticketAdminId = Bot.getProperty("owner_id") || "8477746023";270    var ticketFullName = ((user.first_name || "") + " " + (user.last_name || "")).trim() || "No Name";271    var ticketUsername = user.username ? "@" + user.username : "No Username";272    var ticketId = String(Date.now()).slice(-6);273 274    try {275      Api.sendMessage({276        chat_id: ticketAdminId,277        text: "<blockquote>🎫 <b>NEW SUPPORT TICKET #" + ticketId + "</b></blockquote>\n\n" +278              "👤 <b>From:</b> " + ticketFullName + " (" + ticketUsername + ") — <code>" + userId + "</code>\n\n" +279              "💬 <b>Message:</b>\n" + msgText,280        parse_mode: "HTML",281        reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "Reply on Telegram", url: "tg://user?id=" + userId, style: "primary" }]] })282      });283    } catch (ticketErr) {}284 285    Bot.sendMessage(286      "<blockquote>✅ <b>Ticket Submitted!</b> (#" + ticketId + ")</blockquote>\n\n" +287      "<i>Aapka message admin ko bhej diya gaya hai. Hum jald hi reply karenge.</i>",288      { parse_mode: "HTML", reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "Back to Menu", callback_data: "/back", style: "danger" }]] }) }289    );290    return;291  }292 293  // ==========================================294  // ⚡ MODULE: LIVE CONTACT RECEIVER & VERIFIER295  // ==========================================296  if (request && request.contact && request.contact.user_id) {297    if (String(request.contact.user_id) === userId) {298      299      var phoneNumber = request.contact.phone_number;300      var fullName = ((user.first_name || "") + " " + (user.last_name || "")).trim() || "No Name";301      var username = user.username ? "@" + user.username : "No Username";302 303      // Permanently mark user as verified globally304      Bot.setProperty("verified_" + userId, true, "boolean");305      Bot.setProperty("phone_" + userId, phoneNumber, "string");306      // ✅ NEW: Joined date save karo (Profile section me dikhane ke liye)307      if (!Bot.getProperty("joined_date_" + userId)) {308        Bot.setProperty("joined_date_" + userId, new Date().toLocaleDateString("en-IN", { day: "2-digit", month: "short", year: "numeric" }), "string");309      }310      311      // 1. USER DETAILS TO ADMIN312      var adminNotification = 313        "<blockquote><b>" + EMJ_CROWN + " NEW USER VERIFIED " + EMJ_VERIFIED_CHECK + "</b></blockquote>\n" +314        "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>\n" +315        "<b>👤 Name:</b> " + fullName + "\n" +316        "<b>🆔 User ID:</b> <code>" + userId + "</code>\n" +317        "<b>🌐 Username:</b> " + username + "\n" +318        "<b>📞 Number:</b> <code>" + phoneNumber + "</code>\n" +319        "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>";320 321      Api.sendMessage({322        chat_id: adminId,323        text: adminNotification,324        parse_mode: "HTML"325      });326 327      // 2. USER SUCCESS MESSAGE (With your exact requested custom emojis)328      var successMessage = 329        "<blockquote><b>" + EMJ_NEW_ACCESS + " ACCESS GRANTED " + EMJ_NEW_ACCESS + "</b></blockquote>\n" +330        "<b>" + EMJ_VERIFIED_CHECK + " Verification Successful!</b>\n" +331        "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>\n" +332        "<b>Welcome to GOLDEN MODS STORE PANEL </b>\n" +333        "<b>Your profile is now securely fully verified.</b>\n\n" +334        "<b>" + EMJ_ROCKET + " Store Loaded Successfully Use Now! " + EMJ_CROWN + "</b>";335 336      Api.sendMessage({337        chat_id: chat.chatid,338        text: successMessage,339        parse_mode: "HTML",340        reply_markup: JSON.stringify({ remove_keyboard: true }) 341      });342 343      // ✅ FIX: Direct inline menu instead of unreliable Bot.runCommand("/menu")344      sendMainMenu();345      return; 346    } else {347      Bot.sendMessage("❌ <b>Verification Failed!</b> Please share your own contact number only.", { parse_mode: "HTML" });348      return;349    }350  }351 352  // ==========================================353  // 📱 MODULE 0: VERIFICATION CALLBACK HANDLER354  // ==========================================355  if (!isAlreadyVerified && (msgText.toLowerCase() === "/start" || callbackData === "/trigger_contact_popup")) {356    357    var verifyMessage = 358      "<blockquote><b>" + EMJ_ROCKET + " GOLDEN MODS STORE " + EMJ_RADAR + "</b></blockquote>\n" +359      "<b>" + EMJ_STAR + " Welcome, " + (user.first_name || "User") + " " + EMJ_DROP + "</b>\n" +360      "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>\n" +361      "<b>" + EMJ_RED_DOT + " VERIFICATION REQUIRED " + EMJ_CHECK + "</b>\n" +362      "<b>━━━━━━━━━━━━━━━━━━━━━━━━━━</b>\n" +363      "<b>" + EMJ_RADAR + " To start shopping, please verify your phone number.</b>\n\n" +364      "<b>" + EMJ_ROCKET + " Why we need this:</b>\n" +365      "<b>  • Secure your purchases " + EMJ_CHECK + "</b>\n" +366      "<b>  • Deliver your books to you " + EMJ_DROP + "</b>\n" +367      "<b>  • Protect your account " + EMJ_STAR + "</b>\n\n" +368      "<b>" + EMJ_RED_DOT + " Tap the blue button below to verify your account:</b>";369 370    // Standard native reply keyboard because contact sharing works securely here371    var nativeKeyboard = {372      keyboard: [373        [{ text: "✅ Verify Account", request_contact: true }]374      ],375      resize_keyboard: true,376      one_time_keyboard: true377    };378 379    Api.sendMessage({380      chat_id: chat.chatid,381      text: verifyMessage,382      parse_mode: "HTML",383      reply_markup: JSON.stringify(nativeKeyboard)384    });385    return; 386  }387 388  // ==========================================389  // 📦 MODULE 1: STEP-BY-STEP PRODUCT CREATION (UPDATED FOR WEBSITE API ID)390  // ==========================================391  if (userId === adminId && currentStep) {392    if (currentStep === "waiting_for_name") {393      if (!msgText) {394        Bot.sendMessage("⚠️ Invalid name. Please type a valid Product Name:");395        return;396      }397      User.setProperty("temp_product_name", msgText, "string");398      User.setProperty("add_product_step", "waiting_for_emoji", "string");399      Bot.sendMessage("💎 Great! Now send the <b>Premium Emoji ID</b> for this product:", { parse_mode: "HTML" });400      return; 401    }402    403    if (currentStep === "waiting_for_emoji") {404      if (!msgText) {405        Bot.sendMessage("⚠️ Invalid Emoji ID. Please send a valid Telegram Premium Emoji ID:");406        return;407      }408      User.setProperty("temp_product_emoji", msgText, "string");409      User.setProperty("add_product_step", "waiting_for_pid", "string");410      Bot.sendMessage(411        "🔑 Nice! Now please enter the <b>Website API Product ID (PID)</b> for this item.\n\n" +412        "<i>Agar is product ke liye website API nahi hai aur aap khud manually key denge, to PID ki jagah</i> <code>-</code> <i>(ya</i> <code>skip</code><i>) bhej dein.</i>",413        { parse_mode: "HTML" }414      );415      return;416    }417 418    if (currentStep === "waiting_for_pid") {419      if (!msgText) {420        Bot.sendMessage("⚠️ Invalid Product ID. Please type a valid Website PID, or send - to skip:");421        return;422      }423 424      var savedName = User.getProperty("temp_product_name");425      var savedEmoji = User.getProperty("temp_product_emoji");426      var rawPidInput = msgText.trim();427      // ✅ NEW: agar admin "-" ya "skip"/"none" bhejta hai, to ye ek MANUAL-KEY428      // product ban jaata hai (no website API) — har order par admin khud key429      // dega, external API kabhi call nahi hogi is product ke liye.430      var isManualPidSkip = /^(-|skip|none|0|pid|pid_id|n\/?a)$/i.test(rawPidInput);431      var savedPid = isManualPidSkip ? "" : rawPidInput;432 433      var productList = Bot.getProperty("stored_products") || [];434      if (!Array.isArray(productList)) { productList = []; }435      436      // Saving Name, Emoji and Website API ID (id) inside database object437      productList.push({ 438        name: savedName, 439        emoji: savedEmoji, 440        id: savedPid, 441        manual_key_product: isManualPidSkip,442        plans: [] 443      });444 445      Bot.setProperty("stored_products", productList, "json");446      447      // Cleanup temporary states448      User.setProperty("add_product_step", null, "string");449      User.setProperty("temp_product_name", null, "string");450      User.setProperty("temp_product_emoji", null, "string");451      452      var successMsg = "✅ <b>Product Added Successfully!</b>\n\n" +453                       "📦 <b>Name:</b> " + savedName + "\n" +454                       "<tg-emoji emoji-id='" + savedEmoji + "'>💎</tg-emoji> <b>Emoji ID:</b> <code>" + savedEmoji + "</code>\n" +455                       (isManualPidSkip ?456                         "🔑 <b>Delivery:</b> <code>Manual (Admin gives key on each order)</code>\n\n" +457                         "<i>Is product ke liye koi website API PID nahi hai. Jab bhi koi is product ko buy karega, aapko order details ke saath ek \"Give Key\" button milega — usse tap karke key bhej dein.</i>"458                         :459                         "🔑 <b>API Product ID (PID):</b> <code>" + savedPid + "</code>\n\n" +460                         "<i>Aap is product ke andar plans baad me configure kar sakte hain. Automatically website se integration ho gaya hai!</i>");461                       462      Bot.sendMessage(successMsg, { parse_mode: "HTML" });463      return; 464    }465  }466 467  // ==========================================468  // 🟡 MODULE 4b: ADMIN — BINANCE PAYMENT CONFIG WIZARD469  // Step 1: QR (photo OR image URL — whichever the admin sends, both work).470  // Step 2: Binance Pay ID. Step 3: USDT Address. Step 4: USD rate.471  // ==========================================472  if (userId === adminId) {473    var setPaymentBinanceStep = User.getProperty("set_payment_binance_step");474 475    // ✅ ROBUST photo detection — different update shapes have shown up in this476    // environment, so we check every place Telegram (or this platform) might477    // put the photo array before giving up.478    var incomingPhotoArr = null;479    try {480      if (request) {481        if (request.message && request.message.photo && request.message.photo.length) {482          incomingPhotoArr = request.message.photo;483        } else if (request.photo && request.photo.length) {484          incomingPhotoArr = request.photo;485        } else if (request.update && request.update.message && request.update.message.photo && request.update.message.photo.length) {486          incomingPhotoArr = request.update.message.photo;487        }488      }489    } catch (photoDetectErr) {}490 491    if (setPaymentBinanceStep === "waiting_qr") {492      var savedQr = false;493 494      if (incomingPhotoArr) {495        var largestPhoto = incomingPhotoArr[incomingPhotoArr.length - 1];496        var qrFileId = largestPhoto.file_id;497        Bot.setProperty("binance_qr_file_id", qrFileId, "string");498        Bot.setProperty("binance_qr_url", null, "string");499        savedQr = true;500      } else if (msgText && (msgText.trim().indexOf("http://") === 0 || msgText.trim().indexOf("https://") === 0)) {501        Bot.setProperty("binance_qr_url", msgText.trim(), "string");502        Bot.setProperty("binance_qr_file_id", null, "string");503        savedQr = true;504      } else if (msgText && /^(-|skip|none)$/i.test(msgText.trim())) {505        // ✅ NEW: QR skip kiya ja sakta hai — bot USDT address/Binance ID se506        // khud QR generate kar lega, static image zaroori nahi hai.507        Bot.setProperty("binance_qr_url", null, "string");508        Bot.setProperty("binance_qr_file_id", null, "string");509        User.setProperty("set_payment_binance_step", "waiting_binance_id", "string");510        Bot.sendMessage(511          "✅ <b>QR Skipped!</b> <i>(Bot USDT address se khud QR generate karega)</i>\n\n" +512          "<i>Step 2/4 —</i> Ab apna <b>Binance Pay ID</b> bhejein (jaise: <code>839548203</code>):",513          { parse_mode: "HTML" }514        );515        return;516      }517 518      if (savedQr) {519        User.setProperty("set_payment_binance_step", "waiting_binance_id", "string");520        Bot.sendMessage(521          "✅ <b>QR Saved!</b>\n\n" +522          "<i>Step 2/4 —</i> Ab apna <b>Binance Pay ID</b> bhejein (jaise: <code>839548203</code>):",523          { parse_mode: "HTML" }524        );525        return;526      }527 528      // ❌ Neither a photo nor a URL was recognised — don't silently drop it.529      Bot.sendMessage(530        "⚠️ QR receive nahi hua. Kripya QR ko ya toh <b>photo/image</b> ke roop me bhejein, ya QR image ka <b>direct URL link</b> (https://...) paste karein — ya <code>skip</code> bhejein taaki bot khud USDT address se QR bana le.",531        { parse_mode: "HTML" }532      );533      return;534    }535 536    if (setPaymentBinanceStep === "waiting_binance_id" && msgText) {537      Bot.setProperty("binance_pay_id", msgText.trim(), "string");538      User.setProperty("set_payment_binance_step", "waiting_usdt_address", "string");539      Bot.sendMessage(540        "✅ <b>Binance Pay ID Saved!</b>\n\n" +541        "<i>Step 3/4 —</i> Ab apna <b>USDT Address</b> bhejein (jaise: <code>TNvySU5Wk2mBAJNpBLGwvLk9pk4EgkeLXt</code>):",542        { parse_mode: "HTML" }543      );544      return;545    }546 547    if (setPaymentBinanceStep === "waiting_usdt_address" && msgText) {548      Bot.setProperty("binance_usdt_address", msgText.trim(), "string");549      User.setProperty("set_payment_binance_step", "waiting_usd_rate", "string");550      var rateNow = Bot.getProperty("usd_rate") || 91;551      Bot.sendMessage(552        "✅ <b>USDT Address Saved!</b>\n\n" +553        "<i>Step 4/4 —</i> Ab USD conversion rate bhejein (₹ kitne ka $1, jaise <code>91</code>).\n" +554        "<i>Current:</i> <code>₹" + rateNow + " = $1</code>\n" +555        "<i>Same rakhna ho to bhi number type karke bhej dein.</i>",556        { parse_mode: "HTML" }557      );558      return;559    }560 561    if (setPaymentBinanceStep === "waiting_usd_rate" && msgText) {562      var finalRate = parseFloat(msgText.trim());563      if (isNaN(finalRate) || finalRate <= 0) {564        Bot.sendMessage("❌ Invalid rate! Ek valid positive number bhejein, jaise 91.", { parse_mode: "HTML" });565        return;566      }567      Bot.setProperty("usd_rate", finalRate, "string");568      User.setProperty("set_payment_binance_step", null, "string");569 570      var qrStatusMsg = Bot.getProperty("binance_qr_file_id") || Bot.getProperty("binance_qr_url") ? "✅ Set" : "❌ Not set";571      Bot.sendMessage(572        "<blockquote>🟡 <b>BINANCE PAY CONFIG COMPLETE!</b></blockquote>\n\n" +573        "🖼 <b>QR:</b> " + qrStatusMsg + "\n" +574        "🆔 <b>Binance Pay ID:</b> <code>" + Bot.getProperty("binance_pay_id") + "</code>\n" +575        "💳 <b>USDT Address:</b> <code>" + Bot.getProperty("binance_usdt_address") + "</code>\n" +576        "💱 <b>USD Rate:</b> <code>₹" + finalRate + " = $1</code>\n\n" +577        "<i>Binance Pay ab live hai!</i>",578        { parse_mode: "HTML" }579      );580      return;581    }582  }583 584  // ==========================================585  // 🟡 MODULE 4c: USER — BINANCE PROOF SUBMISSION (screenshot only)586  // ==========================================587  if (binanceUtrStep === "awaiting_screenshot") {588    var ssPhotoArr = null;589    try {590      if (request) {591        if (request.message && request.message.photo && request.message.photo.length) {592          ssPhotoArr = request.message.photo;593        } else if (request.photo && request.photo.length) {594          ssPhotoArr = request.photo;595        } else if (request.update && request.update.message && request.update.message.photo && request.update.message.photo.length) {596          ssPhotoArr = request.update.message.photo;597        }598      }599    } catch (ssPhotoDetectErr) {}600 601    if (!ssPhotoArr) {602      Bot.sendMessage("⚠️ Kripya payment screenshot ek <b>image/photo</b> ke roop me bhejein.", { parse_mode: "HTML" });603      return;604    }605 606    var ssLargest = ssPhotoArr[ssPhotoArr.length - 1];607    var ssFileId = ssLargest.file_id;608 609    var subInr = User.getProperty("binance_pending_amount_inr");610    var subUsd = User.getProperty("binance_pending_amount_usd");611    var adminSupportId = Bot.getProperty("owner_id") || "8477746023";612 613    var fullNameSub = ((user.first_name || "") + " " + (user.last_name || "")).trim() || "No Name";614    var usernameSub = user.username ? "@" + user.username : "No Username";615 616    var adminCaption =617      "<blockquote><tg-emoji emoji-id='6312263493051489212'>🟡</tg-emoji> <b>NEW BINANCE PAY SUBMISSION</b></blockquote>\n" +618      "👤 <b>User:</b> <a href='tg://user?id=" + userId + "'>" + fullNameSub + "</a> (<code>" + userId + "</code>)\n" +619      "🌐 <b>Username:</b> " + usernameSub + "\n" +620      "💰 <b>Amount:</b> $<code>" + subUsd + "</code> <i>(₹" + subInr + ")</i>\n\n" +621      "<i>Verify the screenshot, then credit balance with the button below or:</i>\n<code>/addbal " + userId + "|" + subInr + "</code>";622 623    try {624      Api.sendPhoto({625        chat_id: adminSupportId,626        photo: ssFileId,627        caption: adminCaption,628        parse_mode: "HTML",629        reply_markup: JSON.stringify({630          inline_keyboard: [[631            { text: "✅ Approve & Credit ₹" + subInr, callback_data: "/addbal_binance_approve " + userId + " " + subInr, style: "success" }632          ]]633        })634      });635    } catch (notifyAdminErr) {}636 637    User.setProperty("binance_utr_step", null, "string");638    User.setProperty("binance_pending_amount_inr", null, "string");639    User.setProperty("binance_pending_amount_usd", null, "string");640 641    Bot.sendMessage(642      "<blockquote><tg-emoji emoji-id='6147936236125298267'>⏳</tg-emoji> <b>WAIT FOR ADMIN CHECK</b></blockquote>\n\n" +643      "<i>Aapka payment screenshot admin ko bhej diya gaya hai. Admin manually verify karke aapka balance add karega — thodi der wait karein!</i>",644      {645        parse_mode: "HTML",646        reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "Back to Menu", callback_data: "/back", style: "danger" }]] })647      }648    );649    return;650  }651 652  // (Removed MODULE 4d — old screenshot-based manual UPI flow. Superseded by653  // the QR-edit + short-token Approve/Reject flow in /check.js.)654 655  // ==========================================656  // 💵 MODULE 5: ADMIN BALANCE TOOLS (Add Bal / Remove Bal / Check Bal657  // button-click continuation — fixes buttons that previously just658  // showed a "Wrong Format" error with no way to actually complete it)659  // ==========================================660  if (userId === adminId) {661    var addbalStep = User.getProperty("addbal_step");662    var addbalAllStep = User.getProperty("addbalall_step");663    var rembalStep = User.getProperty("rembal_step");664    var checkbalStep = User.getProperty("checkbal_step");665 666    if (addbalStep === "waiting_input" && msgText) {667      User.setProperty("addbal_step", null, "string");668 669      // ✅ FIXED: pehle sirf Bot.run(...) se /addbal ko dobara call kiya jaata tha —670      // agar us re-run me "message" text sahi se forward nahi hota tha (jo wildcard671      // "*" -> /start delegation ke through hone par silently fail ho sakta tha),672      // toh balance kabhi credit hi nahi hota tha aur admin ko koi error bhi nahi673      // dikhta tha. Ab balance yahin, isi jagah, seedha add hota hai — kisi doosre674      // command re-run par depend nahi karta. Bot.run wala call sirf backup ke675      // taur par neeche rakha hai.676      var addbalData = msgText.trim();677 678      if (addbalData.indexOf("|") === -1) {679        Bot.sendMessage("❌ *Invalid Format! Use:* `user_id|amount`", { parse_mode: "Markdown" });680        return;681      }682 683      var addbalParts = addbalData.split("|");684      var addbalTargetId = addbalParts[0].trim();685      var addbalAmount = parseFloat(addbalParts[1].trim());686 687      if (!addbalTargetId || isNaN(addbalAmount) || addbalAmount <= 0) {688        Bot.sendMessage("❌ *Invalid Format! Use:* `user_id|amount`", { parse_mode: "Markdown" });689        return;690      }691 692      try {693        // Primary wallet resource (same store the rest of the bot reads for purchases)694        try {695          Libs.ResourcesLib.anotherUserRes("balance", addbalTargetId).add(addbalAmount);696        } catch (resErr) {}697 698        // ✅ Bonus-balance property — this is the SAME property /menu reads and adds699        // on top of the resource balance. Writing it here too guarantees the credited700        // amount always shows up for the user even if the resource write above fails701        // silently for a user who never triggered it before.702        var prevBonus = Number(Bot.getProperty("balance" + addbalTargetId) || 0);703        Bot.setProperty("balance" + addbalTargetId, (prevBonus + addbalAmount).toFixed(2), "string");704 705        Bot.sendMessage("✅ Success! Added " + addbalAmount + " to user " + addbalTargetId, { parse_mode: "HTML" });706 707        try {708          Api.sendMessage({709            chat_id: addbalTargetId,710            text: "<blockquote>" +711              "<tg-emoji emoji-id='6192822213486321961'>🗣</tg-emoji> Admin Added: " + addbalAmount + "\n" +712              "<tg-emoji emoji-id='6266967801580231067'>💎</tg-emoji> Balance Credited!\n" +713              "<tg-emoji emoji-id='6267068789146260253'>💰</tg-emoji> Wallet Updated\n" +714              "<tg-emoji emoji-id='5866053971960929280'>🛒</tg-emoji> /start TO SHOP NOW" +715              "</blockquote>",716            parse_mode: "HTML"717          });718        } catch (notifyErr) {}719      } catch (addbalErr) {720        Bot.sendMessage("⚠️ *Error:* " + addbalErr.message, { parse_mode: "Markdown" });721      }722      return;723    }724    if (addbalAllStep === "waiting_input" && msgText) {725      User.setProperty("addbalall_step", null, "string");726      Bot.run({ command: "/addbal_all", options: { message: "/addbal_all " + msgText.trim() } });727      return;728    }729    if (rembalStep === "waiting_input" && msgText) {730      User.setProperty("rembal_step", null, "string");731      Bot.run({ command: "/rembal", options: { message: "/rembal " + msgText.trim() } });732      return;733    }734    if (checkbalStep === "waiting_input" && msgText) {735      User.setProperty("checkbal_step", null, "string");736      Bot.run({ command: "/checkbal", options: { params: msgText.trim() } });737      return;738    }739 740    var setDownloadLinkStep = User.getProperty("set_download_link_step");741    if (setDownloadLinkStep === "waiting_input" && msgText) {742      User.setProperty("set_download_link_step", null, "string");743      Bot.run({ command: "/set_update_link", options: { params: msgText.trim() } });744      return;745    }746 747    var setPaymentUpiStep = User.getProperty("set_payment_upi_step");748    if (setPaymentUpiStep === "waiting_input" && msgText) {749      User.setProperty("set_payment_upi_step", null, "string");750      Bot.run({ command: "/set_payment_upi", options: { params: msgText.trim() } });751      return;752    }753 754    var setDailyGiftPriceStep = User.getProperty("set_dailygift_price_step");755    if (setDailyGiftPriceStep === "waiting_input" && msgText) {756      User.setProperty("set_dailygift_price_step", null, "string");757      Bot.run({ command: "/set_dailygift_price", options: { params: msgText.trim() } });758      return;759    }760 761    var setReferEarnStep = User.getProperty("set_refer_earn_step");762    if (setReferEarnStep === "waiting_input" && msgText) {763      User.setProperty("set_refer_earn_step", null, "string");764      Bot.run({ command: "/set_refer_earn", options: { params: msgText.trim() } });765      return;766    }767 768    var setHowLinkStep = User.getProperty("set_how_link_step");769    if (setHowLinkStep === "waiting_input" && msgText) {770      User.setProperty("set_how_link_step", null, "string");771      Bot.run({ command: "/set_how_link", options: { params: msgText.trim() } });772      return;773    }774 775    var setProofLinkStep = User.getProperty("set_proof_link_step");776    if (setProofLinkStep === "waiting_input" && msgText) {777      User.setProperty("set_proof_link_step", null, "string");778      Bot.run({ command: "/set_proof_link", options: { params: msgText.trim() } });779      return;780    }781 782    var setSupportLinkStep = User.getProperty("set_support_link_step");783    if (setSupportLinkStep === "waiting_input" && msgText) {784      User.setProperty("set_support_link_step", null, "string");785      Bot.run({ command: "/set_support_link", options: { params: msgText.trim() } });786      return;787    }788 789    var setSaleChannelStep = User.getProperty("set_sale_channel_step");790    if (setSaleChannelStep === "waiting_input" && msgText) {791      User.setProperty("set_sale_channel_step", null, "string");792      Bot.run({ command: "/set_sale_channel", options: { params: msgText.trim() } });793      return;794    }795 796    var setMenuEmojiStep = User.getProperty("set_menu_emoji_step");    if (setMenuEmojiStep === "waiting_input" && msgText) {797      User.setProperty("set_menu_emoji_step", null, "string");798      var menuEmojiKey = User.getProperty("set_menu_emoji_key");799      User.setProperty("set_menu_emoji_key", null, "string");800 801      var newEmojiId = msgText.trim().replace(/[^0-9]/g, "");802      var menuLabels = {803        shop: "Shop Now", profile: "Profile", addfund: "Add Balance", mykey: "My Keys",804        how: "How to use", download: "Download Files", dailygift: "Daily Gift",805        refer: "Refer & Earn", support: "Support", reseller: "Reseller Upgrade"806      };807      var pickedLabel = menuLabels[menuEmojiKey] || menuEmojiKey;808 809      if (!menuEmojiKey || !newEmojiId || !/^[0-9]{5,25}$/.test(newEmojiId)) {810        Bot.sendMessage("❌ Invalid emoji ID! Sirf numeric ID bhejein (jaise <code>5866053971960929280</code>).", { parse_mode: "HTML" });811        return;812      }813 814      Bot.setProperty("menu_emoji_" + menuEmojiKey, newEmojiId, "string");815      Bot.sendMessage(816        "<blockquote>✅ <b>Emoji Updated!</b></blockquote>\n\n" +817        "<b>Button:</b> " + pickedLabel + "\n" +818        "<b>New Emoji:</b> <tg-emoji emoji-id='" + newEmojiId + "'>✅</tg-emoji> (<code>" + newEmojiId + "</code>)\n\n" +819        "<i>Menu me is button pe ab yehi emoji dikhega.</i>",820        { parse_mode: "HTML" }821      );822      return;823    }824 825    var setWelcomeMsgStep = User.getProperty("set_welcome_message_step");826    if (setWelcomeMsgStep === "waiting_input" && msgText) {827      User.setProperty("set_welcome_message_step", null, "string");828 829      if (msgText.trim().toLowerCase() === "reset") {830        Bot.setProperty("custom_welcome_text", null, "string");831        Bot.sendMessage("✅ Welcome message default pe reset ho gaya.", { parse_mode: "HTML" });832        return;833      }834 835      Bot.setProperty("custom_welcome_text", msgText.trim(), "string");836      Bot.sendMessage(837        "<blockquote>✅ <b>Welcome Message Updated!</b></blockquote>\n\n" +838        "<i>Ye ab /start, /menu, aur Back button pe har jagah dikhega.</i>\n\n━━━━━━━━━━━━━━━━━━━━━\n" +839        msgText.trim().replace(/\{name\}/g, ((user && user.first_name) ? user.first_name.toUpperCase() : "RESELLER")) +840        "\n━━━━━━━━━━━━━━━━━━━━━",841        { parse_mode: "HTML" }842      );843      return;844    }845  }846 847  // ==========================================848  // 🔑 MODULE 5b: ADMIN — MANUAL KEY DELIVERY ("Give Key" button flow)849  // Jab koi user kisi manual (no-PID) product ko buy karta hai, admin ko order850  // details + "Give Key" button milta hai (/give_key_btn se). Tap karne ke851  // baad admin yahan apni agli text message me seedha KEY bhejta hai, jo852  // turant buyer ko deliver ho jaati hai.853  // ==========================================854  var isCoAdminForKey = Bot.getProperty("co_admin_" + userId);855  if ((userId === adminId || isCoAdminForKey)) {856    var giveKeyStep = User.getProperty("give_key_step");857    if (giveKeyStep === "waiting_key") {858      if (!msgText) {859        Bot.sendMessage("⚠️ Kripya ek valid key (text) bhejein.");860        return;861      }862 863      var giveKeyOrderId = User.getProperty("give_key_order_id");864      User.setProperty("give_key_step", null, "string");865      User.setProperty("give_key_order_id", null, "string");866 867      var pendingOrder = giveKeyOrderId ? Bot.getProperty("pending_manual_order_" + giveKeyOrderId) : null;868 869      if (!pendingOrder) {870        Bot.sendMessage("❌ <b>Ye order nahi mila.</b> Ho sakta hai ye pehle hi fulfil ho chuka ho ya expire ho gaya ho.", { parse_mode: "HTML" });871        return;872      }873 874      var deliveredKeyText = msgText.trim();875      var buyerIdKey = String(pendingOrder.buyerId);876 877      // Buyer ke purchase history me record karo878      try {879        var buyerKeysHistory = Bot.getProperty("manual_key_history_" + buyerIdKey) || [];880        buyerKeysHistory.push({881          product: pendingOrder.prodName,882          days: pendingOrder.durationDisplay,883          price: pendingOrder.price,884          key: deliveredKeyText,885          date: new Date().toLocaleDateString()886        });887        Bot.setProperty("manual_key_history_" + buyerIdKey, buyerKeysHistory, "json");888      } catch (histErr) {}889 890      var buyerKeyText = "<blockquote>" +891        "✅ <b>YOUR KEY HAS ARRIVED!</b>\n\n" +892        "📦 <b>Product:</b> " + pendingOrder.prodName + "\n" +893        "🗝 <b>Validity:</b> " + pendingOrder.durationDisplay + "\n" +894        "✨ <b>Paid:</b> ₹" + Number(pendingOrder.price).toFixed(2) +895        "</blockquote>\n\n" +896        "━━━━━━━━━━━━━━━━━━━━━\n" +897        "🔑 <b>YOUR KEY</b>\n" +898        "<code>" + deliveredKeyText + "</code>\n" +899        "━━━━━━━━━━━━━━━━━━━━━\n\n" +900        "<i>Enjoy your purchase. 🥳</i>";901      var buyerKeyButtons = JSON.stringify({902        inline_keyboard: [903          [{ text: "📋 Copy Key", copy_text: { text: deliveredKeyText } }],904          [{ text: "Back to Menu", callback_data: "/back", style: "danger" }]905        ]906      });907 908      // ✅ Buyer ko key deliver karo — purani "ORDER PLACED!" wali message909      // ko DELETE kar diya jaata hai aur key ek bilkul NAYI, alag message me910      // bheji jaati hai (edit nahi) — jaisa maanga gaya.911      if (pendingOrder.buyerMsgId && pendingOrder.buyerChatId) {912        try {913          Api.deleteMessage({914            chat_id: String(pendingOrder.buyerChatId),915            message_id: Number(pendingOrder.buyerMsgId)916          });917        } catch (delBuyerErr) {}918      }919      try {920        Api.sendMessage({921          chat_id: buyerIdKey,922          text: buyerKeyText,923          parse_mode: "HTML",924          reply_markup: buyerKeyButtons925        });926      } catch (deliverErr) {927        Bot.sendMessage("⚠️ Key deliver karte waqt error aaya (user ne bot block kiya ho sakta hai): " + deliverErr.message, { parse_mode: "HTML" });928      }929 930      var adminConfirmText = "<blockquote>✅ <b>KEY DELIVERED SUCCESSFULLY!</b></blockquote>\n\n" +931        "👤 <b>Buyer:</b> " + (pendingOrder.buyerName || "User") + " (<code>" + buyerIdKey + "</code>)\n" +932        "📦 <b>Product:</b> " + pendingOrder.prodName + "\n" +933        "⏳ <b>Plan:</b> " + pendingOrder.durationDisplay + "\n" +934        "💸 <b>Price:</b> ₹" + Number(pendingOrder.price).toFixed(2) + "\n" +935        "🔑 <b>Key Sent:</b> <code>" + deliveredKeyText + "</code>";936 937      // ✅ Admin ko confirmation — naya message bhejne ke bajaye, wahi order938      // alert wala message (jo "Give Key" click par "SEND THE KEY NOW" ban939      // gaya tha) ab final "KEY DELIVERED" status me EDIT ho jaata hai.940      var adminEdited = false;941      if (pendingOrder.adminMsgId && pendingOrder.adminChatId) {942        try {943          Api.editMessageText({944            chat_id: String(pendingOrder.adminChatId),945            message_id: Number(pendingOrder.adminMsgId),946            text: adminConfirmText,947            parse_mode: "HTML"948          });949          adminEdited = true;950        } catch (editAdminErr) {}951      }952      if (!adminEdited) {953        Bot.sendMessage(adminConfirmText, { parse_mode: "HTML" });954      }955 956      // ✅ Channel ko sale announcement (public proof) — ab buyer ka username957      // aur AADHI-masked key (privacy ke liye) bhi dikhti hai.958      // Channel_id admin panel se set ki hui use hoti hai (/set_sale_channel_btn),959      // default -1003901057163.960      try {961        var saleChannelId = Bot.getProperty("sale_channel_id") || "-1003901057163";962        var maskedKeyLen = deliveredKeyText.length;963        var maskedVisibleLen = Math.ceil(maskedKeyLen / 2);964        var maskedKeyText = deliveredKeyText.substring(0, maskedVisibleLen) + Array(maskedKeyLen - maskedVisibleLen + 1).join("*");965        Api.sendMessage({966          chat_id: saleChannelId,967          text: "<blockquote>" +968            "<tg-emoji emoji-id='6102856637343600044'>🎉</tg-emoji> <b>NEW SALE!</b>\n\n" +969            "👤 <b>Buyer:</b> " + (pendingOrder.buyerUsername || "Hidden") + "\n" +970            "📦 <b>Product:</b> " + pendingOrder.prodName + "\n" +971            "⏳ <b>Plan:</b> " + pendingOrder.durationDisplay + "\n" +972            "💰 <b>Price:</b> ₹" + Number(pendingOrder.price).toFixed(2) + "\n" +973            "🔑 <b>Key:</b> <code>" + maskedKeyText + "</code>\n" +974            "✅ <b>Status:</b> Delivered\n\n" +975            "<i>Thank you for shopping with GOLDEN MODS STORE!</i>" +976            "</blockquote>",977          parse_mode: "HTML"978        });979      } catch (channelErr) {}980 981      Bot.setProperty("pending_manual_order_" + giveKeyOrderId, null, "string");982      return;983    }984 985    var setBotLogoStep = User.getProperty("set_bot_logo_step");986    if (setBotLogoStep === "waiting_input" && msgText) {987      User.setProperty("set_bot_logo_step", null, "string");988      var logoUrl = msgText.trim();989      if (logoUrl.indexOf("http://") !== 0 && logoUrl.indexOf("https://") !== 0) {990        Bot.sendMessage("❌ Invalid URL! Ek http(s):// se shuru hone wala image link bhejein.", { parse_mode: "HTML" });991        return;992      }993      Bot.setProperty("bot_logo_url", logoUrl, "string");994      Bot.sendMessage("✅ Bot logo set ho gaya! Ab Manual UPI QR ke beech me ye dikhega.", { parse_mode: "HTML" });995      return;996    }997 998    var renameProductStep = User.getProperty("rename_product_step");999    if (renameProductStep === "waiting_input" && msgText) {1000      User.setProperty("rename_product_step", null, "string");1001      var renameIdx = Number(User.getProperty("rename_product_idx"));1002      User.setProperty("rename_product_idx", null, "string");1003 1004      var renameProductList = Bot.getProperty("stored_products") || [];1005      if (!Array.isArray(renameProductList) || !renameProductList[renameIdx]) {1006        Bot.sendMessage("❌ Product not found (shayad delete ho chuka hai).", { parse_mode: "HTML" });1007        return;1008      }1009 1010      var oldName = renameProductList[renameIdx].name;1011      renameProductList[renameIdx].name = msgText.trim();1012      Bot.setProperty("stored_products", renameProductList, "json");1013 1014      Bot.sendMessage(1015        "<blockquote>✅ <b>Product Renamed!</b></blockquote>\n\n" +1016        "<b>Old Name:</b> " + oldName + "\n" +1017        "<b>New Name:</b> " + msgText.trim(),1018        { parse_mode: "HTML" }1019      );1020      return;1021    }1022  }1023 1024  // ==========================================1025  // 🎟 MODULE 3: ADMIN COUPON GENERATOR (step-by-step wizard)1026  // ==========================================1027  if (userId === adminId && couponGenStep) {1028 1029    if (couponGenStep === "code") {1030      if (!msgText) { Bot.sendMessage("⚠️ Kripya ek valid coupon code bhejein."); return; }1031      var couponCodeUpper = msgText.trim().toUpperCase();1032      if (Bot.getProperty("coupon_" + couponCodeUpper)) {1033        Bot.sendMessage("❌ Ye coupon code pehle se exist karta hai! Doosra naam try karein.");1034        return;1035      }1036      User.setProperty("coupon_gen_code", couponCodeUpper, "string");1037      User.setProperty("coupon_gen_step", "maxclaims", "string");1038      Bot.sendMessage("<tg-emoji emoji-id='6091571559233755994'>👥</tg-emoji> <b>Kitne users ye coupon use (claim) kar sakte hain?</b>\n<i>Sirf number bhejein, jaise: 50</i>", { parse_mode: "HTML" });1039      return;1040    }1041 1042    if (couponGenStep === "maxclaims") {1043      var maxClaimsVal = parseInt(msgText.trim());1044      if (isNaN(maxClaimsVal) || maxClaimsVal <= 0) { Bot.sendMessage("❌ Kripya ek valid number bhejein (jaise 50)."); return; }1045      User.setProperty("coupon_gen_maxclaims", maxClaimsVal, "number");1046      User.setProperty("coupon_gen_step", "discount", "string");1047      Bot.sendMessage("<tg-emoji emoji-id='6093591495237967001'>💸</tg-emoji> <b>Kitne % discount dena hai?</b>\n<i>Sirf number bhejein (1-100), jaise: 10</i>", { parse_mode: "HTML" });1048      return;1049    }1050 1051    if (couponGenStep === "discount") {1052      var discountVal = parseFloat(msgText.trim());1053      if (isNaN(discountVal) || discountVal <= 0 || discountVal > 100) { Bot.sendMessage("❌ Discount 1 se 100 ke beech honi chahiye."); return; }1054      User.setProperty("coupon_gen_discount", discountVal, "number");1055      User.setProperty("coupon_gen_step", "scope", "string");1056      Bot.sendMessage(1057        "<tg-emoji emoji-id='6093677128295914531'>🎯</tg-emoji> <b>Scope batayein:</b>\n\n" +1058        "• Sabhi products/plans ke liye: <code>global</code> likh kar bhejein\n" +1059        "• Sirf ek specific product+plan ke liye: <code>Product Name | Duration</code>\n" +1060        "  <i>Example:</i> <code>Atomic Habits (Book) | 1d</code>",1061        { parse_mode: "HTML" }1062      );1063      return;1064    }1065 1066    if (couponGenStep === "scope") {1067      var scopeInput = msgText.trim();1068      var couponData = {1069        code: User.getProperty("coupon_gen_code"),1070        maxClaims: User.getProperty("coupon_gen_maxclaims"),1071        discountPercent: User.getProperty("coupon_gen_discount"),1072        claimedBy: [],1073        isPaused: false,1074        createdAt: new Date().toLocaleDateString()1075      };1076 1077      if (scopeInput.toLowerCase() === "global") {1078        couponData.scope = "global";1079      } else if (scopeInput.indexOf("|") > -1) {1080        var scopeParts = scopeInput.split("|");1081        couponData.scope = "specific";1082        couponData.productName = scopeParts[0].trim();1083        couponData.duration = scopeParts[1].trim();1084      } else {1085        Bot.sendMessage("❌ Galat format! 'global' likhein ya 'Product Name | Duration' format me bhejein.");1086        return;1087      }1088 1089      Bot.setProperty("coupon_" + couponData.code, couponData, "json");1090 1091      // ✅ NEW: master list me bhi add karo, taaki /coupons admin command sabko list kar sake1092      var couponList = Bot.getProperty("coupon_list") || [];1093      if (couponList.indexOf(couponData.code) === -1) {1094        couponList.push(couponData.code);1095        Bot.setProperty("coupon_list", couponList, "json");1096      }1097 1098      // Cleanup wizard state1099      User.setProperty("coupon_gen_step", null, "string");1100      User.setProperty("coupon_gen_code", null, "string");1101      User.setProperty("coupon_gen_maxclaims", null, "number");1102      User.setProperty("coupon_gen_discount", null, "number");1103 1104      Bot.sendMessage(1105        "<blockquote>🎟 <b>COUPON CREATED SUCCESSFULLY!</b></blockquote>\n\n" +1106        "🏷 <b>Code:</b> <code>" + couponData.code + "</code>\n" +1107        "👥 <b>Max Claims:</b> " + couponData.maxClaims + "\n" +1108        "💸 <b>Discount:</b> " + couponData.discountPercent + "%\n" +1109        "🎯 <b>Scope:</b> " + (couponData.scope === "global" ? "🌍 Global (All Plans)" : "📦 " + couponData.productName + " (" + couponData.duration + ")"),1110        { parse_mode: "HTML" }1111      );1112      return;1113    }1114  }1115 1116  // ==========================================1117  // 🎟 MODULE 4: USER — APPLY COUPON CODE TEXT ENTRY1118  // ==========================================1119  if (awaitingCouponFor) {1120    var enteredCode = msgText.trim().toUpperCase();1121    var couponRec = Bot.getProperty("coupon_" + enteredCode);1122 1123    User.setProperty("awaiting_coupon_for", null, "string");1124 1125    if (!couponRec) {1126      Bot.sendMessage("❌ <b>Invalid Coupon Code!</b>", { parse_mode: "HTML" });1127      return;1128    }1129    if (couponRec.isPaused) {1130      Bot.sendMessage("⏸ Ye coupon abhi paused hai, thodi der baad try karein.", { parse_mode: "HTML" });1131      return;1132    }1133    if (!Array.isArray(couponRec.claimedBy)) { couponRec.claimedBy = []; }1134    if (couponRec.claimedBy.indexOf(userId) > -1) {1135      Bot.sendMessage("⚠️ Aapne ye coupon already use kar liya hai!", { parse_mode: "HTML" });1136      return;1137    }1138    if (couponRec.claimedBy.length >= couponRec.maxClaims) {1139      Bot.sendMessage("❌ Is coupon ki claim limit khatam ho gayi hai!", { parse_mode: "HTML" });1140      return;1141    }1142 1143    var couponTargetParts = awaitingCouponFor.split(" ");1144    var cTargetProdIdx = couponTargetParts[0];1145    var cTargetPlanIdx = couponTargetParts[1];1146 1147    if (couponRec.scope === "specific") {1148      var cProductList = Bot.getProperty("stored_products") || [];1149      var cProduct = cProductList[Number(cTargetProdIdx)];1150      var cPlan = cProduct ? cProduct.plans[Number(cTargetPlanIdx)] : null;1151      var cDurationDisplay = cPlan ? (cPlan.durationDisplay || (cPlan.days + " Days")) : "";1152      var matchesProduct = cProduct && cProduct.name.trim().toLowerCase() === couponRec.productName.trim().toLowerCase();1153      var matchesDuration = cDurationDisplay.toLowerCase().indexOf(String(couponRec.duration).toLowerCase().replace(/[^a-z0-9]/g, "")) > -1 ||1154                             String(couponRec.duration).replace(/[^0-9]/g, "") === String(cPlan ? cPlan.days : "");1155      if (!matchesProduct) {1156        Bot.sendMessage("❌ Ye coupon is product ke liye valid nahi hai!", { parse_mode: "HTML" });1157        return;1158      }1159    }1160 1161    // ✅ Valid — apply and mark claimed1162    couponRec.claimedBy.push(userId);1163    Bot.setProperty("coupon_" + enteredCode, couponRec, "json");1164    User.setProperty("applied_coupon_" + cTargetProdIdx + "_" + cTargetPlanIdx, enteredCode, "string");1165 1166    Bot.sendMessage("🎉 <b>Coupon Applied!</b> -" + couponRec.discountPercent + "% discount added.", { parse_mode: "HTML" });1167 1168    Bot.run({1169      command: "buyitem",1170      options: { params: cTargetProdIdx + " " + cTargetPlanIdx }1171    });1172    return;1173  }1174 1175  // ==========================================1176  // 📢 MODULE 2: PREMIUM BROADCAST SYSTEM1177  // ==========================================1178  if (userId === adminId && isAwaitingBroadcast) {1179    User.setProperty("awaiting_broadcast_data", false, "boolean");1180    var userList = Bot.getProperty("all_users_list") || [];1181 1182    if (userList.length === 0) {1183      Bot.sendMessage("❌ Bot mein abhi tak koi bhi user registered nahi hai.");1184      return;1185    }1186 1187    var targetMessageId = null;1188    if (request) {1189      if (request.message_id) { targetMessageId = request.message_id; }1190      else if (request.message && request.message.message_id) { targetMessageId = request.message.message_id; }1191    }1192 1193    if (!targetMessageId) {1194      Bot.sendMessage("❌ Unable to fetch message ID for broadcast.");1195      return;1196    }1197 1198    Bot.sendMessage("⏳ Sending premium broadcast to " + userList.length + " users... Please wait.");1199 1200    // ✅ FIXED: pehle ek bhi blocked/invalid user Api.copyMessage() ko throw karwa deta1201    // tha, jo bahar wale catch() tak chala jaata tha — isse loop beech me hi ruk jaata1202    // tha (baaki users ko broadcast nahi jaata tha) aur admin ko scary "Error in handling"1203    // dikhta tha, jabki zyada tar users ko message mil chuka hota tha. Ab har send apne1204    // try/catch me hai, aur end me accurate success/fail count milega.1205    var sentCount = 0;1206    var failedCount = 0;1207    for (var i = 0; i < userList.length; i++) {1208      try {1209        Api.copyMessage({1210          chat_id: String(userList[i]),1211          from_chat_id: adminId,1212          message_id: Number(targetMessageId)1213        });1214        sentCount++;1215      } catch (perUserErr) {1216        failedCount++;1217      }1218    }1219    Bot.sendMessage(1220      "✅ <b>Broadcast Complete!</b>\n" +1221      "📤 <b>Sent:</b> " + sentCount + " users\n" +1222      (failedCount > 0 ? "⚠️ <b>Failed/Blocked:</b> " + failedCount + " users" : "🎉 <b>No failures!</b>"),1223      { parse_mode: "HTML" }1224    );1225  }1226 1227} catch (err) {1228  Bot.sendMessage("Error in handling: " + err.message);1229}