tarunpoonia905/OfcDevShopBotPublic · Bot Template
AIDEV SHOP appears to be a Telegram automation bot. Commands include /confirm_delete_stock, /addstock_id, /extkey_menu, /partner_api, /apidelete, /buy_hack_cat, /admin_manage_products, /check_buy. Observed in code: messaging, keyboards, payments, libs, web, http, games.
Utilityutility
228 commands0 envUpdated 12d agoCreated Oct 18, 2026
commands/_partner_api.js
javascript · 237 lines
1/**#command2name: /partner_api3answer: 4keyboard: 5parse_mode: markdown6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12// =========================================================13// 🤝 /partner_api — dusre BOT/website ko apne products ki keys bechne ka API.14// Signed TeleBotHost webhook URL (Webhook.getUrl) par POST/GET. Params (form / JSON / query):15// api_key=PK... action=balance | products | buy16// buy: variant_id=<PLAN CODE jaise 155-4H (har plan ka alag) ya purana PID> [duration=<jaise 2 Hours: jab ek PID par kai plans hon>] [quantity=1..10] [order_ref=<unique id: retry par double-charge nahi hota>]17// Reply hamesha HTTP 200 + JSON: {success:true,status:"success",key:"...",keys:[...],order_id,balance}18// {success:false,status:"error",code:"...",message:"..."}19// Paisa partner ke wallet (is bot ka unka Telegram user) se katta hai — reseller price par.20// Delivery sirf is bot ke MANUAL STOCK se hoti hai (sync response ke liye).21// =========================================================22function _reply(obj) { try { if (typeof res !== "undefined" && res) { res.status(200).json(obj); } } catch (e) {} }23function _err(code, msg, extra) { var o = { success: false, status: "error", code: code, message: msg }; if (extra) for (var k in extra) o[k] = extra[k]; _reply(o); }24function _parseAny(v) {25 if (!v) return {};26 if (typeof v === "object") return v;27 var s = String(v);28 try { var j = JSON.parse(s); if (j && typeof j === "object") return j; } catch (e) {}29 var o = {};30 s.split("&").forEach(function (kv) {31 var i = kv.indexOf("="); if (i < 1) return;32 try { o[decodeURIComponent(kv.slice(0, i))] = decodeURIComponent(kv.slice(i + 1).replace(/\+/g, " ")); } catch (e) {}33 });34 return o;35}36try {37 var P = {}, q = _parseAny(typeof request !== "undefined" && request ? request.query : null), b = _parseAny(typeof request !== "undefined" && request ? request.body : null);38 var kk; for (kk in q) P[kk] = q[kk]; for (kk in b) P[kk] = b[kk];39 var hdrs = (typeof request !== "undefined" && request && request.headers) ? request.headers : {};40 var apiKey = String(P.api_key || P.apikey || hdrs["x-api-key"] || hdrs["X-Api-Key"] || "").trim();41 var action = String(P.action || "").trim().toLowerCase();42 if (!apiKey) { _err("no_key", "api_key missing"); return; }43 44 var pid = Bot.getProperty("partner_key_" + apiKey);45 var reg = Bot.getProperty("partner_registry") || {};46 var partner = pid ? reg[pid] : null;47 if (!partner || partner.api_key !== apiKey) { _err("bad_key", "Invalid api_key"); return; }48 if (partner.enabled === false) { _err("disabled", "Partner API disabled by admin"); return; }49 var uid = String(partner.uid);50 if (typeof user === "undefined" || !user || String(user.telegramid) !== uid) { _err("bad_url", "URL is not issued for this partner. Admin se naya URL lein."); return; }51 52 function balRes() { return Libs.ResourcesLib.userRes("balance"); }53 function unified() {54 var r = 0; try { r = Number(balRes().value()) || 0; } catch (e) {}55 return r + (Number(Bot.getProperty("balance" + uid) || 0));56 }57 function money(n) { return Number(Number(n).toFixed(2)); }58 59 var products = Bot.getProperty("stored_products") || [];60 var isRes = Bot.getProperty("is_reseller_" + uid) === true;61 62 function planPid(pl) { return String((pl && (pl.pid || pl.product_id || pl.variant_id || pl.variantId)) || "").trim(); }63 // Har plan ka apna UNIQUE partner code: SUPPLIER_PID + duration, jaise 155-2H, 155-4H, 155-3D (D=day, H=hour, M=minute)64 function pcode(pl) {65 var pd = planPid(pl); if (!pd) return "";66 var u = pl.unit || "day";67 var d = String(pl.days).replace(/[^0-9.]/g, "").replace(/\./g, "_");68 return pd + "-" + d + (u === "hour" ? "H" : (u === "minute" ? "M" : "D"));69 }70 function planInfo(prod, pl) {71 var unit = pl.unit || "day";72 var days = String(pl.days).replace(/[^0-9.]/g, "").trim();73 var pname = String(prod.name || "").trim().toUpperCase();74 var suffix = (unit === "day") ? days : (days + "_" + unit);75 var nk = Bot.getProperty("price_normal_" + pname + "_" + suffix), rk = Bot.getProperty("price_reseller_" + pname + "_" + suffix);76 var curN = (nk !== undefined && nk !== null) ? nk : pl.normal_price;77 var curR = (rk !== undefined && rk !== null) ? rk : pl.reseller_price;78 var price = isRes ? Number(curR) : Number(curN);79 var mk = Bot.getProperty("member_custom_price_" + uid + "_" + pname.replace(/[^A-Z0-9_-]/g, "_") + "_" + ((unit === "day") ? days : (days + "_hour")));80 if (mk !== undefined && mk !== null && isFinite(Number(mk))) price = Number(mk);81 var unitWord = unit === "hour" ? (Number(days) === 1 ? "Hour" : "Hours") : unit === "minute" ? (Number(days) === 1 ? "Minute" : "Minutes") : (Number(days) === 1 ? "Day" : "Days");82 var slug = pname.replace(/[^A-Z0-9_-]/g, "_");83 return {84 unit: unit, days: days, pname: pname, price: price,85 duration: pl.durationDisplay || (days + " " + unitWord),86 unitKey: "manual_keys_" + slug + "_" + days + "_" + unit,87 legacyKey: "manual_keys_" + pname + "_" + days,88 backupKey: "stock_" + String(prod.name).trim() + "_" + days + "_Day"89 };90 }91 function toArr(v) {92 if (typeof v === "string" && v.trim() !== "") { try { v = JSON.parse(v); } catch (e) { v = v.split("\n").map(function (k) { return k.trim(); }).filter(Boolean); } }93 return Array.isArray(v) ? v : [];94 }95 // returns {arr, key, isBackup} -> pehla non-empty stock bucket (confirm_buyitem jaisa hi order)96 function stockOf(info) {97 var a = toArr(Bot.getProperty(info.unitKey)); if (a.length) return { arr: a, key: info.unitKey, isBackup: false };98 if (info.unit === "day") { a = toArr(Bot.getProperty(info.legacyKey)); if (a.length) return { arr: a, key: info.legacyKey, isBackup: false }; }99 a = toArr(Bot.getProperty(info.backupKey)); if (a.length) return { arr: a, key: info.unitKey, isBackup: true };100 return { arr: [], key: info.unitKey, isBackup: false };101 }102 function underMaint(prod) {103 return Bot.getProperty("panel_maintenance_" + String(prod.id || prod.name || "").toUpperCase().replace(/[^A-Z0-9_-]/g, "_")) === true;104 }105 106 // ---------------- balance ----------------107 if (action === "balance" || action === "wallet") {108 _reply({ success: true, status: "success", balance: money(unified()), currency: "INR", reseller_pricing: isRes });109 return;110 }111 112 // ---------------- products ----------------113 if (action === "products" || action === "list" || action === "plans") {114 var out = [];115 products.forEach(function (prod) {116 if (!prod || !prod.plans || underMaint(prod)) return;117 prod.plans.forEach(function (pl) {118 var v = planPid(pl); if (!v) return;119 var inf = planInfo(prod, pl);120 out.push({ variant_id: pcode(pl), product_id: pcode(pl), pid: v, product: String(prod.name).trim(), duration: inf.duration, price: money(inf.price), stock: stockOf(inf).arr.length });121 });122 });123 _reply({ success: true, status: "success", count: out.length, data: out, products: out });124 return;125 }126 127 // ---------------- buy ----------------128 if (action === "buy" || action === "purchase" || action === "generate") {129 var variant = String(P.variant_id || P.product_id || P.pid || P.code || "").trim();130 if (!variant) { _err("no_variant", "variant_id (product code) missing"); return; }131 var qty = Math.floor(Number(P.quantity || 1)); if (!(qty >= 1)) qty = 1; if (qty > 10) qty = 10;132 var ref = String(P.order_ref || P.ref || "").replace(/[^A-Za-z0-9_\-]/g, "").slice(0, 60);133 var refKey = ref ? ("partner_ref_" + pid + "_" + ref) : "";134 if (refKey) { var prev = Bot.getProperty(refKey); if (prev && typeof prev === "object") { prev.duplicate = true; _reply(prev); return; } }135 136 // Ek hi PID par kai plans ho sakte hain (jaise 155 = 2 Hours, 4 Hours, 6 Hours...) -> duration se plan chuno.137 var wantDur = String(P.duration || P.plan || P.time || "").replace(/\s+/g, " ").trim();138 var durKey = function (t) {139 t = String(t || "").toLowerCase().replace(/\s+/g, " ").trim();140 var m = t.match(/^([0-9]+(?:\.[0-9]+)?)\s*([a-z])/);141 return m ? (parseFloat(m[1]) + "|" + (m[2] === "h" ? "hour" : (m[2] === "m" ? "minute" : "day"))) : "";142 };143 var normTxt = function (t) { return String(t || "").toLowerCase().replace(/[^a-z0-9]/g, ""); };144 var cands = [], byCode = [], vUp = variant.toUpperCase();145 for (var i = 0; i < products.length; i++) {146 var pr = products[i]; if (!pr || !pr.plans) continue;147 for (var j = 0; j < pr.plans.length; j++) {148 if (planPid(pr.plans[j]) === variant) cands.push({ prod: pr, plan: pr.plans[j] });149 if (pcode(pr.plans[j]).toUpperCase() === vUp) byCode.push({ prod: pr, plan: pr.plans[j] });150 }151 }152 if (byCode.length > 1) { _err("ambiguous_code", "Ye code kai plans par hai (duplicate). Admin se check karwao: " + variant); return; }153 if (byCode.length === 1) cands = byCode; // plan code = seedha ek hi plan, duration ki zaroorat nahi154 if (!cands.length) { _err("not_found", "Unknown variant_id: " + variant); return; }155 var pick = null;156 if (cands.length === 1) { pick = cands[0]; }157 else {158 var durList = cands.map(function (c) { return planInfo(c.prod, c.plan).duration; });159 if (!wantDur) { _err("duration_required", "Is variant_id par kai plans hain. duration bhi bhejo (jaise duration=" + durList[0] + ").", { durations: durList }); return; }160 var wk = durKey(wantDur), wn = normTxt(wantDur);161 for (var c1 = 0; c1 < cands.length && !pick; c1++) {162 var ci = planInfo(cands[c1].prod, cands[c1].plan), cp = cands[c1].plan;163 var labels = [ci.duration, cp.api_duration, cp.name_on_website, cp.durationDisplay];164 for (var lb = 0; lb < labels.length; lb++) { if (labels[lb] && normTxt(labels[lb]) === wn) { pick = cands[c1]; break; } }165 }166 for (var c2 = 0; c2 < cands.length && !pick && wk; c2++) {167 var cj = planInfo(cands[c2].prod, cands[c2].plan);168 if ((parseFloat(cj.days) + "|" + cj.unit) === wk) pick = cands[c2];169 }170 if (!pick) { _err("duration_not_found", "Is variant_id par ye duration nahi mili: " + wantDur, { durations: durList }); return; }171 }172 var fProd = pick.prod, fPlan = pick.plan;173 if (underMaint(fProd)) { _err("maintenance", "Product under maintenance"); return; }174 175 var inf = planInfo(fProd, fPlan);176 if (!(inf.price > 0)) { _err("no_price", "Price not set for this plan"); return; }177 var total = money(inf.price * qty);178 var bal = unified();179 if (bal + 0.0001 < total) { _err("insufficient_balance", "Wallet balance low. Need " + total.toFixed(2) + ", have " + bal.toFixed(2), { balance: money(bal), required: total }); return; }180 181 var st = stockOf(inf);182 if (st.arr.length < qty) { _err("out_of_stock", "Stock not available", { stock: st.arr.length }); return; }183 184 // keys nikalo185 var keys = [];186 for (var n = 0; n < qty; n++) keys.push(st.arr.shift());187 if (st.isBackup) {188 Bot.setProperty(inf.backupKey, st.arr, "json");189 var main = toArr(Bot.getProperty(inf.unitKey));190 keys.forEach(function (k) { var ix = main.indexOf(k); if (ix > -1) main.splice(ix, 1); });191 Bot.setProperty(inf.unitKey, main, "json");192 } else {193 Bot.setProperty(st.key, st.arr, "json");194 var bk = toArr(Bot.getProperty(inf.backupKey));195 keys.forEach(function (k) { var ix = bk.indexOf(k); if (ix > -1) bk.splice(ix, 1); });196 Bot.setProperty(inf.backupKey, bk, "json");197 }198 199 // paisa kaato: pehle bonus, phir wallet200 var bonus = Number(Bot.getProperty("balance" + uid) || 0);201 var takeB = Math.min(Math.max(bonus, 0), total);202 if (takeB > 0) Bot.setProperty("balance" + uid, bonus - takeB, "number");203 var takeW = money(total - takeB);204 if (takeW > 0) balRes().add(-takeW);205 206 // records207 var sold = Bot.getProperty("manual_sold_key_index") || {};208 if (!sold || typeof sold !== "object") sold = {};209 keys.forEach(function (k) { sold[String(k)] = { product: String(fProd.name).trim(), duration: inf.duration, user_id: uid, partner: pid, sold_at: new Date().toISOString() }; });210 Bot.setProperty("manual_sold_key_index", sold, "json");211 Bot.setProperty("total_spent_by_" + uid, Number(Bot.getProperty("total_spent_by_" + uid) || 0) + total, "number");212 try {213 var hist = User.getProperty("my_purchased_keys") || [];214 keys.forEach(function (k) { hist.push({ product: String(fProd.name).trim(), product_id: variant, days: inf.days, price: inf.price, key: k, date: new Date().toLocaleDateString(), via: "partner_api" }); });215 User.setProperty("my_purchased_keys", hist, "json");216 } catch (hE) {}217 partner.sales = Number(partner.sales || 0) + qty;218 partner.revenue = money(Number(partner.revenue || 0) + total);219 reg[pid] = partner; Bot.setProperty("partner_registry", reg, "json");220 221 var orderId = "PA" + new Date().getTime() + Math.floor(100 + Math.random() * 900);222 var reply = { success: true, status: "success", order_id: orderId, key: keys[0], keys: keys, product: String(fProd.name).trim(), duration: inf.duration, quantity: qty, price: money(inf.price), total: total, balance: money(unified()) };223 if (refKey) Bot.setProperty(refKey, reply, "json");224 225 try {226 Api.sendMessage({ chat_id: String(Bot.getProperty("owner_id") || "7127818616"), parse_mode: "HTML",227 text: "🤝 <b>PARTNER SALE</b>\n👤 <b>Partner:</b> " + String(partner.name).replace(/</g, "<") + " (<code>" + uid + "</code>)\n📦 <b>Product:</b> " + String(fProd.name).trim() + " — " + inf.duration + "\n🔢 <b>Qty:</b> " + qty + "\n💸 <b>Charged:</b> ₹" + total.toFixed(2) + "\n⚡ <b>Stock left:</b> " + st.arr.length });228 } catch (nE) {}229 _reply(reply);230 return;231 }232 233 _err("bad_action", "action must be balance | products | buy");234} catch (e) {235 try { Api.sendMessage({ chat_id: String(Bot.getProperty("owner_id") || "7127818616"), text: "⚠️ partner_api error: " + e.message }); } catch (e2) {}236 _err("server_error", "Internal error");237}