devbro468/Dev_x_store_botPublic · Bot Template

AIThis bot operates a digital storefront (DEV X STORE) selling subscription-based products — likely game hacks, accounts, or access keys — categorized by platform (Android Root, Non-Root, iPhone). It features a reseller program with discounted pricing, a dual-currency wallet (INR balance + Telegram Stars/XTR), and a full admin/co-admin panel for managing products, plans, per-plan pricing, stock (keys/accounts), coupons, and API endpoints. Purchases flow through a plan selection screen offering wallet payment, Stars invoices (sendInvoice with XTR currency), and coupon application. Successful Stars payments are handled via successful_payment webhook, crediting wallet or delivering keys directly. Admin tools include user listing with chunked messaging, stock viewing/deletion with inline keyboards, co-admin management, and API registry updates. The bot registers users on first interaction and

Commercecommercedigital-goodsstars-paymentreseller-systemadmin-panelstock-management
ProfileTelegram
119 commands0 envUpdated 15d agoCreated Aug 23, 2026
Back to folder

commands/_onBuyCheck.js

javascript · 419 lines

Raw
1/**#command2name: /onBuyCheck3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12function resolveApiDuration(plan, cleanPlanDays, planUnit) {13  var raw = String((plan && (plan.api_duration || plan.name_on_website || plan.durationDisplay || plan.name || plan.title)) || "").replace(/\s+/g, " ").trim();14  var canonical = ["1 DaYS NONROOT","House","1 DaYs","15 DaYs All Colours Mix","30 DaYs PRO","1 DaYs Basic","1 Year Ios Esign Gbox Certificate","1 DaYs Root + Nonroot","7 DaYS PC AIMKILL","30 Day Pc Modmenu x86","3 DaYs SAFE","3 DaYs BRUTAL"];15  for (var i=0;i<canonical.length;i++) if (raw.toLowerCase() === canonical[i].toLowerCase()) return canonical[i];16  var gd=raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(day|days)$/i);17  if(gd) return Number(gd[1])===1 ? "1 DaYs" : gd[1]+" Days";18  // HOURS: preserve the exact duration entered by admin/API.19  // Examples: "1 Hours", "2 Hours", "12 Hours" all remain unchanged.20  var gh=raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(hour|hours)$/i);21  if(gh) return raw;22  var gm=raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(minute|minutes)$/i);23  if(gm) return gm[1]+(Number(gm[1])===1?" Minute":" Minutes");24  return raw || (Number(cleanPlanDays||"1")===1 ? "1 DaYs" : String(cleanPlanDays)+" Days");25}26 27 28try {29  var userId = user.telegramid;30 31  // ✅ CRITICAL FIX: Proper atomic duplicate-payment prevention32  var utrFromContent = null;33  34  // Parse content to get UTR early35  if (content) {36    var res = (typeof content === "object") ? content : JSON.parse(content);37    if (res && res.data && res.data.utr) {38      utrFromContent = res.data.utr;39    }40  }41 42  // 🛑 STEP 1: Check if payment already processed using UTR (most reliable identifier)43  if (utrFromContent && Bot.getProperty("paid_" + utrFromContent)) {44    // ✅ FIX: Vanish the QR completely instead of leaving a stale "already used" caption behind45    try {46      Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message.message_id });47    } catch (e) {}48 49    try {50      Bot.setProperty("buy_qr_msg_id_" + userId, null, "string");51      User.setProperty("buy_qr_msg_id_" + userId, null, "string");52    } catch (e) {}53 54    if (request && request.id) {55      try {56        Api.answerCallbackQuery({57          callback_query_id: String(request.id),58          text: "✅ ALREADY CLAIMED ✅\nYe order pehle hi deliver ho chuka hai.",59          show_alert: true60        });61      } catch (e) {}62    }63 64    Api.sendMessage({65      chat_id: chat.chatid,66      text: "<blockquote><tg-emoji emoji-id='5330237710655306682'>✅</tg-emoji> <b>ORDER ALREADY CLAIMED</b>\n<i>Ye payment pehle hi verify ho kar item deliver ho chuka hai. Apni keys 'All History' me check karein.</i></blockquote>",67      parse_mode: "HTML",68      reply_markup: JSON.stringify({69        inline_keyboard: [[70          { text: "📜 My Keys", callback_data: "/mykey", style: "primary" },71          { text: "🛒 Shop Menu", callback_data: "/buy_hack", style: "success" }72        ]]73      })74    });75    return;76  }77 78  // 🛑 STEP 2: Duplicate-click lock check79  var isChecking = User.getProperty("buy_verifying_lock_" + userId);80  if (isChecking) {81    if (request && request.id) {82      Api.answerCallbackQuery({83        callback_query_id: String(request.id),84        text: "⏳ ALREADY CHECKING — PLEASE WAIT...",85        show_alert: true86      });87    }88    return;89  }90  91  // 🛑 STEP 3: SET LOCK IMMEDIATELY before any async operations92  User.setProperty("buy_verifying_lock_" + userId, true, "boolean");93 94  if (!content) {95    Api.editMessageCaption({96      chat_id: chat.chatid, message_id: request.message.message_id,97      caption: "<blockquote>⚠️ <b>Server didn't respond.</b>\nClick 'I have paid' again.</blockquote>", parse_mode: "HTML"98    });99    User.setProperty("buy_verifying_lock_" + userId, false, "boolean");100    return;101  }102 103  var res = (typeof content === "object") ? content : JSON.parse(content);104 105  if (res.status === "success" && res.data) {106    var utr = res.data.utr;107    var isPaid = Bot.getProperty("paid_" + utr);108 109    if (isPaid) {110      // ✅ FIX: Vanish the QR completely instead of leaving a stale "already used" caption behind111      try {112        Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message.message_id });113      } catch (e) {}114 115      try {116        Bot.setProperty("buy_qr_msg_id_" + userId, null, "string");117        User.setProperty("buy_qr_msg_id_" + userId, null, "string");118      } catch (e) {}119 120      if (request && request.id) {121        try {122          Api.answerCallbackQuery({123            callback_query_id: String(request.id),124            text: "✅ ALREADY CLAIMED ✅\nYe order pehle hi deliver ho chuka hai.",125            show_alert: true126          });127        } catch (e) {}128      }129 130      Api.sendMessage({131        chat_id: chat.chatid,132        text: "<blockquote><tg-emoji emoji-id='5330237710655306682'>✅</tg-emoji> <b>ORDER ALREADY CLAIMED</b>\n<i>Ye payment pehle hi verify ho kar item deliver ho chuka hai. Apni keys 'All History' me check karein.</i></blockquote>",133        parse_mode: "HTML",134        reply_markup: JSON.stringify({135          inline_keyboard: [[136            { text: "📜 My Keys", callback_data: "/mykey", style: "primary" },137            { text: "🛒 Shop Menu", callback_data: "/buy_hack", style: "success" }138          ]]139        })140      });141      User.setProperty("buy_verifying_lock_" + userId, false, "boolean");142      return;143    }144    145    // ✅ IMMEDIATELY mark as paid BEFORE any async API calls to prevent race condition146    Bot.setProperty("paid_" + utr, true, "boolean");147 148    Api.editMessageCaption({149      chat_id: chat.chatid, message_id: request.message.message_id,150      caption: "<tg-emoji emoji-id='6192822213486321961'>🔄</tg-emoji> <b>Payment verified! Delivering your key...</b>",151      parse_mode: "HTML"152    });153 154    // ✅ FIX: Detect which purchase pipeline this QR payment belongs to.155    // "ffid" = local stock-based FF ID item (set by /execute_id_buy on low balance)156    // default/"plan" = original plan-based product via external xyzcheats API157    var flowType = User.getProperty("buy_flow_type") || "plan";158 159    if (flowType === "ffid") {160      // =========================================================161      // 🎮 FF ID STOCK DELIVERY (after successful QR payment)162      // =========================================================163      try {164        var rawType = User.getProperty("buy_ffid_rawtype") || "";165        var isResellerFlow = User.getProperty("buy_ffid_is_reseller") === true;166        var finalCost = Number(User.getProperty("buy_price") || 0);167        var displayTypeName = User.getProperty("buy_prod_name") || rawType;168 169        var stockData = [];170        var isDynamicCategory = false;171        var isGeneralCategory = false;172        var selectedCat = null;173 174        var fbCategories = Bot.getProperty("fb_categories") || [];175        if (!Array.isArray(fbCategories)) { fbCategories = []; }176 177        if (rawType.indexOf("fb_") === 0) {178          isDynamicCategory = true;179          var targetCatId = rawType.replace("fb_", "").trim();180          for (var i = 0; i < fbCategories.length; i++) {181            if (fbCategories[i].id === targetCatId) { selectedCat = fbCategories[i]; break; }182          }183          if (selectedCat) { stockData = selectedCat.stock_list || []; }184        } else if (rawType === "fb" || rawType === "google") {185          stockData = Bot.getProperty("ff_stock_" + rawType) || [];186        } else {187          isGeneralCategory = true;188          var categoriesFF = Bot.getProperty("ff_categories") || {};189          selectedCat = categoriesFF[rawType];190          if (selectedCat) {191            var fallbackStock = Bot.getProperty("ff_stock_" + rawType) || [];192            stockData = (selectedCat.stock_list && selectedCat.stock_list.length > 0) ? selectedCat.stock_list : fallbackStock;193          }194        }195 196        if (!stockData || stockData.length === 0) {197          Api.editMessageCaption({198            chat_id: chat.chatid, message_id: request.message.message_id,199            caption: "⚠️ Payment received but item went out of stock. Contact admin with UTR: " + utr,200            parse_mode: "HTML"201          });202          User.setProperty("buy_verifying_lock_" + userId, false, "boolean");203          return;204        }205 206        var accountExtracted = stockData.shift();207 208        if (isDynamicCategory && selectedCat) {209          selectedCat.stock_list = stockData;210          Bot.setProperty("fb_categories", fbCategories, "json");211        } else if (isGeneralCategory && selectedCat) {212          selectedCat.stock_list = stockData;213          var categoriesFF2 = Bot.getProperty("ff_categories") || {};214          categoriesFF2[rawType] = selectedCat;215          Bot.setProperty("ff_categories", categoriesFF2, "json");216          Bot.setProperty("ff_stock_" + rawType, stockData, "json");217        } else {218          Bot.setProperty("ff_stock_" + rawType, stockData, "json");219        }220 221        var fullRawString = String(accountExtracted || "").trim();222        var emailData = fullRawString;223        var passwordData = "No Password Found";224 225        if (fullRawString.indexOf("|") !== -1) {226          var lastPipeIndex = fullRawString.lastIndexOf("|");227          var firstPart = fullRawString.substring(0, lastPipeIndex).trim();228          var secondPart = fullRawString.substring(lastPipeIndex + 1).trim();229 230          if (firstPart.indexOf(" ") !== -1) {231            var spaceParts = firstPart.split(" ");232            emailData = spaceParts[spaceParts.length - 1].trim();233          } else {234            emailData = firstPart;235          }236          passwordData = secondPart;237        }238 239        var purchasedKeys = User.getProperty("my_purchased_keys") || [];240        if (!Array.isArray(purchasedKeys)) { purchasedKeys = []; }241        var currentDate = new Date().toLocaleDateString('en-IN', { timeZone: "Asia/Kolkata" });242        purchasedKeys.push({243          productName: displayTypeName,244          cost: finalCost.toString(),245          key: emailData + (passwordData !== "No Password Found" ? " | " + passwordData : ""),246          days: "Permanent",247          date: currentDate248        });249        User.setProperty("my_purchased_keys", purchasedKeys, "json");250 251        var deliveryText =252          "┏━━━━━━━━━━━━━━━━━━━━━━━━┓\n" +253          "┃ ❤️‍🔥 <b>PURCHASE SUCCESSFUL!</b> ❤️‍🔥 ┃\n" +254          "┗━━━━━━━━━━━━━━━━━━━━━━━━┛\n\n" +255          "📦 <b>Item:</b> <code>" + displayTypeName + "</code>\n" +256          "💰 <b>Paid:</b> <code>₹" + finalCost + "</code> " + (isResellerFlow ? "<b>(Reseller)</b>" : "") + "\n" +257          "━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +258          "👤 <b>ACCOUNT DETAILS:</b>\n\n" +259          "🚀 <b>Email:</b> <code>" + emailData + "</code>\n" +260          "🔒 <b>Password:</b> <code>" + passwordData + "</code>\n" +261          "━━━━━━━━━━━━━━━━━━━━━━━━━━\n" +262          "⚠️ <i>Copy details instantly.</i>";263 264        Api.sendMessage({265          chat_id: chat.chatid,266          text: deliveryText,267          parse_mode: "HTML"268        });269 270        var adminLogChannel = "8875810358";271        var adminNotificationMsg =272          "<blockquote>⚠️ <b>NEW ORDER ALERT (QR)</b>" + (isResellerFlow ? " [RESELLER]" : "") + "</blockquote>\n" +273          "👤 <b>User:</b> <a href='tg://user?id=" + userId + "'>" + user.first_name + "</a> (<code>" + userId + "</code>)\n" +274          "📦 <b>Item:</b> <code>" + displayTypeName + "</code>\n" +275          "💰 <b>Revenue:</b> <code>₹" + finalCost + "</code>\n" +276          "⚡ <b>Stock Left:</b> <code>" + stockData.length + " units</code>\n\n" +277          "🖥 <b>ACCOUNT DETAILS:</b>\n" +278          "➔ <b>Email:</b> <code>" + emailData + "</code>\n" +279          "➔ <b>Password:</b> <code>" + passwordData + "</code>";280 281        Api.sendMessage({282          chat_id: adminLogChannel,283          text: adminNotificationMsg,284          parse_mode: "HTML"285        });286 287        // Cleanup all buy_ state for this order288        User.setProperty("buy_flow_type", null, "string");289        User.setProperty("buy_ffid_rawtype", null, "string");290        User.setProperty("buy_ffid_is_reseller", null, "boolean");291        User.setProperty("buy_price", null, "number");292        User.setProperty("buy_needpay", null, "number");293        User.setProperty("buy_prod_name", null, "string");294        User.setProperty("buy_plan_unit", null, "string");295        User.setProperty("buy_plan_name_on_website", null, "string");296        User.setProperty("buy_pending_order_id", null);297        Bot.setProperty("buy_qr_msg_id_" + userId, null, "string");298        User.setProperty("buy_qr_msg_id_" + userId, null, "string");299        Bot.setProperty("buy_qr_caption_" + userId, null, "string");300        User.setProperty("buy_qr_caption_" + userId, null, "string");301        Bot.setProperty("buy_qr_buttons_" + userId, null, "string");302        User.setProperty("buy_qr_buttons_" + userId, null, "string");303 304      } catch (ffErr) {305        Api.editMessageCaption({306          chat_id: chat.chatid, message_id: request.message.message_id,307          caption: "⚠️ Delivery error. Contact admin with UTR: " + utr + " | Error: " + ffErr.message,308          parse_mode: "HTML"309        });310      }311      User.setProperty("buy_verifying_lock_" + userId, false, "boolean");312      return;313    }314 315    // =========================================================316    // 📦 ORIGINAL PLAN-BASED DELIVERY (external xyzcheats API)317    // =========================================================318    var prodIdx = User.getProperty("buy_prod_idx");319    var planIdx = User.getProperty("buy_plan_idx");320    var productList = Bot.getProperty("stored_products") || [];321    var product = productList[prodIdx];322    var plan = product && product.plans ? product.plans[planIdx] : null;323 324    if (!product || !plan) {325      Api.editMessageCaption({326        chat_id: chat.chatid, message_id: request.message.message_id,327        caption: "⚠️ Payment received but product data missing. Contact admin with UTR: " + utr,328        parse_mode: "HTML"329      });330      User.setProperty("buy_verifying_lock_" + userId, false, "boolean");331      return;332    }333 334    var webProductId = String(product.id || "PID_ID").trim();335    var cleanPlanDays = User.getProperty("buy_plan_days") || String(plan.days);336    var planUnit = User.getProperty("buy_plan_unit") || plan.unit || "day";337    var prodNameLower = String(product.name).toLowerCase();338    var durationParam = resolveApiDuration(plan, cleanPlanDays, planUnit);339 340    // 🔌 Use configured multi-API system instead of a hardcoded API.341    var apiRegistry = Bot.getProperty("api_registry") || {};342    var activeApiId = Bot.getProperty("active_reseller_api") || "";343    var selectedApi = activeApiId ? apiRegistry[activeApiId] : null;344    if (!selectedApi) {345      selectedApi = { id:"default", url:"https://xyzcheats.com/api/reseller_v1.php", api_key:"a9b26aa6439ff7cd495d64cb47916cb2", master_key:"a7f3e8b2c9d1f4a6b8c2d5e9f1a3b6c8", android_required:false, enabled:true };346    }347    if (selectedApi.enabled === false) {348      Bot.sendMessage("❌ Selected API is disabled. Admin ko /apiset se active API select karna hoga.");349      return;350    }351    var postFields = { api_key:selectedApi.api_key || "", action:"buy", product_id:webProductId, duration:durationParam };352    var savedAndroidId = User.getProperty("android_id") || User.getProperty("android_id_" + userId) || Bot.getProperty("android_id_" + userId) || "";353    if (selectedApi.android_required && !savedAndroidId) {354      Bot.sendMessage("⚠️ Android ID required for this API/product.");355      return;356    }357    if (savedAndroidId) postFields.android_id = String(savedAndroidId);358    var postFieldsString = Object.keys(postFields).map(function(k){ return encodeURIComponent(k) + "=" + encodeURIComponent(postFields[k]); }).join("&");359    User.setProperty("last_pending_api_id", String(selectedApi.id || activeApiId || ""), "string");360 361    User.setProperty("last_pending_price", User.getProperty("buy_price"), "number");362    User.setProperty("last_pending_prod_id", webProductId, "string");363    User.setProperty("last_pending_prod_name", String(product.name).trim(), "string");364    User.setProperty("last_pending_plan_days", cleanPlanDays, "string");365    User.setProperty("last_pending_plan_unit", planUnit, "string");366 367    HTTP.post({368      url: selectedApi.url,369      body: postFieldsString,370      headers: (function(){ var h={"Content-Type":"application/x-www-form-urlencoded"}; if(selectedApi.master_key) h["x-master-key"]=selectedApi.master_key; return h; })(),371      success: "/onWebKeyReceive",372      error: "/onWebKeyError"373    });374 375    User.setProperty("buy_pending_order_id", null);376    User.setProperty("buy_prod_idx", null);377    User.setProperty("buy_plan_idx", null);378    Bot.setProperty("buy_qr_msg_id_" + userId, null, "string");379    User.setProperty("buy_qr_msg_id_" + userId, null, "string");380    Bot.setProperty("buy_qr_caption_" + userId, null, "string");381    User.setProperty("buy_qr_caption_" + userId, null, "string");382    Bot.setProperty("buy_qr_buttons_" + userId, null, "string");383    User.setProperty("buy_qr_buttons_" + userId, null, "string");384    385    User.setProperty("buy_verifying_lock_" + userId, false, "boolean");386 387  } else {388    // ❌ Payment not found — restore original QR caption/buttons, then show dismissible notice389    try {390      var origCaption = Bot.getProperty("buy_qr_caption_" + userId) || User.getProperty("buy_qr_caption_" + userId);391      var origButtons = Bot.getProperty("buy_qr_buttons_" + userId) || User.getProperty("buy_qr_buttons_" + userId);392 393      if (origCaption) {394        Api.editMessageCaption({395          chat_id: chat.chatid,396          message_id: request.message.message_id,397          caption: origCaption,398          parse_mode: "HTML",399          reply_markup: origButtons ? origButtons : undefined400        });401      }402    } catch (e) {}403 404    if (request && request.id) {405      Api.answerCallbackQuery({406        callback_query_id: String(request.id),407        text: "❌ PAYMENT NOT FOUND ❌\nPlease complete the payment first, then tap again.",408        show_alert: true409      });410    }411    User.setProperty("buy_verifying_lock_" + userId, false, "boolean");412  }413 414} catch (err) {415  try {416    User.setProperty("buy_verifying_lock_" + user.telegramid, false, "boolean");417  } catch (e) {}418  Bot.sendMessage("⚠️ <b>Verification Exception:</b> " + err.message, { parse_mode: "HTML" });419}