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

javascript · 186 lines

Raw
1/**#command2name: /buyitem3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12// =========================================================13// 🚀 PLAN CLICK HANDLER — Premium "Payment Method" confirmation screen14// (Pay from Wallet / Pay via UPI / Apply Coupon / Back to Shop)15// ✅ Supports Hour / Minute / Day duration units16// ✅ Supports coupon discounts (global or product-specific)17// =========================================================18 19try {20  var productList = Bot.getProperty("stored_products") || [];21  var callbackId = (request && request.id) ? request.id : ((request && request.callback_query && request.callback_query.id) || null);22  var chatId = chat.chatid;23  var userId = user.telegramid;24 25  var parts = params ? params.split(" ") : [];26  if (parts.length < 2) {27    var cbData = (request && request.callback_query) ? request.callback_query.data : "";28    parts = cbData.replace("buyitem ", "").split(" ");29  }30 31  var prodIdx = Number(parts[0]);32  var planIdx = Number(parts[1]);33 34  var product = productList[prodIdx];35  if (!product) {36    Bot.sendMessage("❌ Product configuration missing!");37    return;38  }39 40  // /viewprod legacy products ko default plans dikhata hai.41  // Yahan bhi wahi fallback use karo, warna plan click par42  // "Product or Plan configuration missing" error aata tha.43  var productPlans = Array.isArray(product.plans) ? product.plans : [];44  if (productPlans.length === 0) {45    productPlans = [46      { days: "1", normal_price: "79", reseller_price: "65" },47      { days: "7", normal_price: "350", reseller_price: "300" }48    ];49  }50 51  if (!productPlans[planIdx]) {52    Bot.sendMessage("❌ Plan configuration missing!");53    return;54  }55 56  if (product.out_of_stock === true) {57    Bot.sendMessage("<blockquote>🛒 <b>" + String(product.name).toUpperCase() + "</b></blockquote>\n<blockquote>👇 <b>NOTICE: THIS PRODUCT IS CURRENTLY UNDER MAINTENANCE.</b></blockquote>\n\nPlease check back later or contact admin support.", { parse_mode: "HTML" });58    return;59  }60 61  var plan = productPlans[planIdx];62  var planUnit = plan.unit || "day";63  var cleanPlanDays = String(plan.days).replace(/[^0-9.]/g, "").trim();64  var unitLabelWord = (planUnit === "hour") ? (Number(cleanPlanDays) === 1 ? "Hour" : "Hours") :65                       (planUnit === "minute") ? (Number(cleanPlanDays) === 1 ? "Minute" : "Minutes") :66                       (Number(cleanPlanDays) === 1 ? "Day" : "Days");67  var durationDisplay = plan.durationDisplay || (cleanPlanDays + " " + unitLabelWord);68 69  var unifiedBal = (function () {70    var resBal = 0;71    try { resBal = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (e) {}72    return resBal;73  })();74 75  var isReseller = Bot.getProperty("is_reseller_" + userId) === true;76  var cleanProdName = product.name.trim().toUpperCase();77 78  // ✅ Unit-aware price key (Day plans keep the old key format for backward-compat)79  var priceKeySuffix = (planUnit === "day") ? cleanPlanDays : (cleanPlanDays + "_" + planUnit);80  var normalKey = "price_normal_" + cleanProdName + "_" + priceKeySuffix;81  var resellerKey = "price_reseller_" + cleanProdName + "_" + priceKeySuffix;82 83  var adminNormalPrice = Bot.getProperty(normalKey);84  var adminResellerPrice = Bot.getProperty(resellerKey);85 86  var currentNormal = (adminNormalPrice !== undefined && adminNormalPrice !== null) ? adminNormalPrice : plan.normal_price;87  var currentReseller = (adminResellerPrice !== undefined && adminResellerPrice !== null) ? adminResellerPrice : plan.reseller_price;88 89  var originalPrice = isReseller ? Number(currentReseller) : Number(currentNormal);90  var price = originalPrice;91 92  // 💸 Auto-discount (admin-set, no coupon code needed) — plan-specific > product-wide > global93  var planSpecificDiscKey = "auto_discount_" + cleanProdName + "_" + cleanPlanDays + "_" + planUnit.toUpperCase();94  var productWideDiscKey = "auto_discount_" + cleanProdName + "_ALL";95  var autoDiscountPercent = Bot.getProperty(planSpecificDiscKey) || Bot.getProperty(productWideDiscKey) || Bot.getProperty("auto_discount_global") || 0;96 97  // 🎟 Coupon check (if user applied one for this exact prod/plan) — coupon overrides auto-discount98  var appliedCouponCode = User.getProperty("applied_coupon_" + prodIdx + "_" + planIdx);99  var couponDiscountPercent = 0;100  if (appliedCouponCode) {101    var couponRec = Bot.getProperty("coupon_" + appliedCouponCode);102    if (couponRec && couponRec.discountPercent) {103      couponDiscountPercent = couponRec.discountPercent;104      price = Number((originalPrice * (1 - couponDiscountPercent / 100)).toFixed(2));105    }106  } else if (autoDiscountPercent > 0) {107    couponDiscountPercent = autoDiscountPercent; // reuse the same display variable108    price = Number((originalPrice * (1 - autoDiscountPercent / 100)).toFixed(2));109  }110 111  // 💎 PREMIUM EMOJI SET (verified valid custom-emoji IDs from your reference bot)112  var e_diamond = "<tg-emoji emoji-id='6266967801580231067'>💎</tg-emoji>";113  var e_pack   = "<tg-emoji emoji-id='6147767796097884213'>📦</tg-emoji>";114  var e_hour   = "<tg-emoji emoji-id='6147936236125298267'>⏳</tg-emoji>";115  var e_tag    = "<tg-emoji emoji-id='6080214566191505147'>🏷</tg-emoji>";116  var e_wallet = "<tg-emoji emoji-id='5348392971207194994'>💳</tg-emoji>";117  var e_check  = "<tg-emoji emoji-id='6100657257605763582'>✔️</tg-emoji>";118  var e_offer  = "<tg-emoji emoji-id='6102856637343600044'>🎉</tg-emoji>";119  var e_lock   = "<tg-emoji emoji-id='6215386799133433653'>🔒</tg-emoji>";120  var e_coupon = "<tg-emoji emoji-id='6093677128295914531'>🎫</tg-emoji>";121  var e_back   = "<tg-emoji emoji-id='5893163582194978381'>⬅️</tg-emoji>";122 123  var priceLine = couponDiscountPercent > 0124    ? e_tag + " <b>Price:</b> <s>₹" + originalPrice.toFixed(2) + "</s> ➜ <b>₹" + price.toFixed(2) + "</b>  " + e_offer + " <b>-" + couponDiscountPercent + "%</b>"125    : e_tag + " <b>Price:</b> ₹<code>" + price.toFixed(2) + "</code>";126 127  // =====================================================128  // 💎 PREMIUM CHECKOUT SCREEN — always shown on plan click129  // =====================================================130  var confirmText =131    "<blockquote>" + e_diamond + " <b>CONFIRM YOUR ORDER</b> " + e_diamond + "</blockquote>\n" +132    "━━━━━━━━━━━━━━━━━━━━━\n\n" +133    e_pack + " <b>Product:</b> " + product.name + "\n" +134    e_hour + " <b>Duration:</b> " + durationDisplay + "\n" +135    priceLine + "\n" +136    e_wallet + " <b>Wallet Balance:</b> ₹<code>" + unifiedBal.toFixed(2) + "</code>\n\n" +137    "━━━━━━━━━━━━━━━━━━━━━\n" +138    e_lock + " <i>Secure checkout — choose a payment method below</i> " + e_check;139 140  var confirmButtons = [];141 142  if (unifiedBal >= price) {143    confirmButtons.push([144      { text: "💳 Pay ₹" + price.toFixed(2) + " from Wallet", callback_data: "/confirm_buyitem " + prodIdx + " " + planIdx, style: "success", icon_custom_emoji_id: "6100657257605763582" }145    ]);146  } else {147    var needToPayPreview = (price - unifiedBal).toFixed(2);148    confirmButtons.push([149      { text: "💸 Pay ₹" + needToPayPreview + " via UPI", callback_data: "/pay_upi " + prodIdx + " " + planIdx, style: "success", icon_custom_emoji_id: "5348392971207194994" }150    ]);151  }152 153  confirmButtons.push([154    { text: "🎫 Apply Coupon Code", callback_data: "/apply_coupon " + prodIdx + " " + planIdx, style: "primary", icon_custom_emoji_id: "6093677128295914531" }155  ]);156  confirmButtons.push([157    { text: "Back to Shop", callback_data: "/buy_hack", style: "danger" }158  ]);159 160  if (request && request.message) {161    Api.editMessageText({162      chat_id: String(chatId),163      message_id: Number(request.message.message_id),164      text: confirmText,165      parse_mode: "HTML",166      reply_markup: JSON.stringify({ inline_keyboard: confirmButtons })167    });168  } else {169    Api.sendMessage({170      chat_id: String(chatId),171      text: confirmText,172      parse_mode: "HTML",173      reply_markup: JSON.stringify({ inline_keyboard: confirmButtons })174    });175  }176 177  if (callbackId) {178    Api.answerCallbackQuery({ callback_query_id: String(callbackId) });179  }180 181} catch (e) {182  var errChatId = (typeof chat !== "undefined" && chat && chat.chatid) ? chat.chatid : null;183  if (errChatId) {184    try { Api.sendMessage({ chat_id: errChatId, text: "❌ <b>Error:</b> <code>" + e.message + "</code>", parse_mode: "HTML" }); } catch (fatal) {}185  }186}