indrajitghosh20006/Testseller_01botPublic · Bot Template

ProfileTelegram

AIThis bot provides an admin‑controlled system for managing user balances, products, and reseller roles. It includes commands to add balances (via manual input, Binance Pay, or UPI), approve and credit payments, and set up product listings with categories and pricing. Admins can also add resellers, view reseller info, and manage stock entries. The bot uses built‑in TeleBotHost APIs such as Bot, Api, HTTP, and Libs for database operations and message handling.

Commerceadminbalanceproductresellerpaymentsbinance
138 commands0 envUpdated 17h agoCreated Sep 27, 2026
Back to folder

commands/_buyitem.js

javascript · 169 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 || !product.plans || !product.plans[planIdx]) {36    Bot.sendMessage("❌ Product or Plan configuration missing!");37    return;38  }39 40  var plan = product.plans[planIdx];41  var globalMaintenance = Bot.getProperty("maintenance_mode") === true;42  if (globalMaintenance) { Bot.sendMessage("🛠 <b>BOT UNDER MAINTENANCE</b>\n\n<i>Purchases are temporarily unavailable.</i>",{parse_mode:"HTML"}); return; }43  if (product.maintenance === true) { Bot.sendMessage("🛠 <b>PRODUCT ON MAINTENANCE</b>\n\n📦 <b>" + product.name + "</b> is temporarily unavailable.",{parse_mode:"HTML"}); return; }44  if (plan.out_of_stock === true) { Bot.sendMessage("🟠 <b>OUT OF STOCK</b>\n\n⏳ <b>Validity:</b> " + (plan.durationDisplay || plan.days) + "\n<i>Please choose another plan.</i>",{parse_mode:"HTML"}); return; }45  var planUnit = plan.unit || "day";46  var cleanPlanDays = String(plan.days).replace(/[^0-9.]/g, "").trim();47  var unitLabelWord = (planUnit === "hour") ? (Number(cleanPlanDays) === 1 ? "Hour" : "Hours") :48                       (planUnit === "minute") ? (Number(cleanPlanDays) === 1 ? "Minute" : "Minutes") :49                       (Number(cleanPlanDays) === 1 ? "Day" : "Days");50  var durationDisplay = plan.durationDisplay || (cleanPlanDays + " " + unitLabelWord);51 52  var unifiedBal = (function () {53    var resBal = 0;54    try { resBal = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (e) {}55    return resBal;56  })();57 58  var isReseller = Bot.getProperty("is_reseller_" + userId) === true;59  var cleanProdName = product.name.trim().toUpperCase();60 61  // ✅ Unit-aware price key (Day plans keep the old key format for backward-compat)62  var priceKeySuffix = (planUnit === "day") ? cleanPlanDays : (cleanPlanDays + "_" + planUnit);63  var normalKey = "price_normal_" + cleanProdName + "_" + priceKeySuffix;64  var resellerKey = "price_reseller_" + cleanProdName + "_" + priceKeySuffix;65 66  var adminNormalPrice = Bot.getProperty(normalKey);67  var adminResellerPrice = Bot.getProperty(resellerKey);68 69  var currentNormal = (adminNormalPrice !== undefined && adminNormalPrice !== null) ? adminNormalPrice : plan.normal_price;70  var currentReseller = (adminResellerPrice !== undefined && adminResellerPrice !== null) ? adminResellerPrice : plan.reseller_price;71 72  var originalPrice = isReseller ? Number(currentReseller) : Number(currentNormal);73  var price = originalPrice;74 75  // 💸 Auto-discount (admin-set, no coupon code needed) — plan-specific > product-wide > global76  var planSpecificDiscKey = "auto_discount_" + cleanProdName + "_" + cleanPlanDays + "_" + planUnit.toUpperCase();77  var productWideDiscKey = "auto_discount_" + cleanProdName + "_ALL";78  var autoDiscountPercent = Bot.getProperty(planSpecificDiscKey) || Bot.getProperty(productWideDiscKey) || Bot.getProperty("auto_discount_global") || 0;79 80  // 🎟 Coupon check (if user applied one for this exact prod/plan) — coupon overrides auto-discount81  var appliedCouponCode = User.getProperty("applied_coupon_" + prodIdx + "_" + planIdx);82  var couponDiscountPercent = 0;83  if (appliedCouponCode) {84    var couponRec = Bot.getProperty("coupon_" + appliedCouponCode);85    if (couponRec && couponRec.discountPercent) {86      couponDiscountPercent = couponRec.discountPercent;87      price = Number((originalPrice * (1 - couponDiscountPercent / 100)).toFixed(2));88    }89  } else if (autoDiscountPercent > 0) {90    couponDiscountPercent = autoDiscountPercent; // reuse the same display variable91    price = Number((originalPrice * (1 - autoDiscountPercent / 100)).toFixed(2));92  }93 94  // 💎 PREMIUM EMOJI SET (verified valid custom-emoji IDs from your reference bot)95  var e_diamond = "<tg-emoji emoji-id='6266967801580231067'>💎</tg-emoji>";96  var e_pack   = "<tg-emoji emoji-id='6147767796097884213'>📦</tg-emoji>";97  var e_hour   = "<tg-emoji emoji-id='6147936236125298267'>⏳</tg-emoji>";98  var e_tag    = "<tg-emoji emoji-id='6080214566191505147'>🏷</tg-emoji>";99  var e_wallet = "<tg-emoji emoji-id='5348392971207194994'>💳</tg-emoji>";100  var e_check  = "<tg-emoji emoji-id='6100657257605763582'>✔️</tg-emoji>";101  var e_offer  = "<tg-emoji emoji-id='6102856637343600044'>🎉</tg-emoji>";102  var e_lock   = "<tg-emoji emoji-id='6215386799133433653'>🔒</tg-emoji>";103  var e_coupon = "<tg-emoji emoji-id='6093677128295914531'>🎫</tg-emoji>";104  var e_back   = "<tg-emoji emoji-id='5893163582194978381'>⬅️</tg-emoji>";105 106  var priceLine = couponDiscountPercent > 0107    ? e_tag + " <b>Price:</b> <s>₹" + originalPrice.toFixed(2) + "</s> ➜ <b>₹" + price.toFixed(2) + "</b>  " + e_offer + " <b>-" + couponDiscountPercent + "%</b>"108    : e_tag + " <b>Price:</b> ₹<code>" + price.toFixed(2) + "</code>";109 110  // =====================================================111  // 💎 PREMIUM CHECKOUT SCREEN — always shown on plan click112  // =====================================================113  var confirmText =114    "<blockquote>" + e_diamond + " <b>CONFIRM YOUR ORDER</b> " + e_diamond + "</blockquote>\n" +115    "━━━━━━━━━━━━━━━━━━━━━\n\n" +116    e_pack + " <b>Product:</b> " + product.name + "\n" +117    e_hour + " <b>Duration:</b> " + durationDisplay + "\n" +118    priceLine + "\n" +119    e_wallet + " <b>Wallet Balance:</b> ₹<code>" + unifiedBal.toFixed(2) + "</code>\n\n" +120    "━━━━━━━━━━━━━━━━━━━━━\n" +121    e_lock + " <i>Secure checkout — choose a payment method below</i> " + e_check;122 123  var confirmButtons = [];124 125  if (unifiedBal >= price) {126    confirmButtons.push([127      { text: "Pay ₹" + price.toFixed(2) + " from Wallet", callback_data: "/confirm_buyitem " + prodIdx + " " + planIdx, style: "success", icon_custom_emoji_id: "6100657257605763582" }128    ]);129  } else {130    var needToPayPreview = (price - unifiedBal).toFixed(2);131    confirmButtons.push([132      { text: "Pay ₹" + needToPayPreview + " via UPI", callback_data: "/pay_upi " + prodIdx + " " + planIdx, style: "success", icon_custom_emoji_id: "5348392971207194994" }133    ]);134  }135 136  confirmButtons.push([137    { text: "Apply Coupon Code", callback_data: "/apply_coupon " + prodIdx + " " + planIdx, style: "primary", icon_custom_emoji_id: "6093677128295914531" }138  ]);139  confirmButtons.push([140    { text: "Back to Shop", callback_data: "/buy_hack", style: "danger", icon_custom_emoji_id: "5893163582194978381" }141  ]);142 143  if (request && request.message) {144    Api.editMessageText({145      chat_id: String(chatId),146      message_id: Number(request.message.message_id),147      text: confirmText,148      parse_mode: "HTML",149      reply_markup: JSON.stringify({ inline_keyboard: confirmButtons })150    });151  } else {152    Api.sendMessage({153      chat_id: String(chatId),154      text: confirmText,155      parse_mode: "HTML",156      reply_markup: JSON.stringify({ inline_keyboard: confirmButtons })157    });158  }159 160  if (callbackId) {161    Api.answerCallbackQuery({ callback_query_id: String(callbackId) });162  }163 164} catch (e) {165  var errChatId = (typeof chat !== "undefined" && chat && chat.chatid) ? chat.chatid : null;166  if (errChatId) {167    try { Api.sendMessage({ chat_id: errChatId, text: "❌ <b>Error:</b> <code>" + e.message + "</code>", parse_mode: "HTML" }); } catch (fatal) {}168  }169}