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/_onBuyCheck.js

javascript · 431 lines

Raw
1/**#command2name: /onBuyCheck3answer: 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  if (/\bbrutal\b/.test(productName)) return n + " DaYs";45 46  // Hours/minutes are preserved exactly; no existing API duration is removed.47  var gh = raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(hour|hours)$/i);48  if (gh) return gh[1] + " Hours";49  var gm = raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(minute|minutes)$/i);50  if (gm) return gm[1] + (Number(gm[1]) === 1 ? " Minute" : " Minutes");51 52  return raw || n + " Days";53}54 55 56try {57  var userId = user.telegramid;58 59  // ✅ CRITICAL FIX: Proper atomic duplicate-payment prevention60  var utrFromContent = null;61  62  // Parse content to get UTR early63  if (content) {64    var res = (typeof content === "object") ? content : JSON.parse(content);65    if (res && res.data && res.data.utr) {66      utrFromContent = res.data.utr;67    }68  }69 70  // 🛑 STEP 1: Check if payment already processed using UTR (most reliable identifier)71  if (utrFromContent && Bot.getProperty("paid_" + utrFromContent)) {72    // ✅ FIX: Vanish the QR completely instead of leaving a stale "already used" caption behind73    try {74      Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message.message_id });75    } catch (e) {}76 77    try {78      Bot.setProperty("buy_qr_msg_id_" + userId, null, "string");79      Bot.setProperty("buy_qr_watch_order_" + userId, null, "string");80      User.setProperty("buy_qr_watch_order_" + userId, null, "string");81      User.setProperty("buy_qr_msg_id_" + userId, null, "string");82    } catch (e) {}83 84    if (request && request.id) {85      try {86        Api.answerCallbackQuery({87          callback_query_id: String(request.id),88          text: "✅ ALREADY CLAIMED ✅\nYe order pehle hi deliver ho chuka hai.",89          show_alert: true90        });91      } catch (e) {}92    }93 94    Api.sendMessage({95      chat_id: chat.chatid,96      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>",97      parse_mode: "HTML",98      reply_markup: JSON.stringify({99        inline_keyboard: [[100          { text: "📜 My Keys", callback_data: "/mykey", style: "primary" },101          { text: "🛒 Shop Menu", callback_data: "/buy_hack", style: "success" }102        ]]103      })104    });105    return;106  }107 108  // 🛑 STEP 2: Duplicate-click lock check109  var isChecking = User.getProperty("buy_verifying_lock_" + userId);110  if (isChecking) {111    if (request && request.id) {112      Api.answerCallbackQuery({113        callback_query_id: String(request.id),114        text: "⏳ ALREADY CHECKING — PLEASE WAIT...",115        show_alert: true116      });117    }118    return;119  }120  121  // 🛑 STEP 3: SET LOCK IMMEDIATELY before any async operations122  User.setProperty("buy_verifying_lock_" + userId, true, "boolean");123 124  if (!content) {125    Api.editMessageCaption({126      chat_id: chat.chatid, message_id: request.message.message_id,127      caption: "<blockquote>⚠️ <b>Server didn't respond.</b>\nClick 'I have paid' again.</blockquote>", parse_mode: "HTML"128    });129    User.setProperty("buy_verifying_lock_" + userId, false, "boolean");130    return;131  }132 133  var res = (typeof content === "object") ? content : JSON.parse(content);134 135  if (res.status === "success" && res.data) {136    var utr = res.data.utr;137    var isPaid = Bot.getProperty("paid_" + utr);138 139    if (isPaid) {140      // ✅ FIX: Vanish the QR completely instead of leaving a stale "already used" caption behind141      try {142        Api.deleteMessage({ chat_id: chat.chatid, message_id: request.message.message_id });143      } catch (e) {}144 145      try {146        Bot.setProperty("buy_qr_msg_id_" + userId, null, "string");147        User.setProperty("buy_qr_msg_id_" + userId, null, "string");148      } catch (e) {}149 150      if (request && request.id) {151        try {152          Api.answerCallbackQuery({153            callback_query_id: String(request.id),154            text: "✅ ALREADY CLAIMED ✅\nYe order pehle hi deliver ho chuka hai.",155            show_alert: true156          });157        } catch (e) {}158      }159 160      Api.sendMessage({161        chat_id: chat.chatid,162        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>",163        parse_mode: "HTML",164        reply_markup: JSON.stringify({165          inline_keyboard: [[166            { text: "📜 My Keys", callback_data: "/mykey", style: "primary" },167            { text: "🛒 Shop Menu", callback_data: "/buy_hack", style: "success" }168          ]]169        })170      });171      User.setProperty("buy_verifying_lock_" + userId, false, "boolean");172      return;173    }174    175    // ✅ IMMEDIATELY mark as paid BEFORE any async API calls to prevent race condition176    Bot.setProperty("paid_" + utr, true, "boolean");177 178    Api.editMessageCaption({179      chat_id: chat.chatid, message_id: request.message.message_id,180      caption: "<tg-emoji emoji-id='6192822213486321961'>🔄</tg-emoji> <b>Payment verified! Delivering your key...</b>",181      parse_mode: "HTML"182    });183 184    // QR payment is for the normal plan-based purchase pipeline.185    // =========================================================186    // 📦 ORIGINAL PLAN-BASED DELIVERY (external xyzcheats API)187    // =========================================================188    var prodIdx = User.getProperty("buy_prod_idx");189    var planIdx = User.getProperty("buy_plan_idx");190    var productList = Bot.getProperty("stored_products") || [];191    var product = productList[prodIdx];192    var plan = product && product.plans ? product.plans[planIdx] : null;193 194    if (!product || !plan) {195      Api.editMessageCaption({196        chat_id: chat.chatid, message_id: request.message.message_id,197        caption: "⚠️ Payment received but product data missing. Contact admin with UTR: " + utr,198        parse_mode: "HTML"199      });200      User.setProperty("buy_verifying_lock_" + userId, false, "boolean");201      return;202    }203 204    var webProductId = String(product.id || "PID_ID").trim();205    var cleanPlanDays = User.getProperty("buy_plan_days") || String(plan.days);206    var planUnit = User.getProperty("buy_plan_unit") || plan.unit || "day";207    var prodNameLower = String(product.name).toLowerCase();208    var durationParam = resolveApiDuration(plan, cleanPlanDays, planUnit, product && product.name);209 210    var unitLabelWordQ = (planUnit === "hour") ? (Number(cleanPlanDays) === 1 ? "Hour" : "Hours") :211                          (planUnit === "minute") ? (Number(cleanPlanDays) === 1 ? "Minute" : "Minutes") :212                          (Number(cleanPlanDays) === 1 ? "Day" : "Days");213    var durationDisplayQ = plan.durationDisplay || (cleanPlanDays + " " + unitLabelWordQ);214    var priceQ = Number(User.getProperty("buy_price") || 0);215 216    // =====================================================217    // 🔑 STEP A — MANUAL STOCK FIRST CHECK (same priority as wallet-balance218    // purchase path in /confirm_buyitem) — agar admin ne /addkey se already219    // keys daal rakhi hain, unhi se seedha deliver karo, external API skip.220    // =====================================================221    var manualKeysStorageKeyQ = "manual_keys_" + String(product.name).trim().toUpperCase() + "_" + cleanPlanDays;222    var backupStockKeyQ = "stock_" + product.name.trim() + "_" + cleanPlanDays + "_Day";223    var isBackupUsedQ = false;224    var manualStockQ = Bot.getProperty(manualKeysStorageKeyQ);225    if (!manualStockQ || (Array.isArray(manualStockQ) && manualStockQ.length === 0)) {226      manualStockQ = Bot.getProperty(backupStockKeyQ);227      isBackupUsedQ = true;228    }229    if (typeof manualStockQ === "string" && manualStockQ.trim() !== "") {230      try { manualStockQ = JSON.parse(manualStockQ); }231      catch (eQ) { manualStockQ = manualStockQ.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }232    }233 234    if (Array.isArray(manualStockQ) && manualStockQ.length > 0) {235      var generatedKeyQ = manualStockQ.shift();236      if (isBackupUsedQ) {237        Bot.setProperty(backupStockKeyQ, manualStockQ, "json");238        var mainStockQ = Bot.getProperty(manualKeysStorageKeyQ) || [];239        if (typeof mainStockQ === "string") { mainStockQ = mainStockQ.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }240        if (Array.isArray(mainStockQ)) {241          var idxQ1 = mainStockQ.indexOf(generatedKeyQ);242          if (idxQ1 > -1) { mainStockQ.splice(idxQ1, 1); }243          Bot.setProperty(manualKeysStorageKeyQ, mainStockQ, "json");244        }245      } else {246        Bot.setProperty(manualKeysStorageKeyQ, manualStockQ, "json");247        var backupStockQ2 = Bot.getProperty(backupStockKeyQ) || [];248        if (typeof backupStockQ2 === "string") { backupStockQ2 = backupStockQ2.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }249        if (Array.isArray(backupStockQ2)) {250          var idxQ2 = backupStockQ2.indexOf(generatedKeyQ);251          if (idxQ2 > -1) { backupStockQ2.splice(idxQ2, 1); }252          Bot.setProperty(backupStockKeyQ, backupStockQ2, "json");253        }254      }255 256      var keysHistoryQ = User.getProperty("my_purchased_keys") || [];257      keysHistoryQ.push({258        product: String(product.name).trim(),259        product_id: product.id || null,260        days: cleanPlanDays,261        price: priceQ,262        key: generatedKeyQ,263        date: new Date().toLocaleDateString()264      });265      User.setProperty("my_purchased_keys", keysHistoryQ, "json");266 267      Api.editMessageCaption({268        chat_id: chat.chatid, message_id: request.message.message_id,269        caption: "<blockquote><b>✅ PURCHASE SUCCESSFUL!</b>\n\n📦 <b>Product:</b> <code>" + String(product.name).trim() + "</code>\n🗝 <b>Validity:</b> <code>" + durationDisplayQ + "</code>\n👆 <b>Your Key:</b> <code>" + generatedKeyQ + "</code></blockquote>",270        parse_mode: "HTML",271        reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "📋 Copy Key", copy_text: { text: generatedKeyQ } }], [{ text: "Back to Menu", callback_data: "/back", style: "danger" }]] })272      });273 274      Api.sendMessage({275        chat_id: (Bot.getProperty("owner_id") || "8477746023"),276        text: "🔔 <b>NEW PURCHASE DELIVERED (MANUAL STOCK — QR PAY)</b> ✔️\n\n👤 <b>Buyer:</b> " + (user.first_name || "User") + " (<code>" + userId + "</code>)\n📦 <b>Product:</b> " + String(product.name).trim() + "\n⏳ <b>Plan:</b> " + durationDisplayQ + "\n💸 <b>Price:</b> ₹" + priceQ.toFixed(2) + "\n🔑 <b>Key:</b> <code>" + generatedKeyQ + "</code>",277        parse_mode: "HTML"278      });279 280      User.setProperty("buy_pending_order_id", null);281      User.setProperty("buy_prod_idx", null);282      User.setProperty("buy_plan_idx", null);283      Bot.setProperty("buy_qr_msg_id_" + userId, null, "string");284      User.setProperty("buy_qr_msg_id_" + userId, null, "string");285      Bot.setProperty("buy_qr_caption_" + userId, null, "string");286      User.setProperty("buy_qr_caption_" + userId, null, "string");287      Bot.setProperty("buy_qr_buttons_" + userId, null, "string");288      User.setProperty("buy_qr_buttons_" + userId, null, "string");289      User.setProperty("buy_verifying_lock_" + userId, false, "boolean");290      return;291    }292 293    // =====================================================294    // 🆕 STEP B — MANUAL-KEY (NO PID) PRODUCT: ADMIN FULFILLS PER ORDER295    // Same as /confirm_buyitem — agar PID khaali/placeholder hai to external296    // API bilkul call nahi hoti, admin ko "Give Key" button milta hai.297    // =====================================================298    var isManualKeyProductQ = product.manual_key_product === true || !webProductId || /^(pid|pid_id|n\/?a|none|skip|-|0)$/i.test(webProductId);299    if (isManualKeyProductQ) {300      var buyerFullNameQ = ((user.first_name || "") + " " + (user.last_name || "")).trim() || "No Name";301      var buyerUsernameQ = user.username ? "@" + user.username : "No Username";302      var manualOrderIdQ = String(Date.now()) + "_" + userId;303 304      Api.editMessageCaption({305        chat_id: chat.chatid, message_id: request.message.message_id,306        caption: "<blockquote>⏳ <b>ORDER PLACED!</b>\n\n📦 <b>Product:</b> <code>" + String(product.name).trim() + "</code>\n🗝 <b>Validity:</b> <code>" + durationDisplayQ + "</code>\n✨ <b>Paid:</b> ₹" + priceQ.toFixed(2) + "\n\n<i>Payment received! Admin aapki key thodi hi der me manually bhej denge, kripya wait karein.</i></blockquote>",307        parse_mode: "HTML",308        reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "Back to Menu", callback_data: "/back", style: "danger" }]] })309      });310 311      // 🔔 Admin ko order details + "Give Key" button — message_id capture312      // karo taaki delivery ke waqt usi message ko EDIT kiya ja sake.313      var adminChatIdQ = Bot.getProperty("owner_id") || "8477746023";314      var adminMsgIdQ = null;315      try {316        var adminAlertResQ = Api.sendMessage({317          chat_id: adminChatIdQ,318          text: "<blockquote>🔔 <b>NEW ORDER — MANUAL KEY REQUIRED</b> 🔑</blockquote>\n\n👤 <b>Buyer:</b> " + buyerFullNameQ + " (" + buyerUsernameQ + ") — <code>" + userId + "</code>\n📦 <b>Product:</b> " + String(product.name).trim() + "\n⏳ <b>Plan:</b> " + durationDisplayQ + "\n💸 <b>Price Paid:</b> ₹" + priceQ.toFixed(2) + "\n\n<i>Neeche button dabaayein aur agli message me KEY type karke bhejein — buyer ko turant deliver ho jaayegi.</i>",319          parse_mode: "HTML",320          reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "🔑 Give Key", callback_data: "/give_key_btn " + manualOrderIdQ, style: "success" }]] })321        });322        adminMsgIdQ = (adminAlertResQ && adminAlertResQ.result && adminAlertResQ.result.message_id) ? adminAlertResQ.result.message_id : (adminAlertResQ && adminAlertResQ.message_id ? adminAlertResQ.message_id : null);323      } catch (e) {}324 325      Bot.setProperty("pending_manual_order_" + manualOrderIdQ, {326        buyerId: String(userId),327        buyerName: buyerFullNameQ,328        buyerUsername: buyerUsernameQ,329        prodName: String(product.name).trim(),330        durationDisplay: durationDisplayQ,331        price: priceQ,332        buyerChatId: String(chat.chatid),333        buyerMsgId: Number(request.message.message_id),334        buyerMsgType: "caption",335        adminChatId: String(adminChatIdQ),336        adminMsgId: adminMsgIdQ337      }, "json");338 339      User.setProperty("buy_pending_order_id", null);340      User.setProperty("buy_prod_idx", null);341      User.setProperty("buy_plan_idx", null);342      Bot.setProperty("buy_qr_msg_id_" + userId, null, "string");343      User.setProperty("buy_qr_msg_id_" + userId, null, "string");344      Bot.setProperty("buy_qr_caption_" + userId, null, "string");345      User.setProperty("buy_qr_caption_" + userId, null, "string");346      Bot.setProperty("buy_qr_buttons_" + userId, null, "string");347      User.setProperty("buy_qr_buttons_" + userId, null, "string");348      User.setProperty("buy_verifying_lock_" + userId, false, "boolean");349      return;350    }351 352    // 🔌 Use configured multi-API system instead of a hardcoded API.353    var apiRegistry = Bot.getProperty("api_registry") || {};354    var activeApiId = Bot.getProperty("active_reseller_api") || "";355    var selectedApi = activeApiId ? apiRegistry[activeApiId] : null;356    if (!selectedApi) {357      selectedApi = { id:"default", url:"https://adminpanels.shop/api/reseller_v1.php", api_key:"9cd415688a9b01920994099cba20180c", master_key:"a7f3e8b2c9d1f4a6b8c2d5e9f1a3b6c8", android_required:false, enabled:true };358    }359    if (selectedApi.enabled === false) {360      Bot.sendMessage("❌ Selected API is disabled. Admin ko /apiset se active API select karna hoga.");361      return;362    }363    var postFields = { api_key:selectedApi.api_key || "", action:"buy", product_id:webProductId, duration:durationParam };364    var savedAndroidId = User.getProperty("android_id") || User.getProperty("android_id_" + userId) || Bot.getProperty("android_id_" + userId) || "";365    if (selectedApi.android_required && !savedAndroidId) {366      Bot.sendMessage("⚠️ Android ID required for this API/product.");367      return;368    }369    if (savedAndroidId) postFields.android_id = String(savedAndroidId);370    var postFieldsString = Object.keys(postFields).map(function(k){ return encodeURIComponent(k) + "=" + encodeURIComponent(postFields[k]); }).join("&");371    User.setProperty("last_pending_api_id", String(selectedApi.id || activeApiId || ""), "string");372 373    User.setProperty("last_pending_price", User.getProperty("buy_price"), "number");374    User.setProperty("last_pending_prod_id", webProductId, "string");375    User.setProperty("last_pending_prod_name", String(product.name).trim(), "string");376    User.setProperty("last_pending_plan_days", cleanPlanDays, "string");377    User.setProperty("last_pending_plan_unit", planUnit, "string");378 379    HTTP.post({380      url: selectedApi.url,381      body: postFieldsString,382      headers: (function(){ var h={"Content-Type":"application/x-www-form-urlencoded"}; if(selectedApi.master_key) h["x-master-key"]=selectedApi.master_key; return h; })(),383      success: "/onWebKeyReceive",384      error: "/onWebKeyError"385    });386 387    User.setProperty("buy_pending_order_id", null);388    User.setProperty("buy_prod_idx", null);389    User.setProperty("buy_plan_idx", null);390    Bot.setProperty("buy_qr_msg_id_" + userId, null, "string");391    User.setProperty("buy_qr_msg_id_" + userId, null, "string");392    Bot.setProperty("buy_qr_caption_" + userId, null, "string");393    User.setProperty("buy_qr_caption_" + userId, null, "string");394    Bot.setProperty("buy_qr_buttons_" + userId, null, "string");395    User.setProperty("buy_qr_buttons_" + userId, null, "string");396    397    User.setProperty("buy_verifying_lock_" + userId, false, "boolean");398 399  } else {400    // ❌ Payment not found — restore original QR caption/buttons, then show dismissible notice401    try {402      var origCaption = Bot.getProperty("buy_qr_caption_" + userId) || User.getProperty("buy_qr_caption_" + userId);403      var origButtons = Bot.getProperty("buy_qr_buttons_" + userId) || User.getProperty("buy_qr_buttons_" + userId);404 405      if (origCaption) {406        Api.editMessageCaption({407          chat_id: chat.chatid,408          message_id: request.message.message_id,409          caption: origCaption,410          parse_mode: "HTML",411          reply_markup: origButtons ? origButtons : undefined412        });413      }414    } catch (e) {}415 416    if (request && request.id) {417      Api.answerCallbackQuery({418        callback_query_id: String(request.id),419        text: "❌ PAYMENT NOT FOUND ❌\nPlease complete the payment first, then tap again.",420        show_alert: true421      });422    }423    User.setProperty("buy_verifying_lock_" + userId, false, "boolean");424  }425 426} catch (err) {427  try {428    User.setProperty("buy_verifying_lock_" + user.telegramid, false, "boolean");429  } catch (e) {}430  Bot.sendMessage("⚠️ <b>Verification Exception:</b> " + err.message, { parse_mode: "HTML" });431}