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
commands/_onSuccessfulPayment.js
javascript · 182 lines
1/**#command2name: /onSuccessfulPayment3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12// =========================================================13// ⭐ Handles Telegram's successful_payment event (Stars payment completed).14// Two payload types:15// "deposit:<userId>:<amount>" -> credit Stars wallet balance16// "buy:<userId>:<prodIdx>:<planIdx>" -> deliver key directly (manual-first, then API)17// ⚠️ PLATFORM NOTE: same routing caveat as _onPreCheckoutQuery.js — this is18// also duplicated as a fallback inside _start.js.19// =========================================================20 21try {22 var sp = (request && request.message && request.message.successful_payment)23 ? request.message.successful_payment24 : (request && request.successful_payment ? request.successful_payment : null);25 26 if (!sp) { return; }27 28 var chatId = chat.chatid;29 var payload = sp.invoice_payload || "";30 var starsPaid = Number(sp.total_amount || 0); // XTR amount = Stars count (no decimals)31 var telegramChargeId = sp.telegram_payment_charge_id || "N/A";32 33 var parts = payload.split(":");34 var mode = parts[0];35 36 // 📒 Log every Stars transaction for admin visibility37 function logStarsTransaction(entry) {38 var log = Bot.getProperty("stars_transactions") || [];39 log.push(entry);40 if (log.length > 500) { log = log.slice(log.length - 500); } // keep it bounded41 Bot.setProperty("stars_transactions", log, "json");42 }43 44 if (mode === "deposit") {45 var depUserId = parts[1];46 var depAmount = Number(parts[2]);47 48 var current = Number(Bot.getProperty("stars_balance_" + depUserId) || 0);49 var newBal = current + starsPaid;50 Bot.setProperty("stars_balance_" + depUserId, newBal, "number");51 52 logStarsTransaction({53 type: "deposit",54 userId: depUserId,55 stars: starsPaid,56 chargeId: telegramChargeId,57 date: new Date().toLocaleString()58 });59 60 Api.sendMessage({61 chat_id: chatId,62 text: "<blockquote>⭐ <b>STARS DEPOSIT SUCCESSFUL!</b></blockquote>\n\n" +63 "⭐ <b>Added:</b> " + starsPaid + " Stars\n" +64 "💫 <b>New Stars Balance:</b> " + newBal + "\n" +65 "🧾 <b>Transaction ID:</b> <code>" + telegramChargeId + "</code>\n\n" +66 "<i>Aapke Stars wallet me add ho gaye!</i>",67 parse_mode: "HTML",68 reply_markup: JSON.stringify({ inline_keyboard: [[{ text: "Back to Menu", callback_data: "/back", style: "primary", icon_custom_emoji_id: "5893163582194978381" }]] })69 });70 71 var ownerId = Bot.getProperty("owner_id") || "8875810358";72 try {73 Api.sendMessage({74 chat_id: ownerId,75 text: "<blockquote>⭐ <b>NEW STARS DEPOSIT</b></blockquote>\n👤 <b>User:</b> <code>" + depUserId + "</code>\n⭐ <b>Amount:</b> " + starsPaid + " Stars\n🧾 <b>Charge ID:</b> <code>" + telegramChargeId + "</code>",76 parse_mode: "HTML"77 });78 } catch (e) {}79 80 } else if (mode === "buy") {81 var buyUserId = parts[1];82 var prodIdx = Number(parts[2]);83 var planIdx = Number(parts[3]);84 85 var productList = Bot.getProperty("stored_products") || [];86 var product = productList[prodIdx];87 var plan = product ? product.plans[planIdx] : null;88 89 if (!product || !plan) {90 Api.sendMessage({ chat_id: chatId, text: "⚠️ Payment received but product config changed. Contact support with charge ID: " + telegramChargeId, parse_mode: "HTML" });91 return;92 }93 94 var planUnit = plan.unit || "day";95 var cleanPlanDays = String(plan.days).replace(/[^0-9.]/g, "").trim();96 var durationDisplay = plan.durationDisplay || (cleanPlanDays + " " + (planUnit === "hour" ? "Hour(s)" : planUnit === "minute" ? "Minute(s)" : "Day(s)"));97 var cleanProdName = product.name.trim().toUpperCase();98 99 // 🔑 MANUAL STOCK FIRST (same rule as the UPI flow — never waste a paid API call if manual stock exists)100 var scopeSuffix = (planUnit === "day") ? cleanPlanDays : (cleanPlanDays + "_" + planUnit);101 var manualKeysStorageKey = "manual_keys_" + cleanProdName + "_" + cleanPlanDays;102 var backupStockKey = "stock_" + product.name.trim() + "_" + cleanPlanDays + "_Day";103 var manualStock = Bot.getProperty(manualKeysStorageKey);104 var isBackupUsed = false;105 if (!manualStock || (Array.isArray(manualStock) && manualStock.length === 0)) {106 manualStock = Bot.getProperty(backupStockKey);107 isBackupUsed = true;108 }109 if (typeof manualStock === "string" && manualStock.trim() !== "") {110 try { manualStock = JSON.parse(manualStock); } catch (e) { manualStock = manualStock.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }111 }112 113 var generatedKey = null;114 if (Array.isArray(manualStock) && manualStock.length > 0) {115 generatedKey = manualStock.shift();116 if (isBackupUsed) { Bot.setProperty(backupStockKey, manualStock, "json"); }117 else { Bot.setProperty(manualKeysStorageKey, manualStock, "json"); }118 }119 120 logStarsTransaction({121 type: "purchase",122 userId: buyUserId,123 product: product.name,124 plan: durationDisplay,125 stars: starsPaid,126 chargeId: telegramChargeId,127 date: new Date().toLocaleString()128 });129 130 if (generatedKey) {131 // ✅ Manual delivery132 var purchaseHistory = User.getProperty("my_purchased_keys") || [];133 purchaseHistory.push({134 productName: product.name,135 days: durationDisplay,136 key: generatedKey,137 cost: starsPaid + " ⭐",138 date: new Date().toLocaleDateString()139 });140 User.setProperty("my_purchased_keys", purchaseHistory, "json");141 142 Api.sendMessage({143 chat_id: chatId,144 text: "<blockquote>⭐ <b>PAYMENT SUCCESSFUL — KEY DELIVERED!</b></blockquote>\n\n" +145 "📦 <b>Product:</b> " + product.name + "\n" +146 "⏳ <b>Duration:</b> " + durationDisplay + "\n" +147 "⭐ <b>Paid:</b> " + starsPaid + " Stars\n" +148 "🔑 <b>Your Key:</b> <code>" + generatedKey + "</code>\n\n" +149 "<i>Enjoy your purchase! 🎉</i>",150 parse_mode: "HTML",151 reply_markup: JSON.stringify({ inline_keyboard: (function() {152 var buttons = [[{ text: "📋 Copy Key", copy_text: { text: generatedKey } }]];153 var productDownloadLink = product.download_link;154 if (productDownloadLink) buttons.push([{ text: "📥 Download Link", url: productDownloadLink, style: "primary", icon_custom_emoji_id: "6091571559233755994" }]);155 buttons.push([{ text: "Back to Menu", callback_data: "/back", style: "primary", icon_custom_emoji_id: "5893163582194978381" }]);156 return buttons;157 })() })158 });159 } else {160 // No manual stock — flag for admin to deliver via existing API/manual process161 Api.sendMessage({162 chat_id: chatId,163 text: "<blockquote>⭐ <b>PAYMENT RECEIVED!</b></blockquote>\n\n" +164 "<i>Manual stock khaali hai — aapki key jald hi deliver ki jaayegi. Agar API-based delivery configured hai, wo bhi automatically try hogi.</i>\n\n" +165 "🧾 <b>Charge ID:</b> <code>" + telegramChargeId + "</code>",166 parse_mode: "HTML"167 });168 }169 170 var ownerId2 = Bot.getProperty("owner_id") || "8875810358";171 try {172 Api.sendMessage({173 chat_id: ownerId2,174 text: "<blockquote>⭐ <b>NEW STARS PURCHASE</b></blockquote>\n👤 <b>User:</b> <code>" + buyUserId + "</code>\n📦 <b>Product:</b> " + product.name + " (" + durationDisplay + ")\n⭐ <b>Paid:</b> " + starsPaid + " Stars\n🔑 <b>Delivery:</b> " + (generatedKey ? "Manual Stock ✅" : "PENDING ⚠️") + "\n🧾 <b>Charge ID:</b> <code>" + telegramChargeId + "</code>",175 parse_mode: "HTML"176 });177 } catch (e) {}178 }179 180} catch (err) {181 try { Bot.sendMessage("⚠️ Successful Payment Handler Error: " + err.message, { parse_mode: "HTML" }); } catch (e2) {}182}