// ========================= // pbot.php // ========================= require_once __DIR__ . '/pfunctions.php'; if(file_exists(__DIR__ . '/pbot_menu_ext.php')) require_once __DIR__ . '/pbot_menu_ext.php'; ensureDataFiles(); $content = file_get_contents("php://input"); $update = json_decode($content, true); if(!$update) exit; /* ========================= MESSAGE ========================= */ if(isset($update['message'])){ $msg = $update['message']; $chat_id = $msg['chat']['id']; $user_id = $msg['from']['id']; $text = trim($msg['text'] ?? ''); if($text === '/emojitest'){ $data = [ 'chat_id' => $chat_id, 'text' => 'تست ✅', 'entities' => json_encode([ [ 'type' => 'custom_emoji', 'offset' => 4, 'length' => 2, 'custom_emoji_id' => '4958610528588008305' ] ], JSON_UNESCAPED_UNICODE) ]; $url = "https://api.telegram.org/bot" . BOT_TOKEN . "/sendMessage"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($ch); $err = curl_error($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"HTTP: ".$code."\nERR: ".$err."\nRES:\n".$res ]); exit; } if($text === '/emojiinfo'){ $data = [ 'custom_emoji_ids' => json_encode(['4958610528588008305']) ]; $url = "https://api.telegram.org/bot" . BOT_TOKEN . "/getCustomEmojiStickers"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($ch); $err = curl_error($ch); $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"HTTP: ".$code."\nERR: ".$err."\nRES:\n".$res ]); exit; } if(function_exists('handle_menu_ext_message') && handle_menu_ext_message($msg, $chat_id, $user_id, $text)) exit; upsertUser($msg); // --- state handler $st = getState($user_id); if($st){ // ✅ اگر کاربر وسط مرحله پرداخت/رسید بود ولی از منوی اصلی چیزی زد، // state رو پاک کن تا گیر نکنه و منو کار کنه. $menu_actions = [ '/start', '🛒 خرید اشتراک', '📘 آموزش اتصال', '📜 قوانین', '💬 پشتیبانی', '👤 حساب کاربری من', '💰 کیف پول', // ادمین‌ها: '👥 کاربران ربات', '🧩 مدیریت محصولات', '⚙️ تنظیمات فروشگاه', '📣 ارسال همگانی', '📦 ارسال محصول', 'ℹ️ اطلاعات ربات', '📊 آمار فروش', ]; if(in_array($text, $menu_actions, true)){ if(in_array(($st['state'] ?? ''), [ 'WAIT_PURCHASE_NAME', 'WAIT_RECEIPT', 'WAIT_CUST_DISC', 'WAIT_WALLET_TOPUP_AMOUNT', 'WAIT_WALLET_TOPUP_RECEIPT', 'WAIT_WALLET_GIFT', 'WAIT_ADMIN_SEND_PRODUCT', 'WAIT_USER_SEARCH' ], true)){ clearState($user_id); $st = null; // اجازه بده ادامه‌ی کد منوها اجرا بشه } } /* ========================= ✅ ADMIN: set force join channel ========================= */ if(($st['state'] ?? '') === 'WAIT_SET_FORCE_JOIN_CHANNEL'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $ch = normalize_channel_username($text); if($ch === ''){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ کانال نامعتبره. دوباره بفرست یا /cancel" ]); exit; } set_force_join_channel($ch); clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✅ کانال عضویت اجباری تنظیم شد: {$ch}" ]); showNewUserSettingsInline($chat_id, $user_id); exit; } if(($st['state'] ?? '') === 'WAIT_REF_LINKS_UPLOAD'){ $lines = explode("\n", $text); $clean_links = array_filter(array_map('trim', $lines)); $current = readJson(REF_LINKS_FILE, []); $new_list = array_merge($current, $clean_links); writeJson(REF_LINKS_FILE, $new_list); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id, 'text'=>"✅ تعداد ".count($clean_links)." لینک جدید به بانک هدیه اضافه شد."]); exit; } /* ========================= ✅ ADMIN: Referral Settings Update ========================= */ // تغییر تعداد دعوت لازم if(($st['state'] ?? '') === 'WAIT_REF_SET_TARGET'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $val = (int)preg_replace('/\D+/', '', $text); if($val < 1){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"❌ عدد وارد شده باید حداقل ۱ باشد."]); exit; } $ref_st = get_ref_settings(); $ref_st['target_invites'] = $val; save_ref_settings($ref_st); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ تعداد دعوت لازم به {$val} نفر تغییر یافت.", 'parse_mode'=>'HTML']); exit; } // تغییر محدودیت زمانی (Cooldown) if(($st['state'] ?? '') === 'WAIT_REF_SET_COOLDOWN'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $val = (int)preg_replace('/\D+/', '', $text); $ref_st = get_ref_settings(); $ref_st['cooldown_minutes'] = $val; save_ref_settings($ref_st); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ محدودیت زمانی به {$val} دقیقه تغییر یافت.", 'parse_mode'=>'HTML']); exit; } /* ========================= ✅ ADMIN: Referral Settings States ========================= */ // تنظیم مبالغ هدیه نقدی if(($st['state'] ?? '') === 'WAIT_REF_SET_MONEY'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $val = (int)preg_replace('/\D+/', '', $text); $ref_st = get_ref_settings(); // در این مثال هر دو مبلغ (دعوت‌کننده و دعوت‌شونده) را یکسان ست می‌کنیم // اگر می‌خواهید جدا باشد، باید دو مرحله‌ای ساخته شود $ref_st['reward_inviter'] = $val; $ref_st['reward_invitee'] = 0; // فعلاً هدیه دعوت‌شونده را صفر می‌گذاریم save_ref_settings($ref_st); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ مبلغ هدیه دعوت‌کننده به ".number_format($val)." تومان تغییر یافت.", 'parse_mode'=>'HTML']); exit; } // تنظیم تعداد دعوت لازم if(($st['state'] ?? '') === 'WAIT_REF_SET_TARGET'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $val = (int)preg_replace('/\D+/', '', $text); if($val < 1) $val = 1; $ref_st = get_ref_settings(); $ref_st['target_invites'] = $val; save_ref_settings($ref_st); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ تعداد دعوت لازم به {$val} نفر تغییر یافت.", 'parse_mode'=>'HTML']); exit; } // تنظیم محدودیت زمانی (دقیقه) if(($st['state'] ?? '') === 'WAIT_REF_SET_COOLDOWN'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $val = (int)preg_replace('/\D+/', '', $text); $ref_st = get_ref_settings(); $ref_st['cooldown_minutes'] = $val; save_ref_settings($ref_st); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ محدودیت زمانی به {$val} دقیقه تغییر یافت.", 'parse_mode'=>'HTML']); exit; } // دریافت و ذخیره لینک‌های هدیه (کانفیگ‌ها) if(($st['state'] ?? '') === 'WAIT_REF_LINKS_UPLOAD'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $lines = explode("\n", $text); $clean_links = array_filter(array_map('trim', $lines)); if(empty($clean_links)){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"❌ لینکی پیدا نشد. دوباره بفرست یا /cancel"]); exit; } $current = readJson(REF_LINKS_FILE, []); $new_list = array_merge($current, $clean_links); writeJson(REF_LINKS_FILE, $new_list); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id, 'text'=>"✅ تعداد ".count($clean_links)." لینک جدید به بانک هدیه اضافه شد.\nتعداد کل لینک‌های موجود: ".count($new_list), 'parse_mode'=>'HTML']); exit; } /* ========================= ✅ ADMIN: Wallet Management States ========================= */ // مرحله مشاهده موجودی if(($st['state'] ?? '') === 'WAIT_ADMIN_WAL_VIEW_ID'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $target = trim($text); $bal = get_wallet_balance($target); clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"💰 موجودی کاربر {$target} برابر است با:\n\n".number_format($bal)." ".DEFAULT_CURRENCY, 'parse_mode'=>'HTML' ]); exit; } // مرحله ۱ تغییر موجودی (دریافت آیدی) if(($st['state'] ?? '') === 'WAIT_ADMIN_WAL_EDIT_ID'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $target = trim($text); $bal = get_wallet_balance($target); setState($user_id, 'WAIT_ADMIN_WAL_EDIT_AMOUNT', ['target_uid' => $target]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"👤 کاربر: {$target}\n💰 موجودی فعلی: ".number_format($bal)." ".DEFAULT_CURRENCY."\n\n". "مقدار تغییر را ارسال کنید:\n". "مثال: +50000 برای افزایش\n". "مثال: -20000 برای کاهش\n". "مثال: 100000 برای تنظیم دقیق روی این عدد\n\n". "/cancel برای لغو", 'parse_mode'=>'HTML' ]); exit; } // مرحله ۲ تغییر موجودی (دریافت مبلغ و اعمال) if(($st['state'] ?? '') === 'WAIT_ADMIN_WAL_EDIT_AMOUNT'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $target = $st['data']['target_uid']; $currentBal = get_wallet_balance($target); $input = trim($text); if(str_starts_with($input, '+')){ $change = (int)preg_replace('/\D+/', '', $input); $newBal = $currentBal + $change; $actionTxt = "افزایش یافت ➕"; } elseif(str_starts_with($input, '-')){ $change = (int)preg_replace('/\D+/', '', $input); $newBal = $currentBal - $change; $actionTxt = "کاهش یافت ➖"; } else { $newBal = (int)preg_replace('/\D+/', '', $input); $actionTxt = "تنظیم شد 📍"; } if($newBal < 0) $newBal = 0; set_wallet_balance($target, $newBal); clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✅ موجودی کاربر {$target} با موفقیت {$actionTxt}\n\n💰 موجودی جدید: ".number_format($newBal)." ".DEFAULT_CURRENCY, 'parse_mode'=>'HTML' ]); // اطلاع‌رسانی به کاربر apiRequest('sendMessage',[ 'chat_id'=>$target, 'text'=>"🔔 موجودی کیف پول شما توسط مدیریت تغییر کرد.\n💰 موجودی جدید: ".number_format($newBal)." ".DEFAULT_CURRENCY, ]); // ثبت در لاگ حسابداری if(function_exists('log_send')){ log_send('accounting', "✍️ تغییر دستی موجودی\n👤 کاربر: {$target}\n📝 نوع: {$actionTxt}\n💰 مبلغ جدید: ".number_format($newBal)." ".DEFAULT_CURRENCY."\n🆔 ادمین: {$user_id}", 'HTML'); } exit; } /* ========================= ✅ ADMIN: set join gift amount ========================= */ if(($st['state'] ?? '') === 'WAIT_SET_JOIN_GIFT_AMOUNT'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $amt = (int)preg_replace('/\D+/', '', $text); if($amt < 0) $amt = 0; set_join_gift_amount($amt); clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✅ مبلغ هدیه عضویت تنظیم شد: ".number_format($amt)." ".DEFAULT_CURRENCY ]); showNewUserSettingsInline($chat_id, $user_id); exit; } /* ========================================================= ✅ /cancel behavior ========================================================= */ if($text === '/cancel'){ // برگشت از مرحله کد تخفیف به پرداخت if(($st['state'] ?? '') === 'WAIT_CUST_DISC'){ $cat_id = $st['data']['cat_id'] ?? ''; $item_id = $st['data']['item_id'] ?? ''; clearState($user_id); // نمایش دوباره پیام پرداخت با مبلغ پایه + انتظار رسید showCustomerItem($chat_id, $cat_id, $item_id, null, $user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✅ برگشتی به مرحله پرداخت.\n📸 رسید پرداخت رو ارسال کن." ]); exit; } // برگشت از مرحله کد هدیه کیف پول if(($st['state'] ?? '') === 'WAIT_WALLET_GIFT'){ clearState($user_id); showWalletMenu($chat_id, $user_id); exit; } // برگشت از مرحله مبلغ شارژ if(($st['state'] ?? '') === 'WAIT_WALLET_TOPUP_AMOUNT'){ clearState($user_id); showWalletChargeMenu($chat_id); exit; } // برگشت از مرحله انتظار رسید شارژ if(($st['state'] ?? '') === 'WAIT_WALLET_TOPUP_RECEIPT'){ clearState($user_id); showWalletChargeMenu($chat_id); exit; } // ✅ خروج از حالت ارسال محصول if(($st['state'] ?? '') === 'WAIT_ADMIN_SEND_PRODUCT'){ clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ ارسال محصول لغو شد." ]); exit; } if(($st['state'] ?? '') === 'WAIT_SET_FORCE_JOIN_CHANNEL' || ($st['state'] ?? '') === 'WAIT_SET_JOIN_GIFT_AMOUNT'){ clearState($user_id); showNewUserSettingsInline($chat_id, $user_id); exit; } // سایر موارد: لغو کامل clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ عملیات لغو شد." ]); exit; } if(($st['state'] ?? '') === 'WAIT_PURCHASE_NAME'){ $cat_id = $st['data']['cat_id'] ?? ''; $item_id = $st['data']['item_id'] ?? ''; [$okName, $nameOrMsg] = is_valid_purchase_name($text); if(!$okName){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$nameOrMsg . "\n\nدوباره بفرست یا /cancel" ]); exit; } $purchaseName = $nameOrMsg; if(is_purchase_name_taken($purchaseName)){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ این اسم قبلاً استفاده شده.\nیک اسم دیگه بفرست یا /cancel" ]); exit; } apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✅ اسم ثبت شد: {$purchaseName}", 'parse_mode'=>'HTML' ]); showCustomerItem($chat_id, $cat_id, $item_id, null, $user_id, $purchaseName); exit; } /* ========================= ✅ CUSTOMER: Waiting Receipt for PRODUCT ========================= */ if(($st['state'] ?? '') === 'WAIT_RECEIPT'){ $receipt = extract_receipt_file_id($msg); if($receipt){ $cat_id = $st['data']['cat_id'] ?? ''; $item_id = $st['data']['item_id'] ?? ''; $final = isset($st['data']['final_price']) ? (int)$st['data']['final_price'] : null; $info = getItemInfo($cat_id, $item_id); $catTitle = $info['cat_title'] ?? 'نامشخص'; $itemTitle = $info['item_title'] ?? 'نامشخص'; $basePrice = (int)($info['base_price'] ?? 0); $paid = ($final !== null) ? $final : $basePrice; $username = $msg['from']['username'] ?? ''; $first = $msg['from']['first_name'] ?? ''; $unameTxt = $username ? "@{$username}" : "—"; // ✅ ذخیره سفارش $orderId = (string)($st['data']['order_id'] ?? generate_order_id()); $createdAt = (int)($st['data']['created_at'] ?? time()); $catTitle = (string)($st['data']['cat_title'] ?? $catTitle); $itemTitle = (string)($st['data']['item_title'] ?? $itemTitle); $basePrice = (int)($st['data']['base_price'] ?? $basePrice); $paymentMethod = (string)($st['data']['payment_method'] ?? 'card'); add_order([ 'id' => $orderId, 'ts' => time(), 'user_id' => (string)$user_id, 'username' => $username ? "@{$username}" : '', 'first_name' => $first, 'cat_id' => $cat_id, 'cat_title' => $catTitle, 'item_id' => $item_id, 'item_title' => $itemTitle, 'purchase_name' => (string)($st['data']['purchase_name'] ?? ''), 'amount' => (int)$paid, 'status' => 'pending', 'receipt_file_id' => $receipt, 'payment_method' => 'card', 'delivered_text' => null, 'delivered_link' => null, 'delivered_message_id' => null, 'approved_at' => null, 'rejected_at' => null, 'delivered_at' => null, 'approved_by' => null, 'rejected_by' => null, 'delivered_by' => null ]); // ارسال رسید برای ادمین $cap = "🧾 رسید پرداخت جدید\n\n". "🧾 Order ID: ".ltr($orderId)."\n". "🕒 Invoice Date: ".date("Y-m-d H:i", $createdAt)."\n". "📦 دسته: {$catTitle}\n". "🛒 محصول: {$itemTitle}\n". "💳 روش پرداخت: ".get_payment_method_label($paymentMethod)."\n". "💰 مبلغ اصلی: ".number_format((int)$basePrice)." ".DEFAULT_CURRENCY."\n". "✅ مبلغ نهایی: ".number_format((int)$paid)." ".DEFAULT_CURRENCY."\n"; if((int)$basePrice > (int)$paid){ $cap .= "🏷 میزان تخفیف: ".number_format((int)$basePrice - (int)$paid)." ".DEFAULT_CURRENCY."\n"; } $purchaseName = (string)($st['data']['purchase_name'] ?? ''); if($purchaseName !== ''){ $cap .= "\n🏷 اسم خرید: {$purchaseName}"; } $cap .= "\n👤 کاربر: {$first}\n". "🆔 User ID: ".ltr((string)$user_id)."\n". "🔗 Username: {$unameTxt}"; apiRequest('sendPhoto',[ 'chat_id' => ADMIN_ID, 'photo' => $receipt, 'caption' => $cap, 'parse_mode' => 'HTML', 'reply_markup' => ik([ [ ['text'=>'✅ تایید سفارش', 'callback_data'=>"ord_ok:{$orderId}"], ['text'=>'❌ رد سفارش', 'callback_data'=>"ord_no:{$orderId}"], ] ]) ]); // ✅ لاگ: آرشیو رسید + ثبت خرید log_archive_receipt($receipt, $cap); log_send('buy', "🛍 سفارش جدید (کارت به کارت)\n📦 {$catTitle}\n🛒 {$itemTitle}\n💰 ".number_format($paid)." ".DEFAULT_CURRENCY."\n🆔 ".ltr((string)$user_id)."", 'HTML'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✅ رسید دریافت شد.\nدر حال بررسی توسط ادمین ⏳" ]); clearState($user_id); exit; } apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📸 لطفاً رسید پرداخت رو به صورت عکس ارسال کن.\n\nاگر کد تخفیف داری از دکمه «🏷 کد تخفیف دارم» استفاده کن." ]); exit; } /* ========================= ✅ CUSTOMER: Discount Code Enter ========================= */ if(($st['state'] ?? '') === 'WAIT_CUST_DISC'){ $cat_id = $st['data']['cat_id'] ?? ''; $item_id = $st['data']['item_id'] ?? ''; $spec = get_discount_spec($text); if(!$spec){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ کد تخفیف معتبر نیست.\n\nدوباره بفرست یا /cancel" ]); exit; } // قیمت محصول $info = getItemInfo($cat_id, $item_id); $itemPrice = (int)($info['price'] ?? 0); if($itemPrice <= 0){ clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"این محصول پیدا نشد یا قیمت نامعتبر است."]); exit; } $final = apply_discount_amount($itemPrice, $spec); clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✅ کد تخفیف اعمال شد.", 'fx'=>defined('FX_DISCOUNT_APPLIED') ? FX_DISCOUNT_APPLIED : '' ]); // نمایش دوباره پیام پرداخت با مبلغ نهایی + ورود به حالت انتظار رسید showCustomerItem($chat_id, $cat_id, $item_id, $final, $user_id); exit; } /* ========================= ✅ WALLET: Gift code enter ========================= */ if(($st['state'] ?? '') === 'WAIT_WALLET_GIFT'){ [$ok, $msgx] = redeem_gift_code($user_id, $text); if(!$ok){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$msgx."\n\nدوباره بفرست یا /cancel" ]); exit; } clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>$msgx]); log_send('accounting', "🎁 استفاده از کد هدیه\n🆔 ".ltr((string)$user_id)."\n".$msgx, 'HTML'); showWalletMenu($chat_id, $user_id); exit; } /* ========================= ✅ WALLET: Topup amount (card to card) ========================= */ if(($st['state'] ?? '') === 'WAIT_WALLET_TOPUP_AMOUNT'){ $amt = (int)preg_replace('/\D+/', '', $text); if($amt <= 0){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ مبلغ معتبر نیست. فقط عدد بفرست.\n\n/cancel برای برگشت" ]); exit; } setState($user_id, 'WAIT_WALLET_TOPUP_RECEIPT', ['amount'=>$amt]); $payTxt = build_wallet_topup_payment_text($amt); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$payTxt, 'parse_mode'=>'HTML' ]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📸 بعد از پرداخت، رسید رو به صورت عکس ارسال کن.\n\n/cancel برای برگشت" ]); exit; } /* ========================= ✅ WALLET: Topup receipt (send to admin with approve/reject) ========================= */ if(($st['state'] ?? '') === 'WAIT_WALLET_TOPUP_RECEIPT'){ $receipt = extract_receipt_file_id($msg); if(!$receipt){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📸 لطفاً رسید رو به صورت عکس ارسال کن.\n\n/cancel برای برگشت" ]); exit; } $amt = (int)($st['data']['amount'] ?? 0); if($amt <= 0){ clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"خطا: مبلغ شارژ نامعتبر شد. دوباره تلاش کن."]); exit; } $username = $msg['from']['username'] ?? ''; $first = $msg['from']['first_name'] ?? ''; $unameTxt = $username ? "@{$username}" : "—"; $reqId = 'top_' . substr(md5(uniqid('', true)), 0, 10); $okTopup = add_topup_request([ 'id'=>$reqId, 'ts'=>time(), 'user_id'=>(string)$user_id, 'username'=>$username ? "@{$username}" : '', 'first_name'=>$first, 'amount'=>$amt, 'status'=>'pending', 'receipt_file_id'=>$receipt ]); if(!$okTopup){ clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ خطا در ثبت درخواست شارژ. دوباره تلاش کن." ]); exit; } $cap = "💰 درخواست شارژ کیف پول\n\n". "💵 مبلغ شارژ: ".number_format($amt)." ".DEFAULT_CURRENCY."\n". "🆔 User ID: ".ltr((string)$user_id)."\n". "🔗 Username: {$unameTxt}\n". "🧾 Request ID: ".ltr($reqId).""; apiRequest('sendPhoto',[ 'chat_id' => ADMIN_ID, 'photo' => $receipt, 'caption' => $cap, 'parse_mode' => 'HTML', 'reply_markup' => ik([ [ ['text'=>'✅ تایید شارژ', 'callback_data'=>"topup_ok:{$reqId}"], ['text'=>'❌ رد شارژ', 'callback_data'=>"topup_no:{$reqId}"], ] ]) ]); // ✅ لاگ: آرشیو رسید + حسابداری log_archive_receipt($receipt, $cap); log_send('accounting', "📥 درخواست شارژ کیف پول\n💰 ".number_format($amt)." ".DEFAULT_CURRENCY."\n🆔 ".ltr((string)$user_id)."\n🧾 ".ltr($reqId)."", 'HTML'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✅ رسید شارژ دریافت شد.\nدر حال بررسی توسط ادمین ⏳" ]); clearState($user_id); exit; } /* ========================= ✅ ADMIN: Send product to customer ========================= */ if(($st['state'] ?? '') === 'WAIT_ADMIN_SEND_PRODUCT'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $rep = $msg['reply_to_message'] ?? null; if(!$rep){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ باید روی پیام رسید مشتری Reply کنی و محصول رو بفرستی.\n\n/cancel برای لغو" ]); exit; } // ✅ هر دو مقدار را همان اول از پیام رسید استخراج کن $targetUid = extract_user_id_from_receipt_message($rep); $orderId = extract_order_id_from_receipt_message($rep); if(!$targetUid){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ از روی پیام ریپلای‌شده نتونستم User ID رو پیدا کنم.\n\nحتماً روی پیام «رسید» که ربات فرستاده Reply کن.\n\n/cancel برای لغو" ]); exit; } $ok = admin_send_product_to_user($chat_id, $msg, $targetUid); if(!$ok){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ ارسال محصول ناموفق بود. (ممکنه کاربر ربات رو بلاک کرده باشه یا خطای تلگرام)\n\n/cancel برای لغو" ]); exit; } // ✅ اگر Order ID پیدا شد، هم وضعیت را delivered کن // هم متن/لینک محصول ارسالی را داخل سفارش ذخیره کن if($orderId){ save_order_delivery_payload($orderId, $msg, $user_id); } $logTxt = "📦 ارسال محصول توسط ادمین\n👤 User ID: ".ltr((string)$targetUid)."\n🆔 Admin: ".ltr((string)$user_id).""; if($orderId){ $logTxt .= "\n🧾 Order: ".ltr($orderId).""; } log_send('buy', $logTxt, 'HTML'); $doneText = "✅ محصول با موفقیت برای کاربر ارسال شد.\n👤 User ID: {$targetUid}"; if($orderId){ $doneText .= "\n🧾 Order ID: {$orderId}\n📦 وضعیت سفارش: delivered"; } apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$doneText ]); $thanks = get_text_value('purchase_thanks_text'); if(trim($thanks) === '') { $thanks = "✅ خریدت با موفقیت انجام شد.\nممنون از اعتمادت 🌟"; } apiRequest('sendMessage',[ 'chat_id'=>(string)$targetUid, 'text'=>$thanks ]); clearState($user_id); exit; } /* ========================= Broadcast (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_BROADCAST_TEXT'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"⏳ ارسال پیام همگانی شروع شد..." ]); // ✅ ارسال + گزارش $rep = broadcastToAllUsersReport($text, 'HTML'); $reportTxt = "📣 گزارش ارسال همگانی\n\n". "👥 کل کاربران: {$rep['total']}\n". "✅ موفق: {$rep['success']}\n". "❌ ناموفق: {$rep['failed']}\n". "⏱ زمان: {$rep['time']} ثانیه"; apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$reportTxt, 'parse_mode'=>'HTML' ]); // لاگ (اگر سیستم لاگ داری) if(function_exists('log_send')){ log_send('general', "📣 گزارش ارسال همگانی\n". "کل: {$rep['total']}\n". "موفق: {$rep['success']}\n". "ناموفق: {$rep['failed']}\n". "زمان: {$rep['time']}s\n". "ID Admin: ".ltr((string)$user_id)."", 'HTML' ); } exit; } if(($st['state'] ?? '') === 'WAIT_USER_SEARCH'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $q = trim((string)$text); if($q === ''){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ عبارت جستجو خالیه.\n\nUser ID یا @username یا نام رو بفرست.\n\n/cancel برای لغو" ]); exit; } clearState($user_id); showUserSearchResults($chat_id, $q); exit; } /* ========================= Add category (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_ADD_CAT'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $data = productsData(); $data['categories'][] = [ 'id'=> newId('cat'), 'title'=> $text, 'desc'=> '', 'active'=> true, 'items'=> [] ]; saveProductsData($data); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ دسته اضافه شد."]); log_send('changes', "➕ افزودن دسته\n📦 {$text}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showProductsManageInline($chat_id, $user_id); exit; } /* ========================= Rename category (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_CAT_RENAME'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $cat_id = $st['data']['cat_id'] ?? ''; $data = productsData(); foreach($data['categories'] as &$c){ if($c['id'] === $cat_id){ $c['title'] = $text; break; } } saveProductsData($data); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ نام دسته تغییر کرد."]); log_send('changes', "✏️ تغییر نام دسته\n🧩 Cat: {$cat_id}\n📝 نام جدید: {$text}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showAdminCategory($chat_id, $cat_id); exit; } if(($st['state'] ?? '') === 'WAIT_ITEM_DESC'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $cat_id = $st['data']['cat_id'] ?? ''; $item_id = $st['data']['item_id'] ?? ''; $pd = productsData(); foreach($pd['categories'] as &$c){ if($c['id'] === $cat_id){ foreach($c['items'] as &$it){ if($it['id'] === $item_id){ $it['desc'] = trim((string)$text); break 2; } } } } saveProductsData($pd); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ توضیحات محصول ذخیره شد."]); showAdminItem($chat_id, $cat_id, $item_id); exit; } /* ========================= Edit category desc (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_CAT_DESC'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $cat_id = $st['data']['cat_id'] ?? ''; $pd = productsData(); foreach($pd['categories'] as &$c){ if($c['id'] === $cat_id){ $c['desc'] = trim((string)$text); break; } } saveProductsData($pd); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ توضیحات دسته ذخیره شد."]); log_send('changes', "📝 تغییر توضیحات دسته\n🧩 Cat: {$cat_id}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showCategoryDescPickerInline($chat_id, $user_id); exit; } /* ========================= Add item (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_ITEM_ADD_TITLE'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } setState($user_id, 'WAIT_ITEM_ADD_PRICE', [ 'cat_id' => $st['data']['cat_id'], 'title' => $text ]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"💰 قیمت محصول رو عددی بفرست (مثلاً 160000):\n\n/cancel برای لغو" ]); exit; } if(($st['state'] ?? '') === 'WAIT_ITEM_ADD_PRICE'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $price = preg_replace('/[^0-9]/','',$text); if($price === ''){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"قیمت معتبر نیست. فقط عدد بفرست."]); exit; } $cat_id = $st['data']['cat_id']; $title = $st['data']['title']; $data = productsData(); foreach($data['categories'] as &$c){ if($c['id'] === $cat_id){ $c['items'][] = [ 'id'=> newId('it'), 'title'=> $title, 'price'=> (int)$price, 'active'=> true ]; break; } } saveProductsData($data); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ محصول اضافه شد."]); log_send('changes', "➕ افزودن محصول\n🧩 Cat: {$cat_id}\n🛒 {$title}\n💰 {$price} ".DEFAULT_CURRENCY."\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showAdminCategory($chat_id, $cat_id); exit; } /* ========================= Item rename (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_ITEM_RENAME'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $cat_id = $st['data']['cat_id']; $item_id = $st['data']['item_id']; $data = productsData(); foreach($data['categories'] as &$c){ if($c['id'] === $cat_id){ foreach($c['items'] as &$it){ if($it['id'] === $item_id){ $it['title'] = $text; break 2; } } } } saveProductsData($data); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ نام محصول تغییر کرد."]); log_send('changes', "✏️ تغییر نام محصول\n🧩 Cat: {$cat_id}\n🛒 Item: {$item_id}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showAdminItem($chat_id, $cat_id, $item_id); exit; } /* ========================= Item price (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_ITEM_PRICE'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $price = preg_replace('/[^0-9]/','',$text); if($price === ''){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"قیمت معتبر نیست. فقط عدد بفرست."]); exit; } $cat_id = $st['data']['cat_id']; $item_id = $st['data']['item_id']; $data = productsData(); foreach($data['categories'] as &$c){ if($c['id'] === $cat_id){ foreach($c['items'] as &$it){ if($it['id'] === $item_id){ $it['price'] = (int)$price; break 2; } } } } saveProductsData($data); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ قیمت محصول تغییر کرد."]); log_send('changes', "💰 تغییر قیمت محصول\n🧩 Cat: {$cat_id}\n🛒 Item: {$item_id}\n💰 قیمت جدید: {$price} ".DEFAULT_CURRENCY."\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showAdminItem($chat_id, $cat_id, $item_id); exit; } /* ========================= Payment settings (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_PAY_CARD'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $digits = preg_replace('/\D+/', '', $text); if(strlen($digits) !== 16){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"❌ شماره کارت باید ۱۶ رقم باشد. دوباره بفرست یا /cancel"]); exit; } setState($user_id, 'WAIT_PAY_NAME', ['card'=>$digits]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"👤 نام صاحب کارت رو بفرست:\n\n/cancel برای لغو" ]); exit; } if(($st['state'] ?? '') === 'WAIT_PAY_NAME'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $card = $st['data']['card'] ?? ''; [$ok, $msgx] = set_payment_settings($card, $text); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>$msgx]); log_send('changes', "💳 تغییر تنظیمات پرداخت\n{$msgx}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showPaymentSettingsInline($chat_id, $user_id); exit; } if(($st['state'] ?? '') === 'WAIT_PAY_EDIT_NAME'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $p = get_payment_settings(); [$ok, $msgx] = set_payment_settings($p['card_number'], $text); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>$msgx]); log_send('changes', "💳 تغییر نام صاحب کارت\n{$msgx}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showPaymentSettingsInline($chat_id, $user_id); exit; } /* ========================= Text settings (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_TEXT_EDIT'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $key = $st['data']['key'] ?? ''; if($key === ''){ clearState($user_id); exit; } set_text_value($key, $text); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ متن ذخیره شد."]); log_send('changes', "📝 ویرایش متن\nKey: {$key}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showTextsSettingsInline($chat_id, $user_id); exit; } /* ========================= Discount add flow (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_DISC_CODE'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $code = normalize_discount_code($text); if($code === ''){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"کد نامعتبره. دوباره بفرست یا /cancel"]); exit; } setState($user_id, 'WAIT_DISC_VALUE', ['code'=>$code]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"مقدار تخفیف رو بفرست:\n\n-50000 (کسر مبلغ)\n15% (کسر درصد)\n\n/cancel برای لغو" ]); exit; } if(($st['state'] ?? '') === 'WAIT_DISC_VALUE'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $code = $st['data']['code'] ?? ''; [$ok, $parsed] = parse_discount_value($text); if(!$ok){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"❌ {$parsed}\nدوباره بفرست یا /cancel"]); exit; } set_discount_code($code, $parsed); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"✅ کد تخفیف ذخیره شد: {$code}"]); log_send('changes', "🏷 ثبت/ویرایش کد تخفیف\nCode: {$code}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showDiscountsSettingsInline($chat_id, $user_id); exit; } if(($st['state'] ?? '') === 'WAIT_DISC_REMOVE'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $code = normalize_discount_code($text); $ok = remove_discount_code($code); clearState($user_id); apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>$ok ? "✅ حذف شد: {$code}" : "این کد پیدا نشد."]); log_send('changes', "🗑 حذف کد تخفیف\nCode: {$code}\nResult: ".($ok?'OK':'NOT FOUND')."\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showDiscountsSettingsInline($chat_id, $user_id); exit; } /* ========================= ✅ GIFTCODE add flow (Admin) ========================= */ if(($st['state'] ?? '') === 'WAIT_GIFT_CODE'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $code = normalize_gift_code($text); if($code === ''){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"کد نامعتبره. دوباره بفرست یا /cancel"]); exit; } setState($user_id, 'WAIT_GIFT_AMOUNT', ['code'=>$code]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"💰 مبلغ شارژ این کد رو عددی بفرست (مثلاً 50000):\n\n/cancel برای لغو" ]); exit; } if(($st['state'] ?? '') === 'WAIT_GIFT_AMOUNT'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $code = $st['data']['code'] ?? ''; $amt = (int)preg_replace('/\D+/', '', $text); if($code === '' || $amt <= 0){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"❌ مبلغ نامعتبره. فقط عدد بفرست.\n\n/cancel برای لغو"]); exit; } $ok = set_gift_code($code, $amt); clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$ok ? "✅ کد هدیه ساخته شد:\n\n🎁 {$code}\n💰 ".number_format($amt)." ".DEFAULT_CURRENCY : "❌ خطا در ساخت کد." ]); log_send('changes', "🎁 ساخت کد هدیه\nCode: {$code}\nAmount: ".number_format($amt)." ".DEFAULT_CURRENCY."\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showGiftsSettingsInline($chat_id, $user_id); exit; } if(($st['state'] ?? '') === 'WAIT_GIFT_REMOVE'){ if(!isAdmin($user_id)) { clearState($user_id); exit; } $code = normalize_gift_code($text); $ok = disable_gift_code($code); clearState($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$ok ? "✅ کد غیرفعال شد: {$code}" : "این کد پیدا نشد یا قبلاً غیرفعال شده." ]); log_send('changes', "🗑 غیرفعال‌سازی کد هدیه\nCode: {$code}\nResult: ".($ok?'OK':'NOT FOUND')."\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showGiftsSettingsInline($chat_id, $user_id); exit; } /* ========================= ✅ ADMIN: Referral Callbacks ========================= */ if($data === 'ref_set_money'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id); setState($user_id, 'WAIT_REF_SET_MONEY'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"💰 تنظیم هدیه نقدی\n\nلطفاً مبلغی که می‌خواهید به ازای هر دعوت به کیف پول دعوت‌کننده اضافه شود را به عدد (تومان) بفرستید:\nمثال: 5000\n\n/cancel برای لغو", 'parse_mode'=>'HTML' ]); exit; } if($data === 'ref_manage_links'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id); setState($user_id, 'WAIT_REF_LINKS_UPLOAD'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🔗 مدیریت لینک‌های هدیه\n\nلطفاً لیست لینک‌های کانفیگ/ساب‌لینک را بفرستید.\n⚠️ هر لینک باید در یک خط جداگانه باشد.\n\n/cancel برای لغو", 'parse_mode'=>'HTML' ]); exit; } // unknown state clearState($user_id); } // --- Main commands if($text === '/start'){ if(isAdmin($user_id)){ showBottomMenuAdmin($chat_id); } else { $stn = get_newuser_settings(); $enabled = !empty($stn['force_join']['enabled']); $channel = (string)($stn['force_join']['channel'] ?? ''); if($enabled && $channel !== ''){ [$ok, $info] = is_user_joined_channel($user_id, $channel); if($ok){ showBottomMenuCustomer($chat_id); } else { send_force_join_prompt($chat_id); } } else { showBottomMenuCustomer($chat_id); } } if(str_starts_with($msg['text'] ?? '', '/start ref_')){ $inviter = str_replace('/start ref_', '', $msg['text']); process_referral($user_id, $inviter); } exit; } // ✅ ساخت تاپیک های لاگ if($text === '/log_setup'){ if(!isAdmin($user_id)){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"⛔️ دسترسی نداری." ]); exit; } if(!defined('LOG_CHAT_ID') || (string)LOG_CHAT_ID === ''){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ LOG_CHAT_ID تو pconfig.php تنظیم نشده." ]); exit; } // 1) تلاش برای ساخت/بررسی تاپیک‌ها $map = log_setup_topics((string)LOG_CHAT_ID); // 2) فایل و خروجی رو بررسی کن $topics = function_exists('load_log_topics') ? load_log_topics() : readJson(DATA_DIR.'/log_topics.json', []); // چک کن آیا حداقل یکی از تاپیک‌ها thread_id دارد؟ $hasThread = (!empty($topics['general']) && (int)$topics['general'] > 0) || (!empty($topics['orders']) && (int)$topics['orders'] > 0) || (!empty($topics['receipts']) && (int)$topics['receipts'] > 0) || (!empty($topics['errors']) && (int)$topics['errors'] > 0); if(!$hasThread){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"⚠️ تاپیک‌ها ذخیره نشدن یا thread_id برنگشته.\n\nخروجی log_topics.json:\n".htmlspecialchars(json_encode($topics, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT))."", 'parse_mode'=>'HTML' ]); exit; } // 3) پیام تست داخل تاپیک General $ok = false; if(function_exists('log_send')){ $ok = log_send('general', "✅ لاگ فعال شد\n🕒 ".date("Y-m-d H:i:s"), 'HTML'); } apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=> $ok ? "✅ تاپیک‌ها ساخته/ثبت شدند.\n✅ لاگ فعال شد و پیام تست در تاپیک General ارسال شد." : "✅ تاپیک‌ها ساخته/ثبت شدند ولی پیام تست لاگ ارسال نشد.\n(احتمالاً log_send مشکل دارد یا اجازه ارسال داخل تاپیک نیست.)" ]); exit; } // (اختیاری) گرفتن chat_id گروه if($text === '/chatid'){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"chat_id: ".$chat_id ]); exit; } // --- CUSTOMER MENU actions // --- CUSTOMER MENU actions if($text === '🛒 خرید اشتراک'){ showProductsForCustomerView($chat_id); exit; } if($text === '📘 آموزش اتصال'){ showTrainingForCustomer($chat_id); exit; } if($text === '📜 قوانین'){ showRulesForCustomer($chat_id); exit; } if($text === '💬 پشتیبانی'){ showSupportForCustomer($chat_id); exit; } if($text === '👤 حساب کاربری من'){ showMyAccountMenu($chat_id, $user_id); exit; } if($text === '💰 کیف پول'){ showWalletMenu($chat_id, $user_id); exit; } if($text === '👥 زیرمجموعه گیری') { showReferralMenu($chat_id, $user_id); exit; } // --- ADMIN MENU actions if($text === '👥 کاربران ربات'){ if(!isAdmin($user_id)){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"⛔️ دسترسی ندارید."]); exit; } showUsersMenuInline($chat_id, $user_id); exit; } if($text === '💰 مدیریت کیف پول'){ if(!isAdmin($user_id)){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"⛔️ دسترسی ندارید."]); exit; } $txt = "💰 مدیریت کیف پول کاربران\n\n". "در این بخش می‌توانید موجودی کاربران را بررسی یا به صورت دستی تغییر دهید.\n\n". "لطفاً یکی از گزینه‌های زیر را انتخاب کنید 👇"; apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$txt, 'parse_mode'=>'HTML', 'reply_markup'=>ik([ [[ 'text'=>'🔍 مشاهده موجودی کاربر', 'callback_data'=>'adm_wal_view' ]], [[ 'text'=>'✏️ تغییر موجودی (کم/زیاد)', 'callback_data'=>'adm_wal_edit' ]], ]) ]); exit; } if($text === '🧩 مدیریت محصولات'){ if(!isAdmin($user_id)){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"⛔️ دسترسی ندارید."]); exit; } showCustomerMenuAdmin($chat_id); exit; } if($text === '⚙️ تنظیمات فروشگاه'){ if(!isAdmin($user_id)){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"⛔️ دسترسی ندارید."]); exit; } showShopSettingsInline($chat_id, $user_id); exit; } if($text === '📣 ارسال همگانی'){ if(!isAdmin($user_id)){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"⛔️ دسترسی ندارید."]); exit; } startBroadcastFlow($chat_id, $user_id); exit; } if($text === 'ℹ️ اطلاعات ربات'){ if(!isAdmin($user_id)){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"⛔️ دسترسی ندارید."]); exit; } showRobotInfo($chat_id, $user_id); exit; } if($text === '📊 آمار فروش'){ if(!isAdmin($user_id)){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"⛔️ دسترسی ندارید."]); exit; } showSalesStats($chat_id, $user_id); exit; } // ✅ Admin keyboard button: ارسال محصول if($text === '📦 ارسال محصول'){ if(!isAdmin($user_id)){ apiRequest('sendMessage',['chat_id'=>$chat_id,'text'=>"⛔️ دسترسی ندارید."]); exit; } setState($user_id, 'WAIT_ADMIN_SEND_PRODUCT'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📦 حالت ارسال محصول فعال شد.\n\n✅ حالا روی پیام «رسید مشتری» Reply کن و فایل/متن محصول رو بفرست تا برای همان مشتری ارسال کنم.\n\n/cancel برای لغو" ]); exit; } apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"سلام به ربات ما خوش اومدی ! لطفا از منو پایین یک گزینه را انتخاب کنید\n\n/start" ]); exit; } /* ========================= CALLBACK QUERY ========================= */ if(isset($update['callback_query'])){ $cq = $update['callback_query']; $callback_id = $cq['id']; $chat_id = $cq['message']['chat']['id']; $user_id = $cq['from']['id']; $data = $cq['data']; if(function_exists('handle_menu_ext_callback') && handle_menu_ext_callback($cq, $callback_id, $chat_id, $user_id, $data)) exit; // Customer View if(str_starts_with($data, 'pv_cat:')){ $cat_id = explode(':', $data, 2)[1]; answerCallback($callback_id, "باز شد ✅"); $stx = getState($user_id); if($stx && in_array(($stx['state'] ?? ''), ['WAIT_RECEIPT','WAIT_CUST_DISC'], true)){ clearState($user_id); } showCustomerCategory($chat_id, $cat_id); exit; } if($data === 'pv_back:cats'){ $stx = getState($user_id); if($stx && in_array(($stx['state'] ?? ''), ['WAIT_RECEIPT','WAIT_CUST_DISC'], true)){ clearState($user_id); } answerCallback($callback_id, "بازگشت ✅"); showProductsForCustomerView($chat_id); exit; } if($data === 'ref_manage_links'){ setState($user_id, 'WAIT_REF_LINKS_UPLOAD'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🔗 لطفاً لیست لینک‌های کانفیگ را بفرستید (هر خط یک لینک):\n\nمثلاً ۳۰ خط لینک ارسال کنید.\n/cancel برای لغو" ]); exit; } if(str_starts_with($data, 'pv_item:')){ $parts = explode(':', $data); $cat_id = $parts[1] ?? ''; $item_id = $parts[2] ?? ''; answerCallback($callback_id, "اسم خرید رو بفرست ✅"); setState($user_id, 'WAIT_PURCHASE_NAME', [ 'cat_id' => $cat_id, 'item_id' => $item_id ]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✏️ برای این خرید یک اسم انگلیسی انتخاب کن.\n\n". "شرایط اسم:\n". "• فقط حروف انگلیسی، عدد، _ و -\n". "• بین 3 تا 24 کاراکتر\n". "• تکراری نباشد\n\n". "مثال:\n". "securepath_1\n". "my-vpn2\n\n". "/cancel برای لغو", 'parse_mode'=>'HTML' ]); exit; } if(str_starts_with($data, 'acc_order_delivery:')){ $orderId = explode(':', $data, 2)[1] ?? ''; answerCallback($callback_id, "محصول دریافتی ✅"); showDeliveredProductForCustomer($chat_id, $user_id, $orderId); exit; } /* ========================= ✅ CUSTOMER: Discount Button ========================= */ if(str_starts_with($data, 'pv_disc:')){ $parts = explode(':', $data); $cat_id = $parts[1] ?? ''; $item_id = $parts[2] ?? ''; answerCallback($callback_id, "کد رو بفرست ✅"); setState($user_id, 'WAIT_CUST_DISC', [ 'cat_id' => $cat_id, 'item_id' => $item_id ]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🏷 اگر کد تخفیف داری ارسال کن:\n\n/cancel برای برگشت به مرحله پرداخت" ]); exit; } if($data === 'usr_search'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "عبارت رو بفرست ✅"); setState($user_id, 'WAIT_USER_SEARCH'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🔎 User ID یا @username یا نام کاربر رو بفرست.\n\nمثال:\n1162298499\n@securepath\nرضا\n\n/cancel برای لغو" ]); exit; } /* ========================= ✅ ACCOUNT / WALLET UI ========================= */ if($data === 'acc_back'){ answerCallback($callback_id, "باشه ✅"); showBottomMenuCustomer($chat_id); exit; } if($data === 'acc_orders'){ answerCallback($callback_id, "سفارش‌ها ✅"); showMyOrders($chat_id, $user_id, 1, 10); exit; } if(str_starts_with($data, 'acc_orders_page:')){ $p = (int)explode(':', $data, 2)[1]; answerCallback($callback_id, "صفحه {$p} ✅"); showMyOrders($chat_id, $user_id, $p, 10); exit; } if($data === 'acc_wallet'){ answerCallback($callback_id, "کیف پول ✅"); showWalletMenu($chat_id, $user_id); exit; } if($data === 'wal_charge'){ answerCallback($callback_id, "شارژ ✅"); showWalletChargeMenu($chat_id); exit; } if($data === 'wal_gift'){ answerCallback($callback_id, "کد هدیه ✅"); setState($user_id, 'WAIT_WALLET_GIFT'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🎁 کد هدیه رو ارسال کن:\n\n/cancel برای برگشت" ]); exit; } if($data === 'wal_card'){ answerCallback($callback_id, "کارت به کارت ✅"); setState($user_id, 'WAIT_WALLET_TOPUP_AMOUNT'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"💵 مبلغ شارژ رو عددی بفرست (مثلاً 200000):\n\n/cancel برای برگشت" ]); exit; } if(str_starts_with($data, 'ord_ok:')){ if(!isAdmin($user_id)){ answerCallback($callback_id, "⛔️", true); exit; } answerCallback($callback_id, "در حال تایید سفارش..."); $orderId = explode(':', $data, 2)[1]; $ok = set_order_status($orderId, 'approved', $user_id); if(!$ok){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ این سفارش یافت نشد یا قبلاً بررسی شده.\n\n🧾 Order ID: {$orderId}" ]); exit; } [$idx, $order, $all] = find_order_by_id($orderId); $uid = (string)($order['user_id'] ?? ''); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✅ سفارش تایید شد.\n🧾 Order ID: {$orderId}" ]); if($uid !== ''){ apiRequest('sendMessage',[ 'chat_id'=>$uid, 'text'=>"✅ سفارش شما تایید شد.\n🧾 شماره سفارش: {$orderId}\n📦 به‌زودی محصول برای شما ارسال می‌شود.", 'fx'=>defined('FX_SUCCESS') ? FX_SUCCESS : '' ]); } log_send('buy', "✅ تایید سفارش\n🧾 ".ltr($orderId)."\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); exit; } if(str_starts_with($data, 'acc_order_view:')){ $orderId = explode(':', $data, 2)[1] ?? ''; answerCallback($callback_id, "جزئیات سفارش ✅"); showOrderDetailsForCustomer($chat_id, $user_id, $orderId); exit; } if(str_starts_with($data, 'acc_order_delivery:')){ $orderId = explode(':', $data, 2)[1] ?? ''; answerCallback($callback_id, "محصول تحویلی ✅"); showDeliveredProductForCustomer($chat_id, $user_id, $orderId); exit; } if(str_starts_with($data, 'ord_no:')){ if(!isAdmin($user_id)){ answerCallback($callback_id, "⛔️", true); exit; } answerCallback($callback_id, "در حال رد سفارش..."); $orderId = explode(':', $data, 2)[1]; $ok = set_order_status($orderId, 'rejected', $user_id); if(!$ok){ apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ این سفارش یافت نشد یا قبلاً بررسی شده.\n\n🧾 Order ID: {$orderId}" ]); exit; } [$idx, $order, $all] = find_order_by_id($orderId); $uid = (string)($order['user_id'] ?? ''); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ سفارش رد شد.\n🧾 Order ID: {$orderId}" ]); if($uid !== ''){ apiRequest('sendMessage',[ 'chat_id'=>$uid, 'text'=>"❌ سفارش شما رد شد.\n🧾 شماره سفارش: {$orderId}\nاگر فکر می‌کنی اشتباه شده، با پشتیبانی در ارتباط باش.", 'fx'=>defined('FX_PAYMENT_FAILED') ? FX_PAYMENT_FAILED : '' ]); } log_send('buy', "❌ رد سفارش\n🧾 ".ltr($orderId)."\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); exit; } /* ========================= ✅ ADMIN: Approve/Reject wallet topup ========================= */ if(str_starts_with($data, 'topup_ok:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $reqId = explode(':',$data,2)[1]; $req = update_topup_by_id($reqId, function($req){ if(($req['status'] ?? '') !== 'pending'){ return null; } $req['status'] = 'approved'; $req['approved_at'] = time(); return $req; }); if(!$req){ answerCallback($callback_id,"یافت نشد یا قبلاً بررسی شده", true); exit; } $amt = (int)($req['amount'] ?? 0); $uid = (string)($req['user_id'] ?? ''); if($amt <= 0 || $uid === ''){ answerCallback($callback_id,"اطلاعات درخواست نامعتبره", true); exit; } add_wallet_balance($uid, $amt); answerCallback($callback_id, "✅ تایید شد"); apiRequest('sendMessage',[ 'chat_id'=>$uid, 'text'=>"✅ شارژ کیف پول شما تایید شد.\n💰 مبلغ ".number_format($amt)." ".DEFAULT_CURRENCY." به کیف پول اضافه شد.", 'fx'=>defined('FX_WALLET_CHARGED') ? FX_WALLET_CHARGED : '' ]); log_send('accounting', "✅ تایید شارژ کیف پول\n🆔 ".ltr((string)$uid)."\n💰 ".number_format($amt)." ".DEFAULT_CURRENCY."\n🧾 ".ltr($reqId)."", 'HTML'); exit; } if(str_starts_with($data, 'topup_no:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $reqId = explode(':',$data,2)[1]; $req = update_topup_by_id($reqId, function($req){ if(($req['status'] ?? '') !== 'pending'){ return null; } $req['status'] = 'rejected'; $req['rejected_at'] = time(); return $req; }); if(!$req){ answerCallback($callback_id,"یافت نشد یا قبلاً بررسی شده", true); exit; } $amt = (int)($req['amount'] ?? 0); $uid = (string)($req['user_id'] ?? ''); answerCallback($callback_id, "❌ رد شد"); apiRequest('sendMessage',[ 'chat_id'=>$uid, 'text'=>"❌ شارژ کیف پول شما رد شد.\nاگر فکر می‌کنی اشتباه شده، دوباره رسید درست ارسال کن.", 'fx'=>defined('FX_PAYMENT_FAILED') ? FX_PAYMENT_FAILED : '' ]); log_send('accounting', "❌ رد شارژ کیف پول\n🆔 ".ltr((string)$uid)."\n💰 ".number_format($amt)." ".DEFAULT_CURRENCY."\n🧾 ".ltr($reqId)."", 'HTML'); exit; } /* ========================= Admin: back ========================= */ if($data === 'adm_back:cats'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "بازگشت ✅"); showProductsManageInline($chat_id, $user_id); exit; } // Admin: add category if($data === 'adm_add_cat'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_ADD_CAT'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"➕ نام دسته جدید رو بفرست:\n\n/cancel برای لغو" ]); exit; } // Admin: open category if(str_starts_with($data, 'adm_cat:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $cat_id = explode(':', $data, 2)[1]; answerCallback($callback_id, "باز شد ✅"); showAdminCategory($chat_id, $cat_id); exit; } // Admin: cat rename if(str_starts_with($data, 'adm_cat_rename:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $cat_id = explode(':', $data, 2)[1]; answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_CAT_RENAME', ['cat_id'=>$cat_id]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✏️ نام جدید دسته رو بفرست:\n\n/cancel برای لغو" ]); exit; } // Admin: cat toggle if(str_starts_with($data, 'adm_cat_toggle:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $cat_id = explode(':', $data, 2)[1]; $pd = productsData(); foreach($pd['categories'] as &$c){ if($c['id'] === $cat_id){ $c['active'] = empty($c['active']) ? true : false; break; } } saveProductsData($pd); answerCallback($callback_id, "تغییر کرد ✅"); log_send('changes', "♻️ تغییر وضعیت دسته\n🧩 Cat: {$cat_id}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showAdminCategory($chat_id, $cat_id); exit; } // Admin: item add if(str_starts_with($data, 'adm_item_add:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $cat_id = explode(':', $data, 2)[1]; answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_ITEM_ADD_TITLE', ['cat_id'=>$cat_id]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"➕ نام محصول رو بفرست:\n\n/cancel برای لغو" ]); exit; } // Admin: open item if(str_starts_with($data, 'adm_item:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $parts = explode(':', $data); $cat_id = $parts[1] ?? ''; $item_id = $parts[2] ?? ''; answerCallback($callback_id, "باز شد ✅"); showAdminItem($chat_id, $cat_id, $item_id); exit; } // Admin: item rename if(str_starts_with($data, 'adm_item_rename:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $parts = explode(':', $data); $cat_id = $parts[1] ?? ''; $item_id = $parts[2] ?? ''; answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_ITEM_RENAME', ['cat_id'=>$cat_id,'item_id'=>$item_id]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✏️ نام جدید محصول رو بفرست:\n\n/cancel برای لغو" ]); exit; } // Admin: item price if(str_starts_with($data, 'adm_item_price:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $parts = explode(':', $data); $cat_id = $parts[1] ?? ''; $item_id = $parts[2] ?? ''; answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_ITEM_PRICE', ['cat_id'=>$cat_id,'item_id'=>$item_id]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"💰 قیمت جدید رو عددی بفرست (مثلاً 160000):\n\n/cancel برای لغو" ]); exit; } if(str_starts_with($data, 'adm_cat_desc:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $cat_id = explode(':', $data, 2)[1]; answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_CAT_DESC', ['cat_id'=>$cat_id]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📝 توضیحات جدید این دسته رو بفرست:\n\n/cancel برای لغو" ]); exit; } if(str_starts_with($data, 'adm_item_desc:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $p = explode(':', $data); $cat_id = $p[1] ?? ''; $item_id = $p[2] ?? ''; answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_ITEM_DESC', [ 'cat_id'=>$cat_id, 'item_id'=>$item_id ]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📝 توضیحات جدید این محصول رو بفرست:\n\n/cancel برای لغو" ]); exit; } // Admin: item toggle if(str_starts_with($data, 'adm_item_toggle:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $parts = explode(':', $data); $cat_id = $parts[1] ?? ''; $item_id = $parts[2] ?? ''; $pd = productsData(); foreach($pd['categories'] as &$c){ if($c['id'] === $cat_id){ foreach($c['items'] as &$it){ if($it['id'] === $item_id){ $it['active'] = empty($it['active']) ? true : false; break 2; } } } } saveProductsData($pd); answerCallback($callback_id, "تغییر کرد ✅"); log_send('changes', "♻️ تغییر وضعیت محصول\n🧩 Cat: {$cat_id}\n🛒 Item: {$item_id}\n🆔 Admin: ".ltr((string)$user_id)."", 'HTML'); showAdminItem($chat_id, $cat_id, $item_id); exit; } // Users pagination if(str_starts_with($data, 'usr_page:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $page = (int)explode(':', $data, 2)[1]; answerCallback($callback_id, "صفحه {$page} ✅"); showUsersPage($chat_id, $page, 20); exit; } if($data === 'usr_back'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "برگشت ✅"); showUsersMenuInline($chat_id, $user_id); exit; } // Shop settings actions if($data === 'set_pay'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "پرداخت ✅"); showPaymentSettingsInline($chat_id, $user_id); exit; } if($data === 'pay_edit_card'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_PAY_CARD'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"💳 شماره کارت (۱۶ رقم) رو بفرست:\n\n/cancel برای لغو" ]); exit; } if($data === 'pay_edit_name'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_PAY_EDIT_NAME'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"👤 نام صاحب کارت رو بفرست:\n\n/cancel برای لغو" ]); exit; } if($data === 'set_custom_emoji'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "کاستوم ایموجی ✨"); showCustomEmojiInline($chat_id, $user_id); exit; } if($data === 'set_texts'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "متن‌ها ✅"); showTextsSettingsInline($chat_id, $user_id); exit; } if(str_starts_with($data, 'txt_edit:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $key = explode(':', $data, 2)[1]; answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_TEXT_EDIT', ['key'=>$key]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✏️ متن جدید رو بفرست:\n\n/cancel برای لغو" ]); exit; } if($data === 'txt_cat_desc'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "انتخاب کن ✅"); showCategoryDescPickerInline($chat_id, $user_id); exit; } if(str_starts_with($data, 'catdesc:')){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $cat_id = explode(':', $data, 2)[1]; answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_CAT_DESC', ['cat_id'=>$cat_id]); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📝 توضیحات جدید این دسته رو بفرست:\n\n/cancel برای لغو" ]); exit; } if($data === 'set_rules'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "قوانین ✅"); setState($user_id, 'WAIT_TEXT_EDIT', ['key'=>'rules_text']); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📜 متن قوانین رو بفرست:\n\n/cancel برای لغو" ]); exit; } if($data === 'set_training'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "آموزش ✅"); setState($user_id, 'WAIT_TEXT_EDIT', ['key'=>'training_text']); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📘 متن آموزش رو بفرست:\n\n/cancel برای لغو" ]); exit; } if($data === 'set_discounts'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "تخفیف ✅"); showDiscountsSettingsInline($chat_id, $user_id); exit; } if($data === 'disc_add'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "مرحله ۱ ✅"); setState($user_id, 'WAIT_DISC_CODE'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🏷 کد تخفیف رو بفرست (مثلاً VIP15):\n\n/cancel برای لغو" ]); exit; } if($data === 'disc_remove'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "حذف ✅"); setState($user_id, 'WAIT_DISC_REMOVE'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🗑 کد تخفیفی که می‌خوای حذف بشه رو بفرست:\n\n/cancel برای لغو" ]); exit; } if($data === 'disc_list'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "لیست ✅"); showDiscountsList($chat_id); exit; } if($data === 'set_gifts'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "کد هدیه ✅"); showGiftsSettingsInline($chat_id, $user_id); exit; } if($data === 'set_back'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "بازگشت ✅"); showShopSettingsInline($chat_id, $user_id); exit; } /* ========================= ✅ CUSTOMER: Pay with Wallet ========================= */ if(str_starts_with($data, 'pv_wpay:')){ $parts = explode(':', $data); $cat_id = $parts[1] ?? ''; $item_id = $parts[2] ?? ''; $info = getItemInfo($cat_id, $item_id); if(!$info){ answerCallback($callback_id, "محصول پیدا نشد ❌", true); exit; } $catTitle = $info['cat_title'] ?? 'نامشخص'; $itemTitle = $info['item_title'] ?? 'نامشخص'; $price = (int)($info['price'] ?? 0); if($price <= 0){ answerCallback($callback_id, "قیمت نامعتبر ❌", true); exit; } // ✅ اگر قبلش کد تخفیف زده و مبلغ نهایی در state هست، همونو بردار $final = $price; $st2 = getState($user_id); if($st2 && ($st2['state'] ?? '') === 'WAIT_RECEIPT'){ if(($st2['data']['cat_id'] ?? '') === $cat_id && ($st2['data']['item_id'] ?? '') === $item_id){ if(isset($st2['data']['final_price'])){ $final = (int)$st2['data']['final_price']; } } } if($final <= 0) $final = $price; // کسر موجودی (اتمیک) $ok = spend_wallet_balance($user_id, $final); if(!$ok){ answerCallback($callback_id, "موجودی کیف پول کافی نیست ❌", true); exit; } // ثبت سفارش $uname = $cq['from']['username'] ?? ''; $unameTxt = $uname ? "@{$uname}" : "—"; $orderId = (string)($st['data']['order_id'] ?? generate_order_id()); $createdAt = (int)($st['data']['created_at'] ?? time()); $catTitle = (string)($st['data']['cat_title'] ?? $catTitle); $itemTitle = (string)($st['data']['item_title'] ?? $itemTitle); $basePrice = (int)($st['data']['base_price'] ?? $basePrice); $paymentMethod = (string)($st['data']['payment_method'] ?? 'card'); add_order([ 'id' => $orderId, 'ts' => time(), 'user_id' => (string)$user_id, 'username' => $username ? "@{$username}" : '', 'first_name' => $first, 'cat_id' => $cat_id, 'cat_title' => $catTitle, 'item_id' => $item_id, 'item_title' => $itemTitle, 'purchase_name' => (string)($st['data']['purchase_name'] ?? ''), 'amount' => (int)$paid, 'status' => 'pending', 'receipt_file_id' => $receipt, 'payment_method' => 'card', 'delivered_text' => null, 'delivered_link' => null, 'delivered_message_id' => null, 'approved_at' => null, 'rejected_at' => null, 'delivered_at' => null, 'approved_by' => null, 'rejected_by' => null, 'delivered_by' => null ]); // رسید برای ادمین (متنی) $adminText = "✅ پرداخت با کیف پول\n\n". "🆔 User ID: ".ltr((string)$user_id)."\n". "🔗 Username: {$unameTxt}\n\n". "📦 محصول خریداری شده:\n". "• دسته: {$catTitle}\n". "• محصول: {$itemTitle}\n". "• مبلغ: ".number_format($final)." ".DEFAULT_CURRENCY."\n\n". "🗓 تاریخ خرید: ".format_date_fa(time())."\n\n". "🟢 پرداخت شده با کیف پول ✅"; apiRequest('sendMessage',[ 'chat_id' => ADMIN_ID, 'text' => $adminText, 'parse_mode' => 'HTML' ]); log_send('buy', "✅ پرداخت با کیف پول\n📦 {$catTitle}\n🛒 {$itemTitle}\n💰 ".number_format($final)." ".DEFAULT_CURRENCY."\n🆔 ".ltr((string)$user_id)."", 'HTML'); log_send('accounting', "💰 برداشت از کیف پول\nمبلغ: ".number_format($final)." ".DEFAULT_CURRENCY."\n🆔 ".ltr((string)$user_id)."", 'HTML'); // پاک کردن حالت انتظار رسید (اگر بود) if($st2 && ($st2['state'] ?? '') === 'WAIT_RECEIPT'){ clearState($user_id); } answerCallback($callback_id, "پرداخت شد ✅", false); apiRequest('sendMessage',[ 'chat_id' => $chat_id, 'text' => "✅ پرداخت با کیف پول انجام شد.\nسفارش شما ثبت شد." ]); exit; } // ✅ Gifts settings actions (Admin) if($data === 'gift_add'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "مرحله ۱ ✅"); setState($user_id, 'WAIT_GIFT_CODE'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🎁 کد هدیه رو بفرست (مثلاً GIFT50):\n\n/cancel برای لغو" ]); exit; } if($data === 'gift_remove'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "حذف ✅"); setState($user_id, 'WAIT_GIFT_REMOVE'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🗑 کد هدیه‌ای که می‌خوای حذف/غیرفعال بشه رو بفرست:\n\n/cancel برای لغو" ]); exit; } if($data === 'gift_list'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "لیست ✅"); showGiftCodesList($chat_id); exit; } if($data === 'gift_back'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "بازگشت ✅"); showShopSettingsInline($chat_id, $user_id); exit; } /* ========================= ✅ FORCE JOIN: check button ========================= */ if($data === 'join_check'){ answerCallback($callback_id, "درحال بررسی...", false); $stn = get_newuser_settings(); $enabled = !empty($stn['force_join']['enabled']); $channel = (string)($stn['force_join']['channel'] ?? ''); if(!$enabled || $channel === ''){ // اگر غیرفعال بود، مستقیم منو showBottomMenuCustomer($chat_id); exit; } [$ok, $info] = is_user_joined_channel($user_id, $channel); if(!$ok){ // عضو نیست یا خطا apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"❌ هنوز عضو کانال نیستی.\n\nاول عضو شو بعد دوباره «✅ عضو شدم» رو بزن." ]); send_force_join_prompt($chat_id); exit; } // ✅ عضو شد → هدیه عضویت (فقط یک بار) $gift_on = !empty($stn['join_gift']['enabled']); $gift_amt = (int)($stn['join_gift']['amount'] ?? 0); if($gift_on && $gift_amt > 0 && !was_join_gift_given($user_id)){ add_wallet_balance($user_id, $gift_amt); mark_join_gift_given($user_id); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🎁 تبریک! بابت عضویت در کانال، کیف پولت به مبلغ ".number_format($gift_amt)." ".DEFAULT_CURRENCY." شارژ شد." ]); // لاگ حسابداری (اگر فعال کردی) if(function_exists('log_send')){ log_send('accounting', "🎁 هدیه عضویت\n🆔 ".ltr((string)$user_id)."\n💰 ".number_format($gift_amt)." ".DEFAULT_CURRENCY, 'HTML'); } } // ✅ برگشت به منوی استارت showBottomMenuCustomer($chat_id); exit; } /* ========================= ✅ ADMIN: New User Settings panel ========================= */ if($data === 'set_newuser'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "باز شد ✅"); showNewUserSettingsInline($chat_id, $user_id); exit; } if($data === 'nu_fj_toggle'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $stn = get_newuser_settings(); $cur = !empty($stn['force_join']['enabled']); set_force_join_enabled(!$cur); answerCallback($callback_id, "ذخیره شد ✅"); showNewUserSettingsInline($chat_id, $user_id); exit; } if($data === 'nu_fj_set_channel'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_SET_FORCE_JOIN_CHANNEL'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"📣 یوزرنیم یا لینک کانال رو بفرست:\nمثال:\n@securepath_1\nیا\nhttps://t.me/securepath_1\n\n/cancel برای لغو" ]); exit; } if($data === 'nu_gift_toggle'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $stn = get_newuser_settings(); $cur = !empty($stn['join_gift']['enabled']); set_join_gift_enabled(!$cur); answerCallback($callback_id, "ذخیره شد ✅"); showNewUserSettingsInline($chat_id, $user_id); exit; } if($data === 'nu_gift_set_amount'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "ارسال کن ✅"); setState($user_id, 'WAIT_SET_JOIN_GIFT_AMOUNT'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"💰 مبلغ هدیه عضویت رو عددی بفرست (مثلاً 50000):\n\n/cancel برای لغو" ]); exit; } if($data === 'adm_wal_view'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "آیدی کاربر را بفرست"); setState($user_id, 'WAIT_ADMIN_WAL_VIEW_ID'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🔍 مشاهده موجودی\n\nلطفاً User ID عددی کاربر مورد نظر را ارسال کنید:\n\n/cancel برای لغو" , 'parse_mode'=>'HTML' ]); exit; } if($data === 'adm_wal_edit'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "آیدی کاربر را بفرست"); setState($user_id, 'WAIT_ADMIN_WAL_EDIT_ID'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"✏️ تغییر دستی موجودی\n\nمرحله ۱: لطفاً User ID عددی کاربر را ارسال کنید:\n\n/cancel برای لغو" , 'parse_mode'=>'HTML' ]); exit; } /* ========================= ✅ ADMIN: Referral System Menu ========================= */ if($data === 'set_referral'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $st = get_ref_settings(); $status = ($st['enabled'] ?? false) ? "✅ فعال" : "❌ غیرفعال"; $reward_inviter = isset($st['reward_inviter']) ? $st['reward_inviter'] : 0; $reward_invitee = isset($st['reward_invitee']) ? $st['reward_invitee'] : 0; $target_invites = isset($st['target_invites']) ? $st['target_invites'] : 0; $cooldown = isset($st['cooldown_minutes']) ? $st['cooldown_minutes'] : 0; $txt = "👥 سیستم زیرمجموعه گیری\n\n" . "وضعیت فعلی: {$status}\n\n" . "💰 هدیه دعوت‌کننده: " . number_format($reward_inviter) . " " . DEFAULT_CURRENCY . "\n" . "💰 هدیه دعوت‌شونده: " . number_format($reward_invitee) . " " . DEFAULT_CURRENCY . "\n" . "🎯 تعداد دعوت لازم برای لینک هدیه: " . $target_invites . "\n" . "⏱ محدودیت زمانی (Cooldown): " . $cooldown . " دقیقه\n\n" . "لطفاً یک مورد را برای تغییر انتخاب کنید 👇"; apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$txt, 'parse_mode'=>'HTML', // این بخش را جایگزین دکمه‌های قبلی در بخش set_referral کنید 'reply_markup'=>ik([ [['text'=>'🔁 روشن/خاموش کردن سیستم', 'callback_data'=>'ref_toggle']], [['text'=>'💰 تنظیم مبالغ هدیه نقدی', 'callback_data'=>'ref_set_money']], [['text'=>'🎯 تنظیم تعداد دعوت لازم', 'callback_data'=>'ref_set_target']], [['text'=>'⏱ تنظیم محدودیت زمانی', 'callback_data'=>'ref_set_cooldown']], [['text'=>'🔗 مدیریت لینک‌های هدیه', 'callback_data'=>'ref_manage_links']], [['text'=>'⬅️ بازگشت', 'callback_data'=>'set_back']] ]) ]); answerCallback($callback_id); exit; } if($data === 'ref_toggle'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $st = get_ref_settings(); $st['enabled'] = !($st['enabled'] ?? false); save_ref_settings($st); answerCallback($callback_id, "وضعیت تغییر کرد ✅"); // بازخوانی منو برای آپدیت شدن وضعیت در متن $data = 'set_referral'; // در اینجا کد بالا دوباره اجرا می‌شود تا متن آپدیت شود } if($data === 'ref_set_target'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "تعداد را بفرست"); setState($user_id, 'WAIT_REF_SET_TARGET'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"🎯 تنظیم تعداد دعوت لازم\n\nلطفاً تعداد زیرمجموعه مورد نیاز برای دریافت هر لینک هدیه را به صورت عدد بفرستید:\n\n/cancel برای لغو", 'parse_mode'=>'HTML' ]); exit; } if($data === 'ref_set_cooldown'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } answerCallback($callback_id, "زمان را بفرست"); setState($user_id, 'WAIT_REF_SET_COOLDOWN'); apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>"⏱ تنظیم محدودیت زمانی (دقیقه)\n\nلطفاً فاصله زمانی مجاز بین هر بار دریافت لینک هدیه را به دقیقه بفرستید (مثلاً 20):\n\n/cancel برای لغو", 'parse_mode'=>'HTML' ]); exit; } /* ========================= ✅ ADMIN: Referral Management Callbacks ========================= */ if($data === 'set_referral'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $st = get_ref_settings(); $status = ($st['enabled'] ?? false) ? "✅ فعال" : "❌ غیرفعال"; $reward_inviter = isset($st['reward_inviter']) ? $st['reward_inviter'] : 0; $reward_invitee = isset($st['reward_invitee']) ? $st['reward_invitee'] : 0; $target_invites = isset($st['target_invites']) ? $st['target_invites'] : 0; $cooldown = isset($st['cooldown_minutes']) ? $st['cooldown_minutes'] : 0; $txt = "👥 تنظیمات سیستم زیرمجموعه گیری\n\n" . "وضعیت فعلی: {$status}\n\n" . "💰 هدیه دعوت‌کننده: " . number_format($reward_inviter) . " تومان\n" . "💰 هدیه دعوت‌شونده: " . number_format($reward_invitee) . " تومان\n" . "🎯 تعداد دعوت لازم برای لینک هدیه: " . $target_invites . "\n" . "⏱ محدودیت زمانی (Cooldown): " . $cooldown . " دقیقه\n\n" . "لطفاً یک مورد را برای تغییر انتخاب کنید 👇"; apiRequest('sendMessage',[ 'chat_id'=>$chat_id, 'text'=>$txt, 'parse_mode'=>'HTML', 'reply_markup'=>ik([ [['text'=>'🔁 روشن/خاموش کردن سیستم', 'callback_data'=>'ref_toggle']], [['text'=>'💰 تنظیم مبلغ هدیه نقدی', 'callback_data'=>'ref_set_money']], [['text'=>'🎯 تنظیم تعداد دعوت لازم', 'callback_data'=>'ref_set_target']], [['text'=>'⏱ تنظیم محدودیت زمانی', 'callback_data'=>'ref_set_cooldown']], [['text'=>'🔗 مدیریت لینک‌های هدیه', 'callback_data'=>'ref_manage_links']], [['text'=>'⬅️ بازگشت', 'callback_data'=>'set_back']] ]) ]); answerCallback($callback_id); exit; } if($data === 'ref_toggle'){ if(!isAdmin($user_id)){ answerCallback($callback_id,"⛔️",true); exit; } $ref_st = get_ref_settings(); $ref_st['enabled'] = !($ref_st['enabled'] ?? false); save_ref_settings($ref_st); answerCallback($callback_id, "وضعیت تغییر کرد ✅"); // برای رفرش شدن منو $data = 'set_referral'; } if($data === 'ref_get_gift'){ $st = get_ref_settings(); $links = readJson(REF_LINKS_FILE, []); $data_ref = readJson(REFERRALS_FILE, []); $my_invites = 0; foreach($data_ref as $u => $info) if($info['inviter'] == $user_id) $my_invites++; if($my_invites < ($st['target_invites'] ?? 2)){ answerCallback($callback_id, "❌ شما حداقل {$st['target_invites']} دعوت فعال ندارید.", true); exit; } if(empty($links)){ answerCallback($callback_id, "❌ متأسفانه فعلاً لینک هدیه‌ای موجود نیست.", true); exit; } $cooldown_file = DATA_DIR . '/ref_cooldowns.json'; $cooldowns = readJson($cooldown_file, []); $last_time = isset($cooldowns[$user_id]) ? (int)$cooldowns[$user_id] : 0; $diff = time() - $last_time; $needed_diff = (int)($st['cooldown_minutes'] ?? 0) * 60; if($diff < $needed_diff){ $remain = ceil(($needed_diff - $diff) / 60); answerCallback($callback_id, "⏳ شما به تازگی هدیه دریافت کرده‌اید. لطفا {$remain} دقیقه دیگر تلاش کنید.", true); exit; } $gift = array_shift($links); writeJson(REF_LINKS_FILE, $links); $cooldowns[$user_id] = time(); writeJson($cooldown_file, $cooldowns); apiRequest('sendMessage', [ 'chat_id' => $chat_id, 'text' => "🎁 تبریک! هدیه شما:\n\n{$gift}", 'parse_mode' => 'HTML' ]); answerCallback($callback_id, "✅ هدیه ارسال شد"); exit; } // Unknown callback answerCallback($callback_id, "نامعتبر", false); exit; }