# گزارش نهایی — اتصال خودکار Telegram Stars به Fragment (NAVIRA / mirzabot)

## ۱. فایل‌های تغییرکرده (در مخزن اصلی `mirzabot-main`)

| فایل | تغییر |
|---|---|
| `index.php` | دو خط `require_once` برای `services/FragmentStarsService.php` و `services/StarsOrderService.php` اضافه شد (بعد از `virtual_services.php`، قبل از `virtual_services_admin.php`) |
| `virtual_services.php` | فقط شاخه‌ی `vsconfirm_stars` (تأیید نهایی خرید استارز) تغییر کرد: به‌جای `vsFinalizePurchase(...)` عمومی، حالا `vsFinalizeStarsPurchase(...)` جدید صدا زده می‌شود. **هیچ خط دیگری از این فایل دست نخورده** — Premium/Gift از همان مسیر قبلی رد می‌شوند. |
| `virtual_services_admin.php` | ۱) یک دکمه‌ی `⭐ Stars` به کیبورد پنل خدمات مجازی اضافه شد. ۲) در `vsAdminShouldHandle()` مسیریابی برای دکمه و step های جدید اضافه شد. ۳) در ابتدای `vsAdminDispatch()` یک delegate به `vsStarsAdminDispatch()` اضافه شد. بقیه‌ی فایل (تنظیمات Premium/Gift/رنگ/آیکون و...) دست‌نخورده است. |

## ۲. فایل‌های جدید

### PHP (کنار پروژه‌ی اصلی، در `mirzabot-main/`)
- `services/EnvLoader.php` — پارسر سبک `.env.fragment` (بدون composer package جدید)
- `services/FragmentStarsService.php` — تنها لایه‌ای که با سرویس Node صحبت می‌کند (HTTP + shared secret)
- `services/StarsOrderService.php` — کل چرخه‌ی سفارش: ثبت، قفل/Idempotency، پردازش Auto/Manual، پنل ادمین Stars
- `.env.fragment.example` — نمونه‌ی فایل تنظیمات (باید کپی و پر شود؛ **کپی واقعی (`.env.fragment`) هرگز commit نشود**)
- `migrations/2026_09_04_create_stars_orders.sql` — مستندسازی/اجرای دستی جدول (خودِ سرویس هم با `CREATE TABLE IF NOT EXISTS` آن را می‌سازد)
- `.gitignore.additions` — خطوطی که باید به `.gitignore` پروژه اضافه شود (پروژه از قبل `.gitignore` نداشت)

### Node.js — پوشه‌ی کاملاً جدید `fragment-service/`
- `server.js` — Express API داخلی (`/health`, `/session/test`, `/stars/buy`)
- `fragment-client.js` — لایه‌ی نازک روی SDK فرگمنت
- `wallet-service.js` — signing/validation/broadcast تراکنش TON با کیف‌پول عملیاتی
- `logger.js` — لاگر با redact خودکار مقادیر حساس
- `vendor/fragment-tg-src/` — **سورس دقیق و بررسی‌شده‌ی `fragment-tg`** (کپی مستقیم از فایلی که شما دادید)
- `package.json`, `.env.example`, `README.md`

## ۳. چرا سورس `fragment-tg` را vendor کردیم نه از npm نصب کردیم

هنگام `npm install` مشخص شد پکیج منتشرشده روی npm registry به نام `fragment-tg`:
- نسخه‌اش `1.0.0` است، نه `1.0.1` که در `package.json` سورس شما بود
- ناشرش `usoftware` است و homepage آن `n0/fragment-sdk` را نشان می‌دهد — نه لزوماً همان مخزنی که شما به‌عنوان مرجع دادید (`n0/fragment-tg`)

طبق دستور شما («سورس نصب‌شده را ملاک قرار بده»، «endpoint یا متد خیالی استفاده نکن»)، به‌جای ریسک supply-chain (نصب کد ناشناس از یک ناشر متفاوت)، **دقیقاً همان سورسی که خودتان بررسی و ارائه کردید** را مستقیم در `fragment-service/vendor/fragment-tg-src/` کپی کردیم و از آن import می‌شود. هیچ متد یا endpoint فرضی اضافه نشده؛ فقط از متدهای واقعی سورس استفاده شده:
`fragment.buyStars()` → `stars.buy()` → `searchStarsRecipient` → `initBuyStarsRequest` → `getBuyStarsLink` → `fragment.confirmPayment()`.

