# راهنمای نصب و راه‌اندازی روی هاست اشتراکی واقعی (بر اساس سورس فعلی)

این راهنما دقیقاً بر اساس فایل‌ها و تنظیمات موجود در پروژهٔ فعلی (مراحل ۱ تا ۶) نوشته شده — نه یک آموزش عمومی. هیچ کدی تغییر نمی‌کند.

---

## ۱. پیش‌نیازهای هاست

از پنل هاست (مثلاً cPanel → Select PHP Version) این‌ها را چک/فعال کنید:

- **PHP 7.4** دقیقاً (کد از هیچ Syntax مخصوص PHP 8 استفاده نمی‌کند و تضمینی روی نسخه‌های بالاتر تست نشده).
- **Extensions لازم** (طبق کد واقعی پروژه): `pdo_mysql`، `curl`، `mbstring`، `json` (معمولاً هرکدام یک Checkbox جداگانه در MultiPHP INI Editor هاست است).
- **MySQL یا MariaDB** با امکان ساخت Database و User.
- **HTTPS معتبر** روی دامنه (Let's Encrypt رایگان cPanel کافی است) — الزامی، چون:
  - تلگرام فقط به Webhook با HTTPS متصل می‌شود.
  - درگاه‌های پرداخت به `payment_callback.php` با HTTPS نیاز دارند.
- **دسترسی SSH یا Terminal با اجرای `php` از خط فرمان** — چون `scripts/add_admin.php` فقط از طریق CLI کار می‌کند (پارامترها را از `$argv` می‌خواند، نه از مرورگر). اگر SSH ندارید، بخش ۳ یک راه جایگزین (بدون تغییر کد) توضیح می‌دهد.

---

## ۲. ساخت Database و اجرای Migrationها (ترتیب دقیق)

1. از پنل هاست یک Database و یک User با همهٔ دسترسی‌ها بسازید و به هم متصل کنید.
2. از phpMyAdmin وارد Database شوید و فایل‌های زیر را **دقیقاً به این ترتیب** Import کنید (هرکدام به قبلی وابسته است):

```
database/schema.sql
database/migration_v2.sql
database/migration_v3.sql
database/migration_v4.sql
database/migration_v5.sql
database/migration_v6.sql
```

⚠️ نکتهٔ مستند در خود پروژه: `migration_v2.sql` و `migration_v4.sql` از `ALTER TABLE ... ADD COLUMN IF NOT EXISTS` استفاده می‌کنند که فقط در MariaDB و MySQL ۸.۰.۲۹+ کار می‌کند. اگر phpMyAdmin روی Import این دو فایل خطا داد، نسخهٔ MySQL را با دستور `SELECT VERSION();` چک کنید؛ اگر قدیمی‌تر بود، عبارت `IF NOT EXISTS` را از همان چند خط `ALTER TABLE` در فایل حذف و دوباره Import کنید (این تنها ویرایش دستی مجاز در کل نصب است، چون خودِ فایل صریحاً همین راهنما را در کامنتش دارد).

---

## ۳. آپلود سورس و Document Root

ساختار واقعی پروژه:
```
/app          ← منطق برنامه (خارج از دسترس عمومی باید باشد)
/config       ← config.php
/database     ← فایل‌های sql (بعد از Import دیگر لازم نیستند روی سرور، ولی حذف اجباری نیست)
/public       ← webhook.php + payment_callback.php (تنها دو Endpoint عمومی پروژه)
/scripts      ← add_admin.php + set_webhook.php
.env.example
```

**نکتهٔ حیاتی:** پروژه یک فولدر `public/` مجزا دارد که دقیقاً برای همین طراحی شده — فقط همین فولدر باید در معرض اینترنت باشد.

- اگر هاست شما امکان تنظیم Document Root دلخواه دارد (اغلب VPS-مانند یا cPanel با Subdomain اختصاصی): کل پروژه را در یک مسیر خارج از `public_html` (مثلاً `~/telegram-bot`) آپلود کنید و Document Root دامنه/ساب‌دامین را روی `~/telegram-bot/public` بگذارید.
- اگر هاست شما فقط `public_html` را public می‌کند (اغلب Shared Hosting معمولی): کل پروژه را در یک مسیر بیرون از `public_html` (مثلاً `~/app-source`) آپلود کنید، سپس محتوای `public/` (یعنی `webhook.php` و `payment_callback.php`) را داخل `public_html` قرار دهید و مسیر `require __DIR__ . '/../app/bootstrap.php'` در هر دو فایل را با مسیر واقعی به `app-source/app/bootstrap.php` عوض کنید. **این تغییر مسیر یک ویرایش کد است** — طبق خواستهٔ شما «هیچ کدی تغییر نکند»، توصیهٔ من همان گزینهٔ اول (Document Root اختصاصی روی `public/`) است تا هیچ فایلی دست نخورد؛ اگر هاست شما این امکان را ندارد، دقیقاً همین‌جا به من بگویید تا با آگاهی کامل تصمیم بگیریم.

---

## ۴. تنظیمات ضروری پروژه

### ۴.۱ فایل `.env` (کپی از `.env.example`)
مسیر: کنار پوشهٔ `app/` (یعنی ریشهٔ پروژه، بیرون از `public/`).

| کلید | مقدار |
|---|---|
| `DB_HOST` | معمولاً `localhost` |
| `DB_NAME` | نام Database که ساختید |
| `DB_USER` | یوزر Database |
| `DB_PASS` | پسورد Database |
| `DB_CHARSET` | `utf8mb4` (پیش‌فرض، تغییر ندهید) |
| `BOT_TOKEN` | توکن از @BotFather |
| `WEBHOOK_SECRET` | یک رشتهٔ تصادفی طولانی خودتان بسازید (مثلاً با `openssl rand -hex 32`) |
| `AI_API_KEY` | کلید API سرویس AI (اختیاری؛ اگر خالی بماند، لایهٔ AI به‌جای پاسخ، مستقیم Handoff می‌کند) |
| `APP_TIMEZONE` | `Asia/Tehran` (پیش‌فرض) |
| `APP_DEBUG` | `0` برای Production |

### ۴.۲ Admin ID
پروژه یک فیلد `.env` برای Admin ندارد — ثبت ادمین از طریق دیتابیس/اسکریپت است (بخش بعد).

### ۴.۳ APP/Webhook URL و سایر تنظیمات
اینها در `.env` نیستند، بلکه در جدول `settings` دیتابیس ذخیره می‌شوند و **از داخل پنل ادمین در تلگرام** قابل تنظیم‌اند (نه فایل، نه دیتابیس مستقیم):
- `app_base_url` (برای Callback درگاه پرداخت) — از منوی 💳 پرداخت‌ها
- `admin_contact_username` — فعلاً فقط مستقیماً در دیتابیس قابل تنظیم است (در پنل UI برایش دکمه‌ای تعبیه نشده؛ اگر لازم دارید از phpMyAdmin مقدار `setting_value` ردیف `admin_contact_username` را در جدول `settings` ویرایش کنید)

---

## ۵. ثبت و تست Telegram Webhook

بعد از تکمیل `.env` و آپلود:

```bash
php scripts/set_webhook.php https://yourdomain.com/public/webhook.php
```
(اگر Document Root را روی `public/` گذاشته‌اید، آدرس می‌شود `https://yourdomain.com/webhook.php`)

خروجی موفق: `✅ Webhook با موفقیت ثبت شد`

**تست:** به بات در تلگرام پیام `/start` بدهید. اگر پاسخی نیامد، بخش ۱۱ (خطاهای رایج) را ببینید.

---

## ۶. ثبت اولین Admin

چون هنوز هیچ ادمینی ثبت نشده، ابتدا Telegram User ID خودتان را از @userinfobot بگیرید، سپس:

```bash
php scripts/add_admin.php <telegram_user_id> "نام شما" owner
```

**اگر SSH ندارید** (بدون تغییر کد، فقط SQL دستی در phpMyAdmin):
```sql
INSERT INTO admins (telegram_user_id, name, role, status)
VALUES (<telegram_user_id>, 'نام شما', 'owner', 'active');
```

بعد از این، هر پیامی که همین Telegram ID به بات بفرستد، منوی مدیریت را می‌بیند؛ هر شخص دیگر مشتری عادی است.

---

## ۷. Setup اولیه از داخل پنل Admin

به بات پیام `/start` یا `منو` بدهید تا منوی اصلی باز شود. مسیر دقیق هرکدام:

### 🛍 سرویس‌ها (شامل فرم‌ها و قیمت‌ها)
منو → «🛍 سرویس‌ها» → «➕ افزودن سرویس»:
1. عنوان سرویس
2. توضیح کوتاه (یا `-` برای رد کردن)
3. نوع قیمت‌گذاری: **ثابت (Fixed)** / **محاسباتی (Calculated)** / **بررسی مدیر (Custom)**
4. قیمت پایه (به تومان، یا `-`)
5. **فقط برای Calculated**: یک پیام با فرمت زیر (فیلدهای فرم مشتری + فرمول قیمت با هم):
```
quantity|تعداد بازدید|number
duration_days|مدت اجرا (روز)|number
FORMULA:هزینه بازدید|quantity||500
FORMULA:هزینه مدت|duration_days||100000
```
سرویس بلافاصله فعال می‌شود.

### 🎁 تخفیف‌ها
منو → «🎁 تخفیف‌ها» → «📋 قوانین خودکار» یا «🎟 کدهای تخفیف» → دکمهٔ افزودن. مثال قالب قانون خودکار:
```
name=تخفیف VIP
type=vip
kind=percent
value=10
min_order=
max_cap=500000
vip=1
min_orders=
min_spent=
start=
end=
services=
priority=100
active=1
desc=تخفیف ویژهٔ مشتریان VIP
```
مثال قالب کد تخفیف:
```
code=WELCOME10
kind=percent
value=10
min_order=
max_cap=
start=
end=
usage_limit=100
per_customer=1
services=
priority=50
active=1
desc=کد خوش‌آمدگویی
```

### 👑 VIP
منو → «⚙️ تنظیمات» → «👑 ویرایش معیار VIP» → قالب:
```
min_orders=5
min_spent=0
window_days=0
combine=any
```

### ❓ FAQ
منو → «❓ FAQ» → «➕ افزودن FAQ» → سؤال، سپس پاسخ (دو پیام جدا).

### 📢 کانال‌های نمونه
منو → «📢 کانال‌های نمونه» → «➕ افزودن کانال» → عنوان → یوزرنیم (با `@`) یا لینک → توضیح کوتاه (یا `-`).

### 💳 Payment Settings
منو → «💳 پرداخت‌ها» → «⚙️ تنظیمات پرداخت». جزئیات کامل در بخش ۷ و ۸ زیر.

---

## ۸. راه‌اندازی Sandbox برای اولین تست (IDPay یا Zibal)

از «⚙️ تنظیمات پرداخت» → «✏️ انتخاب/ویرایش درگاه»:

- **IDPay**: دکمهٔ IDPay را بزنید، قالب `api_key=...` و `sandbox=1` را با API Key آزمایشی از پنل IDPay (بخش «آزمایشگاه» را در وب‌سرویس‌شان فعال کنید) پر و ارسال کنید.
- **Zibal**: دکمهٔ Zibal را بزنید، `merchant=zibal` را بفرستید (این مقدار لفظی، حالت تستی رسمی زیبال است — نیاز به ثبت‌نام هم ندارد).

سپس «✏️ فقط ویرایش app_base_url» را بزنید و آدرس پایهٔ سایت را دقیقاً برابر بگذارید (بدون `/` انتهایی):
```
https://yourdomain.com/public
```
یا اگر Document Root را روی `public/` گذاشته‌اید:
```
https://yourdomain.com
```
در پایان «روشن کردن درگاه آنلاین» را بزنید.

---

## ۹. تنظیم Callback و Verify (طبق Integration فعلی)

- کد پروژه به‌صورت خودکار Callback URL می‌سازد: `{app_base_url}/payment_callback.php?pid={payment_id}` — نیازی به وارد کردن دستی این آدرس در جایی از پنل ما نیست.
- **در سمت IDPay** باید خودتان در پنل‌شان (هنگام تعریف وب‌سرویس) «روش بازگشت پس از پرداخت» را روی **GET (Query String)** بگذارید، چون `public/payment_callback.php` فقط `$_GET` را می‌خواند، نه `$_POST`. این تنها تنظیم بیرون از پروژهٔ ماست که باید حتماً انجام دهید.
- **در سمت Zibal** نیازی به این تنظیم نیست؛ Callback همیشه GET است.
- Verify به‌صورت خودکار همان لحظه که کاربر به `payment_callback.php` برمی‌گردد اجرا می‌شود (نیازی به هیچ تنظیم اضافه‌ای نیست).

---

## ۱۰. فعال‌سازی و تست Manual Payment / کارت‌به‌کارت

از «⚙️ تنظیمات پرداخت» → «✏️ ویرایش اطلاعات کارت‌به‌کارت» → قالب:
```
holder=نام صاحب حساب
card=شماره کارت
description=لطفاً مبلغ را دقیقاً واریز کرده و رسید را ارسال کنید.
deadline_hours=24
receipt_guide=لطفاً عکس یا فایل رسید را همین‌جا ارسال کنید.
```
اگر «روشن کردن پرداخت دستی» از قبل فعال نبود، آن را هم بزنید (پیش‌فرض پروژه فعال است).

**تست:** بعد از تأیید قیمت توسط یک اکانت تست مشتری، اگر هم درگاه آنلاین هم دستی فعال باشند، هر دو دکمه «💳 پرداخت آنلاین» و «🏦 کارت‌به‌کارت» نمایش داده می‌شوند. روی کارت‌به‌کارت بزنید، اطلاعات کارت را ببینید، سپس یک عکس (هر عکسی، برای تست) به‌عنوان رسید بفرستید — باید پیام «رسید دریافت شد» بگیرید و در تلگرام ادمین، همان عکس با دکمه‌های «✅ تأیید» / «❌ رد» برسد.

---

## ۱۱. یک تست کامل End-to-End

با دو اکانت تلگرام (یکی ادمین، یکی مشتری تستی):

1. **Customer**: به بات پیام دهید، «🛍 خدمات» → یک سرویس → «📋 ثبت سفارش» → فیلدها را پر کنید → «✅ تأیید و ارسال».
2. بررسی در دیتابیس (اختیاری): `orders.status = pending_admin_review`.
3. **Admin Price**: در تلگرام ادمین، منو → «🧾 سفارش‌ها» → سفارش را باز کنید → «💰 تعیین/تأیید قیمت» → عددی وارد کنید.
4. **Customer Confirmation**: مشتری پیام قیمت را می‌بیند → «✅ تأیید قیمت» بزند.
5. بررسی: یک ردیف در `payments` با `status = awaiting_payment` و `amount` دقیقاً برابر `orders.final_amount` ساخته شده باشد.
6. **Payment**: مشتری «💳 پرداخت آنلاین» بزند → دکمهٔ لینک درگاه دریافت کند.
7. **Callback → Verify**: در محیط Sandbox درگاه، پرداخت را «موفق» انتخاب کنید → به `payment_callback.php` برگردید.
8. صفحه باید «پرداخت موفق» نشان دهد و در تلگرام مشتری پیام تأیید برسد.
9. **Completed**: بررسی نهایی — `payments.status = paid` و `orders.status = completed`.

---

## ۱۲. خطاهای رایج نصب و محل بررسی

| علامت | محل بررسی |
|---|---|
| بات به `/start` پاسخ نمی‌دهد | ۱) `set_webhook.php` را دوباره اجرا کنید و پیام موفقیت را ببینید. ۲) لاگ خطای PHP هاست (معمولاً `error_log` در `public_html` یا مسیر مشخص‌شده در cPanel) را چک کنید — `webhook.php` خطاها را با `error_log()` ثبت می‌کند، نه با نمایش مستقیم. |
| خطای «Configuration error» در مرورگر | فایل `.env` در مسیر درست (کنار `app/`) نیست یا نامش اشتباه است (باید دقیقاً `.env` باشد، نه `.env.txt`). |
| پیام می‌رسد ولی پنل ادمین باز نمی‌شود | Telegram ID شما در جدول `admins` نیست یا `status != 'active'`؛ با phpMyAdmin چک کنید. |
| خطای اتصال دیتابیس | مقادیر `DB_HOST/DB_NAME/DB_USER/DB_PASS` در `.env`؛ در برخی هاست‌ها `DB_HOST` باید IP یا Socket خاص باشد نه `localhost` — از مستندات دیتابیس همان هاست چک کنید. |
| درگاه پرداخت لینک نمی‌دهد | ۱) `app_base_url` تنظیم شده؟ ۲) Credential درگاه (`api_key` یا `merchant`) درست وارد شده؟ ۳) آیا `curl` روی هاست فعال است (بعضی هاست‌های ارزان محدودیت Outbound دارند)؟ |
| بعد از پرداخت، سفارش Completed نمی‌شود | آدرس Callback در پنل IDPay/Zibal باید دقیقاً به `app_base_url` تنظیم‌شدهٔ شما اشاره کند؛ برای IDPay حتماً «روش بازگشت = GET» باشد (بخش ۹). |
| Webhook با خطای ۴۰۳ رد می‌شود | `WEBHOOK_SECRET` در `.env` و مقداری که هنگام `set_webhook.php` ثبت شده باید یکی باشند — این خودکار انجام می‌شود؛ فقط اگر `.env` را بعد از ثبت Webhook عوض کردید، `set_webhook.php` را دوباره اجرا کنید. |

