تمدید خودکار اشتراک
| فیلد | مقدار |
|------|--------|
| **نسخه** | 1.12 |
| **آخرین بروزرسانی** | 2026-09-27 |
| **مخاطب** | ادمین |
عملکرد
دستور `billing:process-subscription-renewals` (کرون روزانه ۰۶:۰۰). سرویس **ساعتی** از این فاکتور خارج است و فقط با `billing:process-hourly` از کیف پول تمدید میشود.
- موعد = `next_billing_at` منهای روزهای قبل از سررسید. عدد از دسته خوانده میشود و اگر دستهٔ بالاتر برای همین فیلد مقدار داشته باشد، همان اولویت دارد. دسته باید «تمدید خودکار» باشد
- افزونههای فرزند جداگانه فاکتور نمیشوند (داخل فاکتور والد میآیند)
- خط اصلی = قیمت محصول + گزینههای قابل تنظیم روی محصول
- خطوط جدا برای هر افزونهٔ دورهای فعال (با گزینههای خودش)
- مجموع = محصول + گزینه + افزونه (همان منطق `RenewalPricingService::breakdownForOffering`)
- پس از صدور، `unit_price` والد = محصول+گزینه؛ `unit_price` هر افزونه هم بهروز میشود (نمایش پورتال دوبارهحساب نمیکند)
تمدید دستی (پورتال / ریسلر)
همان جمع:
| جزء | منبع |
|-----|------|
| محصول | `ProductCyclePricingService` (با تبدیل IRR برای USD) |
| گزینههای محصول | `priceForSelections` (IRR) |
| افزونههای فعال | `AddonOrderBuilder::buildRenewalAddonItems` — خطوط جدا در سفارش |
بعد از پرداخت، `unit_price` والد فقط محصول+گزینهٔ والد ذخیره میشود؛ قیمت افزونهها روی اشتراک فرزند میماند.
تنظیمات اصلی (tenant)
**تنظیمات → تنظیمات اصلی → تمدید خودکار اشتراک**
| فیلد | کلید | پیشفرض |
|------|------|---------|
| پرداخت خودکار فاکتور تمدید از کیف پول مشتری | `renewal_auto_pay_from_wallet` | خاموش |
همگامسازی نرخ دلار با قیمت اشتراکهای دلاری: تب **تنظیمات مالی** — [tax-settings.md](./tax-settings.md). با آپدیت نرخ، نسبت روی `unit_price` (که شامل گزینههای ذخیرهشده است) اعمال میشود؛ افزونهها اشتراک جدا دارند و جدا مقیاس میشوند.
دسته محصول
در تب **مالیات و پرداخت**، فقط وقتی نحوه تمدید در تب اطلاعات دسته «تمدید خودکار» باشد:
| فیلد | پیشفرض | اثر |
|------|---------|-----|
| فاکتور تمدید خودکار — چند روز قبل از اتمام سرویس | ۰ | ۰ = همان روز `next_billing_at`. اگر تمدید خودکار نباشد فیلد بسته است و خالی ذخیره میشود |
پرداخت فاکتور تمدید وقتی سرویس معلق است آن را روشن میکند. اگر تاریخ اتمام هنوز نرسیده باشد، دوره از همان تاریخ جلو میرود.
صف اعمال (`provisioning_queue` / action=`renew`)
بعد از پرداخت فاکتور تمدید کرون:
پیشفرض ماژولها: بدون API تمدید. نمونه با API: NetBill.
UI ادمین
سرویس از **سفارشها → مشاهده** دیده میشود. تمدید خودکار روی مدل `subscriptions.auto_renew` است (دسته با `renewal_mode=automatic` روی اشتراک جدید `auto_renew=true` میگذارد).
پنل مشتری / ریسلر (تمدید دستی)
Cron
```bash
0 6 * * * cd /home/bsshostkhaneh/bss && /usr/local/bin/ea-php83 artisan billing:process-subscription-renewals
* * * * * cd /home/bsshostkhaneh/bss && /usr/local/bin/ea-php83 artisan schedule:run
```
(`schedule:run` صف `provisioning:process-queue` را هم هر دقیقه اجرا میکند.)
تست
```bash
php artisan billing:process-subscription-renewals
php artisan provisioning:process-queue
```