## ۴. جدول دیتابیس

جدول جدید و مستقل `stars_orders` (طبق تأیید شما، بدون دست‌کاری `virtual_orders`). ستون‌های کلیدی: `order_id, telegram_user_id, recipient, stars_amount, price, payment_status, delivery_status, delivery_mode, fragment_req_id, fragment_transaction_id, error_message, locked_at, created_at, completed_at`.

Migration به‌صورت **خودکار** در اولین اجرا انجام می‌شود (مثل الگوی خودِ پروژه با `vsEnsureTables`)؛ فایل SQL هم برای اجرای دستی/مستندسازی موجود است.

تنظیم `stars_delivery_mode` (`auto`|`manual`، پیش‌فرض `auto`) در همان جدول `virtual_settings` موجود ذخیره می‌شود (بدون تغییر schema آن).

## ۵. متغیرهای لازم در `.env`

### `mirzabot-main/.env.fragment` (جدید بسازید؛ از `.env.fragment.example` کپی کنید)
```
FRAGMENT_SERVICE_URL=http://127.0.0.1:8787
FRAGMENT_SERVICE_SHARED_SECRET=<همان مقدار fragment-service/.env>
FRAGMENT_SERVICE_TIMEOUT=25
```

### `fragment-service/.env` (جدید بسازید؛ از `.env.example` کپی کنید)
```
FRAGMENT_STEL_DT, FRAGMENT_STEL_SSID, FRAGMENT_STEL_TOKEN, FRAGMENT_STEL_TON_TOKEN   → کوکی‌های Fragment
TONCONNECT_ACCOUNT, TONCONNECT_DEVICE                                                → هویت TonConnect (JSON string)
OPERATIONAL_WALLET_MNEMONIC, OPERATIONAL_WALLET_VERSION, OPERATIONAL_WALLET_WORKCHAIN → کیف‌پول عملیاتی (نه اصلی!)
TON_RPC_ENDPOINT, TON_RPC_API_KEY                                                     → دسترسی شبکه TON
MAX_STARS_PER_ORDER, MAX_TON_PER_TRANSACTION                                          → سقف‌های امنیتی (دفاع لایه‌ی دوم؛ سقف اصلی از پنل PHP کنترل می‌شود)
SERVICE_SHARED_SECRET                                                                 → باید دقیقاً با مقدار بالا یکی باشد
PORT, BIND_HOST                                                                       → پیش‌فرض 127.0.0.1:8787
```

هیچ‌کدام از این مقادیر در دیتابیس، Git، یا لاگ ذخیره نمی‌شوند.

## ۶. نحوه اجرای سرویس Fragment

```bash
cd fragment-service
npm install
cp .env.example .env      # و مقداردهی واقعی
node server.js            # تست دستی
```

برای Production (پیشنهادی):
```bash
npm install -g pm2
pm2 start server.js --name fragment-service
pm2 save && pm2 startup
```

**اگر هاست فعلی PHP شما Node.js/SSH ندارد**: این سرویس باید روی یک VPS جدا (حتی کوچک) اجرا شود چون یک پروسه‌ی دائمی است، نه یک اسکریپت CGI. در این حالت فقط `FRAGMENT_SERVICE_URL` در `.env.fragment` سمت PHP را به آدرس آن VPS (پشت فایروال/فقط IP سرور PHP مجاز) تغییر دهید. Cron/Worker جداگانه‌ای لازم نیست — هر سفارش synchronous از PHP به Node فراخوانی می‌شود.

## ۷. نحوه تغییر Auto/Manual از پنل

`پنل ادمین → 🎛 پنل خدمات مجازی → ⭐ Stars → 🤖 ارسال خودکار / 👤 ارسال دستی`

کلیک روی هرکدام بلافاصله `stars_delivery_mode` را عوض می‌کند؛ فقط روی سفارش‌های **جدید** اثر دارد (سفارش‌های `processing`/`completed` موجود دست‌نخورده می‌مانند چون `delivery_mode` در لحظه‌ی ثبت هر سفارش، در همان رکورد ذخیره شده).

## ۸. نحوه تست اتصال Fragment

همان صفحه → `🔌 تست اتصال Fragment`. این دکمه فقط `fragment.isSessionValid()` (متد غیرمالی SDK) و وضعیت/موجودی کیف‌پول را چک می‌کند — **هیچ خرید یا تراکنشی ایجاد نمی‌کند**.

## ۹. نحوه تست سفارش

