[],
"keys" => [
"1" => [],
"3" => [],
"7" => [],
"15" => [],
"30" => []
],
"free_keys" => [],
"free_claims" => [],
"prices" => [
"1" => 20,
"3" => 50,
"7" => 100,
"15" => 180,
"30" => 300
],
"deposits" => [],
"apk" => [],
"referrals" => []
];
}
function db() {
if (!file_exists(DB_FILE)) {
file_put_contents(
DB_FILE,
json_encode(defaultDB(), JSON_PRETTY_PRINT),
LOCK_EX
);
}
$data = json_decode(file_get_contents(DB_FILE), true);
if (!is_array($data)) {
$data = defaultDB();
}
return array_replace_recursive(defaultDB(), $data);
}
function saveDB($data) {
file_put_contents(
DB_FILE,
json_encode($data, JSON_PRETTY_PRINT),
LOCK_EX
);
}
/* ================= TELEGRAM API ================= */
function api($method, $data = []) {
$url = "https://api.telegram.org/bot" . BOT_TOKEN . "/" . $method;
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30
]);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
function sendMsg($chat, $text, $keyboard = null) {
$data = [
"chat_id" => $chat,
"text" => $text,
"parse_mode" => "HTML"
];
if ($keyboard) {
$data["reply_markup"] = json_encode($keyboard);
}
return api("sendMessage", $data);
}
function answerCallback($id, $text = "") {
api("answerCallbackQuery", [
"callback_query_id" => $id,
"text" => $text
]);
}
/* ================= HELPERS ================= */
function isAdmin($id) {
return (string)$id === (string)ADMIN_ID;
}
function blue($text) {
return [
"text" => $text,
"style" => "primary"
];
}
function green($text) {
return [
"text" => $text,
"style" => "success"
];
}
/* ================= KEYBOARDS ================= */
function mainMenu($admin = false) {
$keyboard = [
[blue("š Buy Key"), green("š Free Key")],
[blue("š° Balance"), green("ā Add Fund")],
[blue("š¦ Stock"), green("š¤ Profile")],
[blue("š Get File"), green("š„ Referral")],
[blue("ā¹ļø Help")]
];
if ($admin) {
$keyboard[] = [green("āļø Admin Panel")];
}
return [
"keyboard" => $keyboard,
"resize_keyboard" => true,
"is_persistent" => true
];
}
function adminMenu() {
return [
"keyboard" => [
[green("ā Add Paid Key"), blue("š Add Free Key")],
[green("š² Set Price"), blue("š¤ Upload APK")],
[green("š³ Pending Deposits"), blue("š Statistics")],
[blue("š Main Menu")]
],
"resize_keyboard" => true,
"is_persistent" => true
];
}
function planMenu($data) {
$buttons = [];
foreach ($data["prices"] as $days => $price) {
$buttons[] = blue($days . " Days - ą§³" . $price);
}
$buttons = array_chunk($buttons, 2);
$buttons[] = [
green("š Back"),
blue("š Main Menu")
];
return [
"keyboard" => $buttons,
"resize_keyboard" => true,
"is_persistent" => true
];
}
function joinMenu() {
return [
"inline_keyboard" => [
[
[
"text" => "šµ Join Channel",
"url" => CHANNEL_LINK
]
],
[
[
"text" => "š¢ Verify",
"callback_data" => "verify"
]
]
]
];
}
/* ================= USER ================= */
function userExists($data, $id) {
return isset($data["users"][(string)$id]);
}
function isJoined($id) {
$res = api("getChatMember", [
"chat_id" => CHANNEL,
"user_id" => $id
]);
if (empty($res["ok"])) {
return false;
}
$status = $res["result"]["status"] ?? "";
return in_array($status, [
"member",
"administrator",
"creator"
]);
}
function createUser(&$data, $id, $ref = "") {
$id = (string)$id;
if (userExists($data, $id)) {
return;
}
$data["users"][$id] = [
"balance" => 0,
"state" => "",
"verified" => false,
"ref" => $ref,
"joined" => time(),
"purchases" => 0
];
}
function referralBonus(&$data, $newUser) {
$newUser = (string)$newUser;
if (!isset($data["users"][$newUser])) {
return;
}
$ref = (string)($data["users"][$newUser]["ref"] ?? "");
if ($ref === "" || $ref === $newUser) {
return;
}
if (!isset($data["users"][$ref])) {
return;
}
if (isset($data["referrals"][$newUser])) {
return;
}
$data["users"][$ref]["balance"] += 20;
$data["referrals"][$newUser] = $ref;
sendMsg(
$ref,
"š Referral Bonus!\n\nYou received ą§³20."
);
}
function welcome($chat, $id) {
sendMsg(
$chat,
"ā
Verification Successful!\n\nWelcome to Key Selling Bot.\nChoose an option:",
mainMenu(isAdmin($id))
);
}
/* ================= UPDATE ================= */
$update = json_decode(file_get_contents("php://input"), true);
if (!$update) {
exit;
}
$data = db();
$message = $update["message"] ?? null;
$callback = $update["callback_query"] ?? null;
/* ================= CALLBACK HANDLER ================= */
if ($callback) {
$callbackData = $callback["data"] ?? "";
$id = (string)$callback["from"]["id"];
$chat = $callback["message"]["chat"]["id"];
$messageId = $callback["message"]["message_id"];
/* Membership verification */
if ($callbackData === "verify") {
if (!isJoined($id)) {
answerCallback(
$callback["id"],
"Please join the channel first!"
);
exit;
}
if (!userExists($data, $id)) {
createUser($data, $id);
}
if (empty($data["users"][$id]["verified"])) {
referralBonus($data, $id);
$data["users"][$id]["verified"] = true;
saveDB($data);
}
answerCallback($callback["id"], "Verified!");
welcome($chat, $id);
exit;
}
/* Deposit approval */
if (
strpos($callbackData, "approve_") === 0 ||
strpos($callbackData, "reject_") === 0
) {
if (!isAdmin($id)) {
answerCallback($callback["id"], "Not allowed!");
exit;
}
$parts = explode("_", $callbackData, 2);
$action = $parts[0];
$depositId = $parts[1];
if (!isset($data["deposits"][$depositId])) {
answerCallback($callback["id"], "Deposit not found!");
exit;
}
$deposit = $data["deposits"][$depositId];
if ($deposit["status"] !== "pending") {
answerCallback($callback["id"], "Already processed!");
exit;
}
$userId = (string)$deposit["user"];
$amount = (float)$deposit["amount"];
if ($action === "approve") {
$data["users"][$userId]["balance"] += $amount;
$data["deposits"][$depositId]["status"] = "approved";
sendMsg(
$userId,
"ā
Deposit Approved!\n\ną§³$amount added to your balance."
);
answerCallback($callback["id"], "Approved!");
$statusText = "ā
DEPOSIT APPROVED";
} else {
$data["deposits"][$depositId]["status"] = "rejected";
sendMsg(
$userId,
"ā Deposit Rejected!\n\nPlease contact support."
);
answerCallback($callback["id"], "Rejected!");
$statusText = "ā DEPOSIT REJECTED";
}
saveDB($data);
api("editMessageCaption", [
"chat_id" => $chat,
"message_id" => $messageId,
"caption" => $statusText .
"\n\nUser: $userId" .
"\nAmount: ą§³$amount",
"parse_mode" => "HTML"
]);
exit;
}
}
/* ================= MESSAGE HANDLER ================= */
if (!$message) {
exit;
}
$chat = $message["chat"]["id"];
$id = (string)$message["from"]["id"];
$text = trim($message["text"] ?? "");
$photo = $message["photo"] ?? [];
$document = $message["document"] ?? null;
/* ================= START ================= */
if (strpos($text, "/start") === 0) {
$parts = explode(" ", $text, 2);
$ref = $parts[1] ?? "";
createUser($data, $id, $ref);
if (isAdmin($id)) {
$data["users"][$id]["verified"] = true;
saveDB($data);
welcome($chat, $id);
exit;
}
if (!isJoined($id)) {
saveDB($data);
sendMsg(
$chat,
"š Channel Join Required\n\nPlease join our official channel and press Verify.",
joinMenu()
);
exit;
}
if (empty($data["users"][$id]["verified"])) {
referralBonus($data, $id);
$data["users"][$id]["verified"] = true;
saveDB($data);
}
saveDB($data);
welcome($chat, $id);
exit;
}
/* ================= FORCE JOIN ================= */
if (!isAdmin($id)) {
if (
!userExists($data, $id) ||
empty($data["users"][$id]["verified"]) ||
!isJoined($id)
) {
sendMsg(
$chat,
"š Join our channel and verify first.",
joinMenu()
);
exit;
}
}
if (!userExists($data, $id)) {
createUser($data, $id);
}
/* ================= NAVIGATION FIRST ================= */
if ($text === "š Main Menu") {
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg($chat, "š Main Menu", mainMenu(isAdmin($id)));
exit;
}
if ($text === "š Back") {
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg($chat, "š Select a plan:", planMenu($data));
exit;
}
if ($text === "āļø Admin Panel" && isAdmin($id)) {
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg($chat, "āļø Admin Control Panel", adminMenu());
exit;
}
/* ================= ADMIN MENU BUTTONS ================= */
if (isAdmin($id)) {
if ($text === "ā Add Paid Key") {
$data["users"][$id]["state"] = "add_paid_key";
saveDB($data);
sendMsg(
$chat,
"ā Add Paid Key\n\nSend in this format:\n7 YOUR-KEY"
);
exit;
}
if ($text === "š Add Free Key") {
$data["users"][$id]["state"] = "add_free_key";
saveDB($data);
sendMsg($chat, "Send your free key:");
exit;
}
if ($text === "š² Set Price") {
$data["users"][$id]["state"] = "set_price";
saveDB($data);
sendMsg(
$chat,
"Send plan and price:\n7 120"
);
exit;
}
if ($text === "š¤ Upload APK") {
$data["users"][$id]["state"] = "upload_apk";
saveDB($data);
sendMsg($chat, "Send APK as a document:");
exit;
}
if ($text === "š Statistics") {
$pending = 0;
foreach ($data["deposits"] as $deposit) {
if ($deposit["status"] === "pending") {
$pending++;
}
}
$paidStock = 0;
foreach ($data["keys"] as $keys) {
$paidStock += count($keys);
}
sendMsg(
$chat,
"š Statistics\n\n" .
"Users: " . count($data["users"]) . "\n" .
"Pending Deposits: $pending\n" .
"Paid Keys: $paidStock\n" .
"Free Keys: " . count($data["free_keys"])
);
exit;
}
if ($text === "š³ Pending Deposits") {
$found = false;
foreach ($data["deposits"] as $depositId => $deposit) {
if ($deposit["status"] !== "pending") {
continue;
}
$found = true;
$keyboard = [
"inline_keyboard" => [[
[
"text" => "š¢ Approve",
"callback_data" => "approve_" . $depositId,
"style" => "success"
],
[
"text" => "šµ Reject",
"callback_data" => "reject_" . $depositId,
"style" => "primary"
]
]]
];
api("sendPhoto", [
"chat_id" => $chat,
"photo" => $deposit["file_id"],
"caption" =>
"š° Deposit Request\n\n" .
"User: " . $deposit["user"] . "\n" .
"Amount: ą§³" . $deposit["amount"] . "\n" .
"ID: $depositId",
"parse_mode" => "HTML",
"reply_markup" => json_encode($keyboard)
]);
}
if (!$found) {
sendMsg($chat, "No pending deposits.");
}
exit;
}
}
/* ================= INPUT STATES ================= */
$state = $data["users"][$id]["state"] ?? "";
/* Add paid key */
if (isAdmin($id) && $state === "add_paid_key") {
$parts = explode(" ", $text, 2);
if (
count($parts) !== 2 ||
!isset($data["keys"][$parts[0]]) ||
trim($parts[1]) === ""
) {
sendMsg($chat, "Invalid format.\nExample: 7 YOUR-KEY");
exit;
}
$days = $parts[0];
$key = trim($parts[1]);
$data["keys"][$days][] = $key;
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg($chat, "ā
Paid key added successfully.", adminMenu());
exit;
}
/* Add free key */
if (isAdmin($id) && $state === "add_free_key") {
if ($text === "") {
sendMsg($chat, "Please send a valid key.");
exit;
}
$data["free_keys"][] = $text;
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg($chat, "ā
Free key added.", adminMenu());
exit;
}
/* Set price */
if (isAdmin($id) && $state === "set_price") {
$parts = preg_split('/\s+/', $text);
if (
count($parts) !== 2 ||
!isset($data["prices"][$parts[0]]) ||
!is_numeric($parts[1]) ||
$parts[1] < 0
) {
sendMsg($chat, "Invalid format.\nExample: 7 120");
exit;
}
$data["prices"][$parts[0]] = (float)$parts[1];
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg($chat, "ā
Price updated.", adminMenu());
exit;
}
/* Upload APK */
if (isAdmin($id) && $state === "upload_apk") {
if (!$document) {
sendMsg($chat, "Please send APK as a document.");
exit;
}
$data["apk"][] = [
"file_id" => $document["file_id"],
"name" => $document["file_name"] ?? "Application"
];
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg($chat, "ā
APK uploaded.", adminMenu());
exit;
}
/* Deposit amount */
if ($state === "deposit_amount") {
if (!is_numeric($text) || $text < 10) {
sendMsg($chat, "Enter a valid amount. Minimum ą§³10.");
exit;
}
$data["users"][$id]["deposit_amount"] = (float)$text;
$data["users"][$id]["state"] = "deposit_proof";
saveDB($data);
sendMsg(
$chat,
"š³ Payment Details\n\n" .
"bKash: " . BKASH . "\n" .
"Amount: ą§³$text\n\n" .
"Send your payment screenshot now."
);
exit;
}
/* Deposit proof */
if ($state === "deposit_proof") {
if (empty($photo) && !$document) {
sendMsg($chat, "Please send a payment screenshot.");
exit;
}
$fileId = $document
? $document["file_id"]
: end($photo)["file_id"];
$depositId = uniqid("DEP");
$amount = $data["users"][$id]["deposit_amount"];
$data["deposits"][$depositId] = [
"user" => $id,
"amount" => $amount,
"file_id" => $fileId,
"status" => "pending",
"time" => time()
];
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg(
$chat,
"ā
Deposit proof submitted!\n\nPlease wait for admin approval.",
mainMenu(false)
);
$keyboard = [
"inline_keyboard" => [[
[
"text" => "š¢ Approve",
"callback_data" => "approve_" . $depositId,
"style" => "success"
],
[
"text" => "šµ Reject",
"callback_data" => "reject_" . $depositId,
"style" => "primary"
]
]]
];
api("sendPhoto", [
"chat_id" => ADMIN_ID,
"photo" => $fileId,
"caption" =>
"š° New Deposit Request\n\n" .
"User: $id\n" .
"Amount: ą§³$amount\n" .
"ID: $depositId",
"parse_mode" => "HTML",
"reply_markup" => json_encode($keyboard)
]);
exit;
}
/* ================= BUY KEY ================= */
if ($text === "š Buy Key") {
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg(
$chat,
"š Select Your Plan",
planMenu($data)
);
exit;
}
foreach ($data["prices"] as $days => $price) {
if ($text === "$days Days - ą§³$price") {
$stock = $data["keys"][$days] ?? [];
if (empty($stock)) {
sendMsg(
$chat,
"ā No stock available for this plan.",
planMenu($data)
);
exit;
}
$balance = $data["users"][$id]["balance"];
if ($balance < $price) {
sendMsg(
$chat,
"ā Insufficient Balance!\n\n" .
"Price: ą§³$price\n" .
"Balance: ą§³$balance",
planMenu($data)
);
exit;
}
$key = array_shift($data["keys"][$days]);
$data["users"][$id]["balance"] -= $price;
$data["users"][$id]["purchases"]++;
$data["users"][$id]["state"] = "";
saveDB($data);
sendMsg(
$chat,
"š Purchase Successful!\n\n" .
"Plan: $days Days\n" .
"Key:\n$key\n\n" .
"Thank you!",
mainMenu(isAdmin($id))
);
exit;
}
}
/* ================= FREE KEY ================= */
if ($text === "š Free Key") {
// One free key per user
if (isset($data["free_claims"][$id])) {
sendMsg(
$chat,
"ā Already Claimed!\n\nYou have already received your Free Key. Only one Free Key is allowed per account.",
mainMenu(isAdmin($id))
);
exit;
}
if (empty($data["free_keys"])) {
sendMsg(
$chat,
"ā No Free Keys Available.",
mainMenu(isAdmin($id))
);
exit;
}
$key = array_shift($data["free_keys"]);
$data["free_claims"][$id] = [
"key" => $key,
"time" => time()
];
saveDB($data);
sendMsg(
$chat,
"š Free Key Claimed!\n\n$key\n\nYou can claim only one Free Key per account.",
mainMenu(isAdmin($id))
);
exit;
}
/* ================= BALANCE ================= */
if ($text === "š° Balance") {
$balance = $data["users"][$id]["balance"];
sendMsg(
$chat,
"š° Your Balance\n\ną§³$balance",
mainMenu(isAdmin($id))
);
exit;
}
/* ================= ADD FUND ================= */
if ($text === "ā Add Fund") {
$data["users"][$id]["state"] = "deposit_amount";
saveDB($data);
sendMsg(
$chat,
"š³ Add Fund\n\nEnter the amount.\nMinimum: ą§³10"
);
exit;
}
/* ================= PROFILE ================= */
if ($text === "š¤ Profile") {
$user = $data["users"][$id];
sendMsg(
$chat,
"š¤ Your Profile\n\n" .
"ID: $id\n" .
"Balance: ą§³" . $user["balance"] . "\n" .
"Purchases: " . $user["purchases"] . "\n" .
"Joined: " . date("d M Y", $user["joined"]),
mainMenu(isAdmin($id))
);
exit;
}
/* ================= REFERRAL ================= */
if ($text === "š„ Referral") {
$link = "https://t.me/" . BOT_USERNAME . "?start=" . $id;
$count = 0;
foreach ($data["referrals"] as $newUser => $referrer) {
if ((string)$referrer === $id) {
$count++;
}
}
sendMsg(
$chat,
"š„ Your Referral\n\n" .
"Your link:\n$link\n\n" .
"Successful referrals: $count\n" .
"Bonus per referral: ą§³20",
mainMenu(isAdmin($id))
);
exit;
}
/* ================= STOCK ================= */
if ($text === "š¦ Stock") {
$msg = "š¦ Available Stock\n\n";
foreach ($data["prices"] as $days => $price) {
$count = count($data["keys"][$days] ?? []);
$msg .= "$days Days: $count keys\n";
}
$msg .= "\nFree Keys: " . count($data["free_keys"]);
sendMsg($chat, $msg, mainMenu(isAdmin($id)));
exit;
}
/* ================= GET FILE ================= */
if ($text === "š Get File") {
if (empty($data["apk"])) {
sendMsg($chat, "No files available.");
exit;
}
foreach ($data["apk"] as $file) {
api("sendDocument", [
"chat_id" => $chat,
"document" => $file["file_id"],
"caption" => $file["name"]
]);
}
exit;
}
/* ================= HELP ================= */
if ($text === "ā¹ļø Help") {
sendMsg(
$chat,
"ā¹ļø Help Center\n\n" .
"š Buy Key - Purchase keys\n" .
"š Free Key - Get free keys\n" .
"š° Balance - Check balance\n" .
"ā Add Fund - Deposit money\n" .
"š„ Referral - Invite friends\n" .
"š Get File - Download files\n\n" .
"Contact admin for support.",
mainMenu(isAdmin($id))
);
exit;
}
/* ================= DEFAULT ================= */
sendMsg(
$chat,
"Please select a button from the menu.",
mainMenu(isAdmin($id))
);
?>