--- ## 📄 فایل ۲: `04_Laravel/README.md` (پوشه لاراول) ```markdown # 🚀 IFNEX Laravel Backend > هسته مرکزی سیستم مدیریت لجستیک ایف‌نکس | مورد | توضیحات | | :--- | :--- | | **نسخه لاراول** | Laravel 11.x | | **نسخه PHP** | PHP 8.2+ | | **پنل ادمین** | Filament 3.3.x | | **دیتابیس** | MySQL 8+ | | **تاریخ آخرین به‌روزرسانی** | 2026-08-10 | --- ## 📋 فهرست مطالب 1. [پیش‌نیازها](#پیشنیازها) 2. [نصب و راه‌اندازی](#نصب-و-راهاندازی) 3. [ساختار پوشه‌ها](#ساختار-پوشهها) 4. [API Endpoints](#api-endpoints) 5. [Artisan Commands](#artisan-commands) 6. [تست‌ها](#تستها) 7. [پیکربندی](#پیکربندی) 8. [نکات امنیتی](#نکات-امنیتی) --- ## پیش‌نیازها قبل از شروع، مطمئن شوید که موارد زیر روی سیستم شما نصب هستند: | ابزار | نسخه حداقل | نصب | |-------|-----------|-----| | PHP | 8.2+ | [دانلود](https://www.php.net/downloads) | | Composer | 2.x | [دانلود](https://getcomposer.org/) | | MySQL | 8+ | [دانلود](https://dev.mysql.com/downloads/) | | Node.js & NPM | 18+ | [دانلود](https://nodejs.org/) (اختیاری - برای WordPress tools) | | XAMPP/WAMP | آخرین نسخه | [دانلود](https://www.apachefriends.org/) (پیشنهادی برای Windows) | --- ## نصب و راه‌اندازی ### ۱. کلون مخزن و ورود به پوشه لاراول ```bash # کلون مخزن git clone https://www.git.vernahost.ir/gitmodir110/ifnex.git # ورود به پوشه لاراول cd ifnex/04_Laravel ۲. نصب پکیج‌های Composer composer install ۳. کپی فایل محیط و تنظیم دیتابیس # کپی فایل محیط cp .env.example .env # ویرایش فایل .env و تنظیم اطلاعات دیتابیس nano .env # یا هر ویرایشگر دلخواه تنظیمات مهم در فایل .env: # دیتابیس DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=ifnex_db DB_USERNAME=root DB_PASSWORD= # API Key برای ترکینگ IFNEX_API_KEY=ifnex-local-dev-key # CORS - فقط دامنه وردپرس CORS_ALLOWED_ORIGINS=http://localhost:8080 # Rate Limiting IFNEX_TRACKING_RATE_LIMIT=60 # Currency API (برای فاز ۲) CURRENCY_API_KEY=your_api_key_here ۴. تولید کلید اپلیکیشن php artisan key:generate ۵. ایجاد دیتابیس # ورود به MySQL mysql -u root -p # ایجاد دیتابیس CREATE DATABASE ifnex_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; EXIT; ۶. اجرای Migration ها php artisan migrate --force ۷. درج داده‌های اولیه (Seeders) # این دستور ۲۳۳ کشور + تنظیمات اولیه + کاربر ادمین را ایجاد می‌کند php artisan db:seed --force اطلاعات ورود پیش‌فرض به پنل ادمین: URL: http://localhost:8000/admin Email: admin@ifnex.local Password: password (در Seeder تنظیم شده) ۸. اجرای سرور توسعه php artisan serve اکنون پروژه در http://localhost:8000 قابل دسترسی است. ساختار پوشه‌ها 04_Laravel/ ├── app/ │ ├── Models/ # مدل‌های Eloquent │ │ ├── Country.php # کشورها با ۴ زون │ │ ├── Shipment.php # مرسولات │ │ ├── ShipmentItem.php # اقلام گمرکی (۹ ردیف) │ │ ├── ShippingRate.php # تعرفه‌های حمل │ │ ├── ShipmentCarrierMapping.php # نگاشت کدهای ترکینگ │ │ ├── ShipmentTrackingEvent.php # رویدادهای ترکینگ │ │ ├── SystemSetting.php # تنظیمات سیستم │ │ └── User.php # کاربران │ │ │ ├── Enums/ # Enum ها │ │ ├── ShipmentDirection.php # import/export │ │ ├── ShipmentType.php # DOC_NORMAL/DOC_ECONOMY/PARCEL │ │ ├── ShipmentStatus.php # ۹ وضعیت مرسوله │ │ ├── CarrierCode.php # ۹ شرکت حمل │ │ ├── TrackingSource.php # ۵ منبع (manual, api, import, system, customer) │ │ ├── TransactionType.php │ │ ├── TransactionStatus.php │ │ ├── PaymentGateway.php # ۴ درگاه (zarinpal, wallet, manual, system) │ │ └── UserRole.php │ │ │ ├── Services/ # لایه سرویس (Business Logic) │ │ ├── PriceCalculatorService.php │ │ ├── TrackingService.php │ │ ├── ExchangeRateService.php │ │ ├── ZarinpalService.php │ │ ├── MockZarinpalService.php │ │ └── OrderPaymentService.php │ │ │ ├── Http/ │ │ ├── Controllers/ │ │ │ ├── Api/ │ │ │ │ ├── TrackController.php │ │ │ │ ├── PricingController.php │ │ │ │ ├── AuthController.php # ورود/خروج Sanctum │ │ │ │ ├── BridgeAuthController.php # لاگین از پلاگین وردپرس │ │ │ │ ├── WalletController.php │ │ │ │ ├── PaymentController.php │ │ │ │ ├── DiscountCodeController.php │ │ │ │ └── Customer/ │ │ │ │ └── CustomerOrderController.php # ۶ endpoint سفارش مشتری │ │ │ ├── OrderController.php │ │ │ ├── PricingPageController.php │ │ │ └── ShipmentPdfController.php │ │ ├── Middleware/ │ │ │ └── ApiKeyMiddleware.php │ │ └── Requests/ │ │ │ ├── Imports/ # Excel Imports │ │ ├── ShippingRatesImport.php # واردات تعرفه‌ها │ │ ├── HistoricalShipmentsImport.php # واردات مرسولات تاریخی │ │ └── RateSheetImport.php # شیت‌های نرخ │ │ │ ├── Console/Commands/ # Artisan Commands │ │ ├── ImportShippingRates.php │ │ ├── ImportHistoricalData.php │ │ ├── UpdateExchangeRates.php │ │ ├── SyncWordPressUsers.php │ │ └── DebugImportCommand.php │ │ │ └── Filament/ # پنل ادمین Filament │ ├── Resources/ │ │ ├── CountryResource.php │ │ ├── ShipmentResource.php │ │ ├── ShippingRateResource.php │ │ ├── ShipmentItemResource.php │ │ ├── WalletResource.php │ │ ├── WalletTransactionResource.php │ │ ├── PaymentResource.php │ │ ├── DiscountCodeResource.php │ │ ├── ExchangeRateHistoryResource.php │ │ ├── RoleResource.php │ │ └── UserResource.php │ ├── Widgets/ │ │ ├── DashboardInfoWidget.php │ │ ├── ExchangeRateWidget.php │ │ ├── WalletStats.php │ │ ├── TransactionChartWidget.php │ │ └── RecentTransactionsWidget.php │ └── Pages/ │ ├── IfnexSettingsPage.php │ ├── PriceTestPage.php │ └── Reports/ │ └── FinancialReport.php │ ├── database/ │ ├── migrations/ # Migration ها │ │ ├── 2026_08_02_000001_create_countries_table.php │ │ ├── 2026_08_02_000002_create_shipments_table.php │ │ ├── 2026_08_02_000003_create_shipping_rates_table.php │ │ ├── 2026_08_02_000004_create_shipment_carrier_mappings_table.php │ │ ├── 2026_08_02_000005_create_shipment_tracking_events_table.php │ │ ├── 2026_08_02_000006_create_system_settings_table.php │ │ ├── 2026_08_02_000007_update_users_table.php │ │ ├── 2026_08_08_000001_create_shipment_items_table.php │ │ ├── 2026_08_05_135026_create_discount_codes_table.php │ │ ├── 2026_08_09_231738_create_exchange_rate_history_table.php │ │ ├── 2026_08_10_080853_add_wallet_to_payment_gateway_enum.php │ │ ├── 2026_08_10_082121_add_system_to_tracking_source_enum.php │ │ ├── 2026_08_09_012526_create_notifications_table.php │ │ └── 2026_08_09_220409_create_permission_tables.php │ └── seeders/ # Seeders │ ├── CountriesTableSeeder.php │ ├── SystemSettingSeeder.php │ ├── DatabaseSeeder.php │ ├── RoleAndPermissionSeeder.php │ └── SampleDataSeeder.php │ ├── routes/ │ ├── web.php # روت‌های وب (فرم‌ها و صفحات) │ └── api.php # روت‌های API │ ├── resources/views/ │ ├── layouts/app.blade.php # لایاوت اصلی │ ├── orders/ # فرم ثبت سفارش │ ├── pricing/ # صفحه استعلام قیمت │ └── pdfs/ # قالب‌های PDF │ ├── config/ │ ├── ifnex.php # تنظیمات اختصاصی IFNEX │ └── cors.php # تنظیمات CORS │ ├── tests/ │ └── Feature/ │ └── Services/ │ └── PriceCalculatorServiceTest.php # ⭐ تست‌های موتور قیمت │ ├── bootstrap/ │ └── app.php # Bootstrap لاراول ۱۱ │ ├── .env.example # نمونه فایل محیط ├── composer.json # وابستگی‌های Composer └── README.md # این فایل API Endpoints 🔓 API های عمومی (نیاز به API Key) ۱. رهگیری مرسوله GET /api/v1/track/{awb_no} Headers: Authorization: Bearer {IFNEX_API_KEY} مثال: curl -H "Authorization: Bearer ifnex-local-dev-key" \ http://localhost:8000/api/v1/track/980100010 پاسخ موفق (200 OK): { "success": true, "data": { "awb_no": "980100010", "status": "delivered", "carrier_mappings": [...], "tracking_events": [...] } } ۲. استعلام قیمت POST /api/v1/calculate Body (JSON): { "direction": "export", "type": "DOC_NORMAL", "country_iso": "US", "weight": 2.5, "volumetric_weight": 3.0, "extra_service": 10.00 } مثال: curl -X POST http://localhost:8000/api/v1/calculate \ -H "Content-Type: application/json" \ -d '{ "direction": "export", "type": "DOC_NORMAL", "country_iso": "US", "weight": 2.5, "volumetric_weight": 3.0 }' پاسخ موفق: { "base_price": 40.00, "net_dirham": 50.00, "net_rial": 22750000, "total_fee": 24906510.9, "zone": 1, "chargeable_weight": 3.0 } 💳 API های کیف پول (فاز ۲) ۱. بررسی موجودی GET /api/v1/wallet/balance ۲. شارژ کیف پول POST /api/v1/wallet/charge Body: { "amount": 1000000, "description": "شارژ اولیه" } ۳. تاریخچه تراکنش‌ها GET /api/v1/wallet/transactions 🎟️ API های تخفیف (فاز ۲) ۱. لیست کدهای تخفیف فعال GET /api/v1/discount-codes/active ۲. اعتبارسنجی کد تخفیف POST /api/v1/discount-codes/validate Body: { "code": "SUMMER20", "amount": 1000000 } 🔐 API های احراز هویت (فاز ۳) ۱. ورود و دریافت توکن Sanctum POST /api/v1/auth/login Body: { "email": "user@example.com", "password": "password", "token_name": "api-token" } ۲. خروج و حذف توکن POST /api/v1/auth/logout Header: Authorization: Bearer {token} 🛒 API های سفارشات مشتری (فاز ۳) ۱. پروفایل و آمار کاربر GET /api/v1/customer/profile ۲. لیست کشورها برای فرم سفارش GET /api/v1/customer/countries ۳. لیست سفارشات کاربر GET /api/v1/customer/orders ۴. ثبت سفارش جدید POST /api/v1/customer/orders Body: { "direction": "export", "type": "PARCEL", "from_country_id": 1, "to_country_id": 2, "weight": 2.5, "sender_name": "نام فرستنده", "sender_phone": "۰۹۱۲۳۴۵۶۷۸۹", "sender_address": "آدرس", "receiver_name": "نام گیرنده", "receiver_phone": "۰۹۱۲۳۴۵۶۷۸۹", "receiver_address": "آدرس", "items": [ { "description": "کالای گمرکی", "hs_code": "8542390001", "quantity": 1, "unit_price": 100 } ] } ۵. جزئیات یک سفارش GET /api/v1/customer/orders/{shipment} ۶. لغو سفارش (فقط pending_payment) POST /api/v1/customer/orders/{shipment}/cancel ۷. پرداخت از کیف پول POST /api/v1/customer/orders/{shipment}/pay-wallet ۸. پرداخت از درگاه بانکی POST /api/v1/customer/orders/{shipment}/pay-gateway Body: { "frontend_callback": "https://your-wordpress.com/order-payment/" } 🔗 API پل وردپرس (فاز ۳) POST /api/v1/bridge/login Body: { "bridge_api_key": "ifnex-bridge-key", "wp_user_id": 1, "wp_user_email": "user@wordpress.local", "wp_user_name": "نام کاربر" } Artisan Commands 📥 واردات داده‌ها ۱. واردات تعرفه‌های حمل از اکسل # واردات عادی php artisan ifnex:import:rates storage/app/public/rates.xlsx # پاک‌سازی و واردات مجدد php artisan ifnex:import:rates storage/app/public/rates.xlsx --clear # تست بدون ذخیره (Dry Run) php artisan ifnex:import:rates storage/app/public/rates.xlsx --dry-run ۲. واردات مرسولات تاریخی php artisan ifnex:import:shipments storage/app/public/historical.xlsx 💱 به‌روزرسانی نرخ ارز (فاز ۲) # به‌روزرسانی دستی php artisan ifnex:update-exchange-rates # تنظیم Cron Job برای به‌روزرسانی روزانه # crontab -e # 0 0 * * * cd /path/to/04_Laravel && php artisan ifnex:update-exchange-rates >> /dev/null 2>&1 🔄 سینک کاربران وردپرس (فاز ۳) # سینک دستی کاربران بین وردپرس و لاراول php artisan ifnex:sync-wp-users 🔑 تولید توکن API (فاز ۲) php artisan ifnex:token --user=admin@ifnex.local --name=api-token 🧪 تست‌ها # اجرای همه تست‌ها php artisan test # اجرای تست‌های یک کلاس خاص php artisan test --filter=PriceCalculatorServiceTest # اجرای تست با نمایش دقیق php artisan test --filter=it_calculates_price_correctly_for_standard_package # گزارش پوشش تست (نیاز به Xdebug) php artisan test --coverage تست‌ها تست‌های موجود ۱. PriceCalculatorServiceTest این تست کلاس PriceCalculatorService را به طور کامل تست می‌کند: php artisan test --filter=PriceCalculatorServiceTest موارد تست شده: ✅ محاسبه صحیح قیمت برای بسته استاندارد ✅ استفاده از وزن حجمی وقتی از وزن واقعی بزرگتر است ✅ اعمال صحیح ضریب سود و VAT ✅ اعمال هزینه‌های جانبی ✅ اعمال کد تخفیف درصدی و ثابت ۲. WalletServiceTest (فاز ۲) تست‌های مربوط به کیف پول و تراکنش‌ها: php artisan test --filter=WalletServiceTest ۳. PaymentControllerTest (فاز ۲) تست‌های مربوط به درگاه پرداخت: php artisan test --filter=PaymentControllerTest ۴. DiscountCodeControllerTest (فاز ۲) تست‌های مربوط به کدهای تخفیف: php artisan test --filter=DiscountCodeControllerTest نوشتن تست جدید برای نوشتن تست جدید، از این الگو استفاده کنید: 'profit_margin', 'value' => 1.0]); SystemSetting::create(['key' => 'aed_to_irr', 'value' => 1.0]); SystemSetting::create(['key' => 'vat_rate', 'value' => 0.0]); SystemSetting::create(['key' => 'packing_cost_default', 'value' => 0]); // 2. ایجاد داده‌های تست $country = Country::factory()->create([...]); ShippingRate::create([...]); // 3. اجرای سرویس $service = app(PriceCalculatorService::class); $result = $service->calculate([...]); // 4. بررسی نتیجه $this->assertEquals(50.00, $result['total_fee']); } } پیکربندی فایل config/ifnex.php return [ // API Key برای احراز هویت 'api_key' => env('IFNEX_API_KEY', 'default-key'), // Rate Limiting 'tracking_rate_limit' => env('IFNEX_TRACKING_RATE_LIMIT', 60), // Currency API 'currency_api_key' => env('CURRENCY_API_KEY'), 'currency_api_url' => env('CURRENCY_API_URL', 'https://api.freecurrencyapi.com/v1/latest'), // Zarinpal Payment Gateway 'zarinpal' => [ 'merchant_id' => env('ZARINPAL_MERCHANT_ID', 'fake-merchant-id-for-testing'), 'sandbox' => env('ZARINPAL_SANDBOX', true), 'callback_url' => env('ZARINPAL_CALLBACK_URL', 'http://localhost:8000/api/v1/payment/callback'), ], // WordPress Bridge 'bridge_api_key' => env('IFNEX_BRIDGE_API_KEY', 'ifnex-bridge-key'), // CORS 'cors_allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', '*')), ]; فایل config/cors.php return [ 'paths' => ['api/*'], 'allowed_methods' => ['*'], 'allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', '*')), 'allowed_headers' => ['*'], 'exposed_headers' => [], 'max_age' => 0, 'supports_credentials' => false, ]; نکات امنیتی 🚫 هرگز این کارها را نکنید هرگز فایل .env را در Git کامیت نکنید # بررسی کنید در .gitignore باشد .env .env.local .env.production هرگز APP_DEBUG=true را در محیط تولید بگذارید # Production APP_DEBUG=false هرگز از CORS * در محیط تولید استفاده نکنید # فقط دامنه وردپرس CORS_ALLOWED_ORIGINS=https://your-wordpress-domain.com هرگز API Key را در کد Hardcode نکنید // ❌ اشتباه $apiKey = 'secret-key-123'; // ✅ درست $apiKey = config('ifnex.api_key'); 🐛 عیب‌یابی مشکل: CHECK constraint failed: direction علت: Factory مقادیر پیش‌فرض اشتباه می‌سازد (مثلاً 'Outbound' به جای 'export') راه‌حل: در تست‌ها از ShippingRate::create() به جای ShippingRate::factory()->create() استفاده کنید: ShippingRate::create([ 'direction' => 'export', // حروف کوچک 'type' => 'DOC_NORMAL', 'weight' => 1.0, 'zone_1' => 20.00, // ... بقیه zone ها ]); مشکل: No rate found for the given parameters علت: Query نمی‌تواند نرخ مناسبی پیدا کند راه‌حل: بررسی کنید که zone_column درست است (zone_1, zone_2, ...) مطمئن شوید که وزن در تست بیشتر از وزن‌های موجود در دیتابیس نیست SystemSetting ها را در تست Mock کنید 📞 پشتیبانی اگر سوالی داشتید که در این فایل یا مستندات 01_Documents پاسخ آن نبود، از کاربر (Kazem) بپرسید — حدس نزنید. © 2026 VernaSoft Group. Internal use only.