indrajitghosh20006/Igstore_01botPublic Β· Bot Template
AIThe bot provides an admin interface for a digital store, allowing the owner or coβadmins to add balances, products, plans, and categories. It supports payment workflows via UPI and Binance Pay, automatically generating QR codes and handling manual approval of deposits. The code patches inline keyboards to use premium emoji icons and includes helper functions for user and bot properties. Overall, it serves as a commerce management tool for a Telegram-based storefront.
Commercestoreadminbalanceproductplancategory
170 commands0 envUpdated 8h agoCreated Oct 30, 2026
commands/_confirm_buyitem.js
javascript Β· 542 lines
1/**#command2name: /confirm_buyitem3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12// PREMIUM BUTTON ICONS13(function(){14 try {15 if (!JSON.__premiumPatched) {16 var __origStringify = JSON.stringify;17 JSON.stringify = function(value, replacer, space) {18 try {19 if (value && value.inline_keyboard && Array.isArray(value.inline_keyboard)) {20 var premiumIds = [21 "6143444134125379822",22 "6091379307907652768",23 "6147534454819661264",24 "6147817325660741985",25 "6235683689292897318",26 "6102856637343600044"27 ];28 var rows = value.inline_keyboard.map(function(row, ri) {29 if (!Array.isArray(row)) return row;30 return row.map(function(btn, bi) {31 if (!btn || typeof btn !== "object") return btn;32 var copy = {};33 for (var k in btn) copy[k] = btn[k];34 if (!copy.icon_custom_emoji_id) copy.icon_custom_emoji_id = premiumIds[(ri + bi) % premiumIds.length];35 return copy;36 });37 });38 var cloned = {};39 for (var key in value) cloned[key] = value[key];40 cloned.inline_keyboard = rows;41 return __origStringify.call(JSON, cloned, replacer, space);42 }43 } catch (e) {}44 return __origStringify.call(JSON, value, replacer, space);45 };46 JSON.__premiumPatched = true;47 }48 } catch (e) {}49})();50 51/**#command52name: /confirm_buyitem53answer: 54keyboard: 55parse_mode: markdown56aliases: 57allow_only_group: false58need_reply: false59case_insensitive: false60is_web: 061#command**/62 63function resolveApiDuration(plan, cleanPlanDays, planUnit, productNameOverride) {64 // IMPORTANT: Keep the admin/API duration name exactly as entered.65 // The product-specific day ranges below are used only when the stored plan66 // contains a plain numeric Day duration; this lets 1-30 Day plans target67 // the exact website/API names requested by the admin without changing any68 // other product data or purchase logic.69 var raw = String((plan && (plan.api_duration || plan.name_on_website || plan.durationDisplay || plan.name || plan.title)) || "").replace(/\s+/g, " ").trim();70 71 // Already-custom API labels (including casing/suffixes) must pass through unchanged.72 if (raw && !/^[0-9]+(?:\.[0-9]+)?\s*(day|days)$/i.test(raw)) {73 return raw;74 }75 76 var dayMatch = raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(day|days)$/i);77 var n = dayMatch ? dayMatch[1] : String(cleanPlanDays || "1");78 var productName = String(productNameOverride || (plan && (plan.product_name || plan.productName || plan.product || plan.category)) || "").trim().toLowerCase();79 80 // If product name is not stored on the plan, the caller's raw API label is81 // still preserved above. Generic numeric Day plans remain "N Days".82 if (/pc\s*aim\s*silent/.test(productName)) return n + " Day Pc Aim Silent";83 if (/pc\s*modmenu\s*x86/.test(productName)) return n + " Day Pc Modmenu x86";84 if (/pc\s*bypass\s*\+\s*silent/.test(productName) || /bypass\s*\+\s*silent/.test(productName)) return n + " Days Pc Bypass + Silent";85 if (/nonroot/.test(productName) && !/root\s*\+\s*nonroot/.test(productName)) return n + " DaYS NONROOT";86 if (/pc\s*aimkill/.test(productName) || /aimkill/.test(productName)) return n + " DaYS PC AIMKILL";87 if (/root\s*\+\s*nonroot/.test(productName)) return n + " DaYs Root + Nonroot";88 if (/fluo?rite\s*ff/.test(productName)) return n + " DAYs FluoRite FF";89 if (/\broot\b/.test(productName)) return n + " DaYs ROOT";90 if (/all\s*colou?rs\s*mix/.test(productName)) return n + " DaYs All Colours Mix";91 if (/\bbasic\b/.test(productName)) return n + " DaYs Basic";92 if (/\bpro\b/.test(productName)) return n + " DaYs PRO";93 if (/\bsafe\b/.test(productName)) return n + " DaYs SAFE";94 if (/\bbrutal\b/.test(productName)) return n + " DaYs BRUTAL";95 if (/\bbrutal\b/.test(productName)) return n + " DaYs";96 97 // Hours/minutes are preserved exactly; no existing API duration is removed.98 var gh = raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(hour|hours)$/i);99 if (gh) return gh[1] + " Hours";100 var gm = raw.match(/^([0-9]+(?:\.[0-9]+)?)\s*(minute|minutes)$/i);101 if (gm) return gm[1] + (Number(gm[1]) === 1 ? " Minute" : " Minutes");102 103 return raw || n + " Days";104}105 106 107// =========================================================108// β
ACTUAL PURCHASE EXECUTION β runs after user taps "Confirm" on the109// premium confirmation screen, OR automatically right after a shortfall110// QR payment is verified (see _onCheck.js), so key delivery is fully automatic.111// =========================================================112 113try {114 115 // π PANEL MAINTENANCE GUARD116 // Re-check at every purchase/payment stage so an admin can switch a panel117 // OFF even if a user already opened the checkout screen.118 function isPanelUnderMaintenance(product) {119 if (!product) return false;120 var mKey = "panel_maintenance_" +121 String(product.id || product.name || "").toUpperCase().replace(/[^A-Z0-9_-]/g, "_");122 return Bot.getProperty(mKey) === true;123 }124 125 var productList = Bot.getProperty("stored_products") || [];126 var chatId = chat.chatid;127 var userId = user.telegramid;128 129 var parts = params ? String(params).trim().split(" ") : [];130 var prodIdx = Number(parts[0]);131 var planIdx = Number(parts[1]);132 133 var product = productList[prodIdx];134 // π PANEL MAINTENANCE CHECK135 var panelMaintenanceKey = "panel_maintenance_" +136 String(product && (product.id || product.name) || prodIdx).toUpperCase().replace(/[^A-Z0-9_-]/g, "_");137 if (product && Bot.getProperty(panelMaintenanceKey) === true) {138 var maintenanceText = "π <b>PANEL UNDER MAINTENANCE</b>\n\n" +139 "π¦ <b>Panel:</b> <code>" + String(product.name || "Product") + "</code>\n\n" +140 "β³ Purchase/payment is temporarily disabled for this panel.\nPlease try again later.";141 var maintenanceCb = (request && request.id) ? request.id : ((request && request.callback_query && request.callback_query.id) || null);142 if (maintenanceCb) {143 try { Api.answerCallbackQuery({ callback_query_id: String(maintenanceCb), text: "π Panel is under maintenance", show_alert: true }); } catch (e) {}144 }145 if (request && request.message && request.message.message_id) {146 try {147 Api.editMessageText({148 chat_id: String(chatId),149 message_id: Number(request.message.message_id),150 text: maintenanceText,151 parse_mode: "HTML",152 reply_markup: JSON.stringify({ inline_keyboard: [[153 { text: "β¬
οΈ Back to Shop", callback_data: "/buy_hack", style: "danger", icon_custom_emoji_id: "5893163582194978381" }154 ]] })155 });156 } catch (e) {157 Api.sendMessage({ chat_id: String(chatId), text: maintenanceText, parse_mode: "HTML" });158 }159 } else {160 Api.sendMessage({ chat_id: String(chatId), text: maintenanceText, parse_mode: "HTML" });161 }162 return;163 }164 165 if (!product || !product.plans || !product.plans[planIdx]) {166 Api.sendMessage({ chat_id: chatId, text: "β Product or Plan configuration missing!" });167 return;168 }169 170 var plan = product.plans[planIdx];171 var planUnit = plan.unit || "day";172 var isReseller = Bot.getProperty("is_reseller_" + userId) === true;173 174 var cleanProdName = product.name.trim().toUpperCase();175 var cleanPlanDays = String(plan.days).replace(/[^0-9.]/g, "").trim();176 var unitLabelWord = (planUnit === "hour") ? (Number(cleanPlanDays) === 1 ? "Hour" : "Hours") :177 (planUnit === "minute") ? (Number(cleanPlanDays) === 1 ? "Minute" : "Minutes") :178 (Number(cleanPlanDays) === 1 ? "Day" : "Days");179 var durationDisplay = plan.durationDisplay || (cleanPlanDays + " " + unitLabelWord);180 181 var priceKeySuffix = (planUnit === "day") ? cleanPlanDays : (cleanPlanDays + "_" + planUnit);182 var normalKey = "price_normal_" + cleanProdName + "_" + priceKeySuffix;183 var resellerKey = "price_reseller_" + cleanProdName + "_" + priceKeySuffix;184 185 var adminNormalPrice = Bot.getProperty(normalKey);186 var adminResellerPrice = Bot.getProperty(resellerKey);187 188 var currentNormal = (adminNormalPrice !== undefined && adminNormalPrice !== null) ? adminNormalPrice : plan.normal_price;189 var currentReseller = (adminResellerPrice !== undefined && adminResellerPrice !== null) ? adminResellerPrice : plan.reseller_price;190 191 var basePrice = isReseller ? Number(currentReseller) : Number(currentNormal);192 var memberPriceKey = "member_custom_price_" + userId + "_" + cleanProdName.replace(/[^A-Z0-9_-]/g, "_") + "_" + ((planUnit === "day") ? cleanPlanDays : (cleanPlanDays + "_hour"));193 var memberCustomPrice = Bot.getProperty(memberPriceKey);194 var hasMemberCustomPrice = memberCustomPrice !== undefined && memberCustomPrice !== null && isFinite(Number(memberCustomPrice));195 var originalPrice = hasMemberCustomPrice ? Number(memberCustomPrice) : basePrice;196 var price = originalPrice;197 198 var planSpecificDiscKey = "auto_discount_" + cleanProdName + "_" + cleanPlanDays + "_" + planUnit.toUpperCase();199 var productWideDiscKey = "auto_discount_" + cleanProdName + "_ALL";200 var autoDiscountPercent = Bot.getProperty(planSpecificDiscKey) || Bot.getProperty(productWideDiscKey) || Bot.getProperty("auto_discount_global") || 0;201 202 // π Apply coupon discount (if any was applied for this exact prod/plan) β coupon overrides auto-discount203 var appliedCouponCode = User.getProperty("applied_coupon_" + prodIdx + "_" + planIdx);204 var couponDiscountPercent = 0;205 if (appliedCouponCode) {206 var couponRec0 = Bot.getProperty("coupon_" + appliedCouponCode);207 if (couponRec0 && couponRec0.discountPercent) {208 couponDiscountPercent = couponRec0.discountPercent;209 price = Number((originalPrice * (1 - couponDiscountPercent / 100)).toFixed(2));210 }211 User.setProperty("applied_coupon_" + prodIdx + "_" + planIdx, null, "string");212 } else if (autoDiscountPercent > 0) {213 couponDiscountPercent = autoDiscountPercent;214 price = Number((originalPrice * (1 - autoDiscountPercent / 100)).toFixed(2));215 }216 217 // π‘οΈ Safety re-check: balance abhi bhi sufficient hai ya nahi (race-condition guard)218 var unifiedBal = (function () {219 var resBal = 0;220 try { resBal = Number(Libs.ResourcesLib.userRes("balance").value()) || 0; } catch (e) {}221 var bonusBal = Number(Bot.getProperty("balance" + userId) || 0);222 return resBal + bonusBal;223 })();224 225 if (unifiedBal < price) {226 Api.sendMessage({227 chat_id: chatId,228 text: "β οΈ <b>Balance abhi kam hai.</b> Kripya phir se try karein.",229 parse_mode: "HTML"230 });231 return;232 }233 234 // =====================================================235 // π STEP 0 β MANUAL STOCK FIRST CHECK (β
NEW)236 // Agar admin ne manually koi key already daal rakhi hai, to wahi seedha237 // deliver karo aur PAID EXTERNAL API ko bilkul call hi mat karo β taaki238 // "1 available key ke liye 2 keys spend" (1 manual + 1 wasted API buy)239 // wala bug kabhi na ho. API sirf tabhi call hoga jab manual stock khaali ho.240 // =====================================================241 var pDaysNumOnly = cleanPlanDays;242 // Isolate stock by PRODUCT + duration + unit. 1 DAY and 1 HOUR never share stock.243 var productStockSlug = cleanProdName.replace(/[^A-Z0-9_-]/g, "_");244 var unitAwareManualKey = "manual_keys_" + productStockSlug + "_" + pDaysNumOnly + "_" + planUnit;245 var legacyDayKey = "manual_keys_" + cleanProdName + "_" + pDaysNumOnly;246 var manualKeysStorageKey = unitAwareManualKey;247 var backupStockKey = "stock_" + product.name.trim() + "_" + pDaysNumOnly + "_Day";248 var isBackupUsed = false;249 250 var manualStock = Bot.getProperty(manualKeysStorageKey);251 252 // Backward compatibility for old Day-only stock buckets.253 if ((!manualStock || (Array.isArray(manualStock) && manualStock.length === 0)) &&254 planUnit === "day" && legacyDayKey !== manualKeysStorageKey) {255 manualStock = Bot.getProperty(legacyDayKey);256 if (manualStock && (!Array.isArray(manualStock) || manualStock.length > 0)) {257 manualKeysStorageKey = legacyDayKey;258 }259 }260 261 if (!manualStock || (Array.isArray(manualStock) && manualStock.length === 0)) {262 manualStock = Bot.getProperty(backupStockKey);263 isBackupUsed = true;264 }265 if (typeof manualStock === "string" && manualStock.trim() !== "") {266 try {267 manualStock = JSON.parse(manualStock);268 } catch (err) {269 manualStock = manualStock.split("\n").map(function (k) { return k.trim(); }).filter(Boolean);270 }271 }272 273 if (Array.isArray(manualStock) && manualStock.length > 0) {274 var generatedKey = manualStock.shift();275 276 if (isBackupUsed) {277 Bot.setProperty(backupStockKey, manualStock, "json");278 var mainStock = Bot.getProperty(manualKeysStorageKey) || [];279 if (typeof mainStock === "string") { mainStock = mainStock.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }280 if (Array.isArray(mainStock)) {281 var idx1 = mainStock.indexOf(generatedKey);282 if (idx1 > -1) { mainStock.splice(idx1, 1); }283 Bot.setProperty(manualKeysStorageKey, mainStock, "json");284 }285 } else {286 Bot.setProperty(manualKeysStorageKey, manualStock, "json");287 var backupStock2 = Bot.getProperty(backupStockKey) || [];288 if (typeof backupStock2 === "string") { backupStock2 = backupStock2.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); }289 if (Array.isArray(backupStock2)) {290 var idx2 = backupStock2.indexOf(generatedKey);291 if (idx2 > -1) { backupStock2.splice(idx2, 1); }292 Bot.setProperty(backupStockKey, backupStock2, "json");293 }294 }295 296 // Permanently remember delivered manual keys so they cannot be added again.297 var soldKeyIndex = Bot.getProperty("manual_sold_key_index") || {};298 if (!soldKeyIndex || typeof soldKeyIndex !== "object") soldKeyIndex = {};299 soldKeyIndex[String(generatedKey)] = {300 product: String(product.name).trim(),301 duration: durationDisplay,302 user_id: String(userId),303 sold_at: new Date().toISOString()304 };305 Bot.setProperty("manual_sold_key_index", soldKeyIndex, "json");306 307 // π° Deduct balance + record purchase (same accounting as API path)308 Libs.ResourcesLib.userRes("balance").add(-price);309 var pastSpent2 = Bot.getProperty("total_spent_by_" + userId) || 0;310 Bot.setProperty("total_spent_by_" + userId, Number(pastSpent2) + price, "number");311 312 313 var keysHistory2 = User.getProperty("my_purchased_keys") || [];314 keysHistory2.push({315 product: String(product.name).trim(),316 product_id: (plan && (plan.pid || plan.product_id || plan.variant_id)) || null,317 days: pDaysNumOnly,318 price: price,319 key: generatedKey,320 date: new Date().toLocaleDateString()321 });322 User.setProperty("my_purchased_keys", keysHistory2, "json");323 324 var remainingBal2 = Libs.ResourcesLib.userRes("balance").value().toFixed(2);325 326 // β
NEW: Key ke saath automatic "Join Updates" button attach hota hai (agar admin ne link set kiya ho)327 var updateLinkForKey = Bot.getProperty("update_channel_link");328 var keyDeliveryButtons = [[{ text: "π Copy Key", copy_text: { text: generatedKey } }]];329 if (updateLinkForKey) {330 keyDeliveryButtons.push([{ text: "π₯ Join Updates", url: updateLinkForKey, style: "primary", icon_custom_emoji_id: "6091571559233755994" }]);331 }332 keyDeliveryButtons.push([{ text: "Back to Menu", callback_data: "/back", style: "primary", icon_custom_emoji_id: "5877536313623711363" }]);333 var keyDeliveryMarkup = JSON.stringify({ inline_keyboard: keyDeliveryButtons });334 335 var deliverText2 = "<blockquote>" +336 "<tg-emoji emoji-id='5350447674971660988'>β
</tg-emoji> <b>PURCHASE SUCCESSFUL!</b>\n\n" +337 "<tg-emoji emoji-id='6147767796097884213'>π¦</tg-emoji> <b>Product:</b> <code>" + String(product.name).trim() + "</code>\n" +338 "<tg-emoji emoji-id='6284816251143331422'>π</tg-emoji> <b>Validity:</b> <code>" + durationDisplay + "</code>\n" +339 "<tg-emoji emoji-id='5352825278672412291'>π</tg-emoji> <b>Your Key:</b> <code>" + generatedKey + "</code>\n\n" +340 "βββββ <tg-emoji emoji-id='6147934084346682063'>#β£</tg-emoji> <b>BALANCE DETAILS</b> βββββ\n" +341 "<tg-emoji emoji-id='6195037488898121775'>β¨</tg-emoji> <b>Total Invest:</b> βΉ" + price.toFixed(2) + "\n" +342 "<tg-emoji emoji-id='5409048419211682843'>π΅</tg-emoji> <b>New Wallet Balance:</b> βΉ" + remainingBal2 + "\n\n" +343 "<i>Enjoy your purchase. <tg-emoji emoji-id='6057881002540274780'>π₯³</tg-emoji></i>" +344 "</blockquote>";345 346 if (request && request.message) {347 try {348 Api.editMessageText({349 chat_id: String(chatId),350 message_id: Number(request.message.message_id),351 text: deliverText2,352 parse_mode: "HTML",353 reply_markup: keyDeliveryMarkup354 });355 } catch (e) {356 Api.sendMessage({ chat_id: chatId, text: deliverText2, parse_mode: "HTML", reply_markup: keyDeliveryMarkup });357 }358 } else {359 Api.sendMessage({ chat_id: chatId, text: deliverText2, parse_mode: "HTML", reply_markup: keyDeliveryMarkup });360 }361 362 var adminId3 = "7839151435";363 Api.sendMessage({364 chat_id: adminId3,365 text: "π <b>NEW PURCHASE DELIVERED (MANUAL STOCK)</b> βοΈ\n\n" +366 "π€ <b>Buyer:</b> " + (user.first_name || "User") + " (<code>" + userId + "</code>)\n" +367 "π¦ <b>Product:</b> " + String(product.name).trim() + "\n" +368 "β³ <b>Plan:</b> " + durationDisplay + "\n" +369 "πΈ <b>Price Deducted:</b> βΉ" + price.toFixed(2) + "\n" +370 "π³ <b>User Remaining Bal:</b> βΉ" + remainingBal2 + "\n" +371 "π <b>Key:</b> <code>" + generatedKey + "</code>\n\n" +372 "<i>β
Manual stock se deliver hui β external paid API call SKIP ki gayi.</i>",373 parse_mode: "HTML"374 });375 376 var qId0 = request ? (request.id || (request.callback_query && request.callback_query.id)) : null;377 if (qId0) {378 try { Api.answerCallbackQuery({ callback_query_id: String(qId0), text: "β
Key Delivered!", show_alert: false }); } catch (e) {}379 }380 381 return; // π« STOP β external API bilkul call nahi hui382 }383 384 // β
PID is plan-level: Add Plan stores the API PID on the selected plan.385 // Product itself no longer needs a PID.386 var webProductId = String((plan && (plan.pid || plan.product_id || plan.variant_id)) || "").trim();387 if (!webProductId) {388 Api.sendMessage({ chat_id: chat.chatid, text: "β οΈ Is plan ka PID set nahi hai. Admin ko Add Plan me PID number add karna hoga.", parse_mode: "HTML" });389 User.setProperty("buy_verifying_lock_" + userId, false, "boolean");390 return;391 }392 var prodNameLower = String(product.name).toLowerCase();393 394 var durationParam = resolveApiDuration(plan, cleanPlanDays, planUnit, product && product.name);395 396 // =====================================================397 // π MULTI-API SYSTEM398 // Admin can add/update/select multiple reseller APIs.399 // The active API is used for external purchases.400 // =====================================================401 var apiRegistry = Bot.getProperty("api_registry") || {};402 var activeApiId = Bot.getProperty("active_reseller_api");403 var selectedApi = activeApiId ? apiRegistry[activeApiId] : null;404 405 if (!selectedApi) {406 Api.sendMessage({chat_id: chatId, text: "β No reseller API configured. Admin ko /apiadd se apna online API add karke /apiset se active karna hoga."});407 return;408 }409 410 if (selectedApi.enabled === false) {411 Api.sendMessage({chat_id: chatId, text: "β Selected API is disabled. Admin ko /apiset se another API select karna hoga."});412 return;413 }414 415 // β
PID is plan-level: Add Plan stores the API PID on the selected plan.416 // Product itself no longer needs a PID.417 var webProductId = String((plan && (plan.pid || plan.product_id || plan.variant_id)) || "").trim();418 if (!webProductId) {419 Api.sendMessage({ chat_id: chat.chatid, text: "β οΈ Is plan ka PID set nahi hai. Admin ko Add Plan me PID number add karna hoga.", parse_mode: "HTML" });420 User.setProperty("buy_verifying_lock_" + userId, false, "boolean");421 return;422 }423 var prodNameLower = String(product.name).toLowerCase();424 425 var durationParam = resolveApiDuration(plan, cleanPlanDays, planUnit, product && product.name);426 427 // Product-level API override is supported: product.api_id.428 var productApiId = product.api_id ? String(product.api_id).trim() : "";429 if (productApiId && apiRegistry[productApiId] && apiRegistry[productApiId].enabled !== false) {430 selectedApi = apiRegistry[productApiId];431 activeApiId = productApiId;432 }433 434 var variantId = String((plan && (plan.pid || plan.product_id || plan.variant_id || plan.variantId)) || "").trim();435 if (!variantId) {436 Api.sendMessage({ chat_id: chat.chatid, text: "β οΈ Is plan ka PID set nahi hai. Admin ko Add Plan me PID number add karna hoga.", parse_mode: "HTML" });437 return;438 }439 var postFields = {440 api_key: selectedApi.api_key || "",441 action: "buy",442 // keyspanelshop reseller_api.php accepts variant_id for key generation.443 variant_id: variantId,444 quantity: 1,445 // Keep these fields for backward compatibility with older API configs.446 product_id: webProductId,447 duration: durationParam448 };449 if (selectedApi.policy) postFields.policy = String(selectedApi.policy);450 if (selectedApi.side) postFields.side = String(selectedApi.side);451 if (selectedApi.user_number) postFields.user_number = String(selectedApi.user_number);452 453 // Device-bound APIs can require android_id. The value may be saved by454 // your existing product/user flow as android_id_<USER_ID>.455 var savedAndroidId = User.getProperty("android_id") || User.getProperty("android_id_" + userId) ||456 Bot.getProperty("android_id_" + userId) || "";457 if (selectedApi.android_required) {458 if (!savedAndroidId) {459 Api.sendMessage({460 chat_id: chatId,461 text: "β οΈ <b>Android ID required</b>\nIs API/product ke liye Android ID zaroori hai. Pehle user ka Android ID save karein.",462 parse_mode: "HTML"463 });464 return;465 }466 postFields.android_id = String(savedAndroidId);467 } else if (savedAndroidId) {468 // Optional APIs may also accept it.469 postFields.android_id = String(savedAndroidId);470 }471 472 var apiHeaders = {473 "Content-Type": "application/x-www-form-urlencoded"474 };475 if (selectedApi.master_key) apiHeaders["x-master-key"] = selectedApi.master_key;476 if (selectedApi.policy) apiHeaders["x-policy"] = String(selectedApi.policy);477 if (selectedApi.side) apiHeaders["x-side"] = String(selectedApi.side);478 if (selectedApi.user_number) apiHeaders["x-user-number"] = String(selectedApi.user_number);479 480 var postFieldsString = Object.keys(postFields).map(function(k) {481 return encodeURIComponent(k) + "=" + encodeURIComponent(postFields[k]);482 }).join("&");483 484 User.setProperty("last_pending_price", Number(price), "number");485 User.setProperty("last_pending_prod_id", webProductId, "string");486 User.setProperty("last_pending_prod_name", String(product.name).trim(), "string");487 User.setProperty("last_pending_plan_days", cleanPlanDays, "string");488 User.setProperty("last_pending_plan_unit", planUnit, "string");489 User.setProperty("last_pending_api_id", String(selectedApi.id || activeApiId || ""), "string");490 491 var queryId = request ? (request.id || (request.callback_query && request.callback_query.id)) : null;492 493 var processingText = "<tg-emoji emoji-id='6147936236125298267'>β³</tg-emoji> <b>Processing your order... please wait!</b>";494 if (request && request.message) {495 try {496 Api.editMessageText({497 chat_id: String(chatId),498 message_id: Number(request.message.message_id),499 text: processingText,500 parse_mode: "HTML"501 });502 Bot.setProperty("gen_msg_id_" + userId, request.message.message_id, "string");503 User.setProperty("gen_msg_id_" + userId, request.message.message_id, "string");504 } catch (e) {505 var pm1 = Api.sendMessage({ chat_id: chatId, text: processingText, parse_mode: "HTML" });506 try {507 var pmid1 = (pm1 && pm1.result && pm1.result.message_id) ? pm1.result.message_id : (pm1 && pm1.message_id ? pm1.message_id : null);508 if (pmid1) { Bot.setProperty("gen_msg_id_" + userId, pmid1, "string"); User.setProperty("gen_msg_id_" + userId, pmid1, "string"); }509 } catch (e2) {}510 }511 } else {512 var pm2 = Api.sendMessage({ chat_id: chatId, text: processingText, parse_mode: "HTML" });513 try {514 var pmid2 = (pm2 && pm2.result && pm2.result.message_id) ? pm2.result.message_id : (pm2 && pm2.message_id ? pm2.message_id : null);515 if (pmid2) { Bot.setProperty("gen_msg_id_" + userId, pmid2, "string"); User.setProperty("gen_msg_id_" + userId, pmid2, "string"); }516 } catch (e2) {}517 }518 519 HTTP.post({520 url: selectedApi.url,521 body: postFieldsString,522 headers: apiHeaders,523 success: "/onWebKeyReceive",524 error: "/onWebKeyError"525 });526 527 if (queryId) {528 try {529 Api.answerCallbackQuery({530 callback_query_id: String(queryId),531 text: "β³ Processing your order... Please wait!",532 show_alert: false533 });534 } catch (e) {}535 }536 537} catch (e) {538 var errChatId = (typeof chat !== "undefined" && chat && chat.chatid) ? chat.chatid : null;539 if (errChatId) {540 try { Api.sendMessage({ chat_id: errChatId, text: "β <b>Error:</b> <code>" + e.message + "</code>", parse_mode: "HTML" }); } catch (fatal) {}541 }542}