---

## ✅ چک‌لیست کوتاه قبل از Production

- [ ] `APP_DEBUG=0` در `.env`
- [ ] `WEBHOOK_SECRET` یک رشتهٔ واقعاً تصادفی است (نه مقدار نمونه)
- [ ] HTTPS روی دامنه فعال و معتبر است
- [ ] حداقل یک Admin با `role=owner` ثبت شده
- [ ] `app_base_url` دقیقاً با آدرس واقعی HTTPS یکی است
- [ ] Credential درگاه با `sandbox=0` (یا معادلش) و مقدار واقعی جایگزین شده
- [ ] «روش بازگشت» در پنل IDPay روی GET تنظیم شده (اگر از IDPay استفاده می‌کنید)
- [ ] یک تراکنش واقعی کوچک با پول واقعی تست شده
- [ ] اطلاعات کارت‌به‌کارت واقعی (اگر Manual Payment فعال است) ثبت شده
- [ ] `admin_contact_username` در دیتابیس تنظیم شده

---

### از اینجا شروع کن

**اولین قدم عملی:** وارد پنل هاست خود شوید و بررسی کنید کدام نسخهٔ PHP فعال است (باید ۷.۴ باشد) — از مسیر cPanel → **Select PHP Version** (یا **MultiPHP Manager**). اگر ۷.۴ در لیست نبود یا فعال نبود، همین‌جا آن را روی دامنه/ساب‌دامین موردنظرتان تنظیم کنید و نتیجه را به من بگویید تا قدم بعد (ساخت Database) را با خیال راحت جلو ببریم.
