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

javascript · 182 lines

Raw
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}