1. حالت را روی `manual` بگذارید.
2. یک خرید کوچک استارز از داخل ربات انجام دهید.
3. سفارش در `⭐ Stars → 👤 سفارش‌های در انتظار دستی` ظاهر می‌شود.
4. قبل از زدن «⭐ تکمیل سفارش» با موجودی واقعی، حتماً مرحله‌ی ۹ از دستور شما را انجام دهید: با یک تراکنش با مبلغ خیلی کم TON، صحت `stars.buy()` → دریافت transaction → صحت amount/destination → signing → `confirmPayment()` را روی محیط تست verify کنید.
5. بعد از اطمینان، «⭐ تکمیل سفارش» را بزنید یا حالت را `auto` کنید.

## ۱۰. محدودیت‌ها و ریسک‌های باقی‌مانده (مهم)

1. **`fragment-tg` رسمی نیست.** بر پایه‌ی کوکی سشن کار می‌کند؛ اگر Fragment صفحه/جریان لاگین را عوض کند، کوکی‌ها منقضی می‌شوند و باید دستی تمدید شوند (تست اتصال همین را نشان می‌دهد).
2. **ریسک باقی‌مانده در Retry نادر:** اگر ارتباط HTTP بین PHP و سرویس Node درست *بعد از* broadcast موفق تراکنش TON ولی *قبل از* برگشت پاسخ به PHP قطع شود (timeout شبکه)، سفارش در PHP همچنان `processing`/`failed` می‌ماند بدون `fragment_transaction_id` ثبت‌شده، و یک Retry دستی می‌تواند نظری به خرید دوباره منجر شود. برای همین Retry **عمداً** به کلیک دستی ادمین محدود شده (نه خودکار) تا یک انسان قبل از تلاش مجدد وضعیت را بررسی کند. اگر بخواهید ریسک را کاملاً صفر کنید، پیشنهاد من افزودن یک store پایدار سمت Node (مثلاً یک فایل/SQLite کوچک نگاشت `orderId → txHash`) است که می‌توانم در گام بعدی اضافه کنم.
3. **آدرس مقصد Fragment در سورس مشخص نیست** — چون خودِ Fragment در پاسخ `buyStars()` مقصد را برمی‌گرداند، امکان hardcode/whitelist کردن یک آدرس ثابت وجود ندارد. اعتبارسنجی فعلی روی «سقف مبلغ» (`MAX_TON_PER_TRANSACTION`) و فرمت معتبر آدرس تمرکز دارد، نه تطبیق با آدرس از پیش‌شناخته‌شده.
4. کتابخانه‌های TON (`@ton/ton`, `@ton/core`, `@ton/crypto`) نسخه‌های فعلی npm هستند — طبق دستور شما (بخش ۹)، قبل از هر تراکنش واقعی باید سازگاری signing با نسخه‌ی نصب‌شده در محیط شما verify شود؛ من signing/validation را با داده‌ی آزمایشی تست کردم (نه با حساب/کیف‌پول واقعی).
5. تست‌های سناریوهای ۱ تا ۱۹ که خواستید: سناریوهای منطقی (Idempotency، قفل، Auto↔Manual، عدم پردازش سفارش `completed`) در سطح کد و با شبیه‌سازی دستی بررسی و تأیید شد؛ سناریوهایی که نیاز به حساب Fragment/کیف‌پول واقعی دارند (Authentication Error واقعی، Confirmation Error واقعی، قطعی واقعی Fragment) را فقط می‌توان با محیط تست واقعی شما (طبق بند ۹) نهایی کرد.

## ۱۱. خلاصه‌ی رعایت الزامات شما

- ✅ API رسمی معرفی نشده، هیچ endpoint حدسی ساخته نشده
- ✅ Premium/Gift/VPN دست‌نخورده
- ✅ `stars_delivery_mode` تک‌مقداری، پیش‌فرض auto، تغییر فقط روی سفارش جدید اثر دارد
- ✅ Secrets فقط در `.env` (دو فایل جدا، هیچ‌کدام در DB/Git/لاگ)
- ✅ کیف‌پول عملیاتی جدا از کیف‌پول اصلی + سقف TON/Stars قبل از signing
- ✅ دکمه‌ی تست اتصال هیچ تراکنش مالی ایجاد نمی‌کند
- ✅ قفل ردیف دیتابیس (`SELECT ... FOR UPDATE`) + چک `fragment_transaction_id` قبل از هر خرید جدید
