# Subscription API مدیریت پنل‌های اشتراکی (Free / Basic / Professional). --- ## GET /api/v1/subscription/plans لیست پنل‌ها با دوره‌های فعال (عمومی — بدون auth). **Response 200:** ```json { "success": true, "data": [ { "uuid": "...", "name": "free", "level": 0, "max_secretaries": 1, "features": { "patient_records": false, "services": false, "sms_panel": false }, "active": true, "periods": [] }, { "uuid": "...", "name": "basic", "level": 1, "max_secretaries": 3, "features": { "patient_records": true, "services": true, "sms_panel": false }, "active": true, "periods": [ { "uuid": "...", "plan_uuid": "...", "label": "یک ماهه", "duration_months": 1, "price_rials": 290000, "is_trial": false, "active": true, "sort_order": 1 } ] } ] } ``` --- ## GET /api/v1/subscription/my اشتراک فعال کاربر جاری. **Permission:** `IS_AUTHENTICATED_FULLY` **نکته:** از نسخه فعلی، این endpoint برای `ROLE_SECRETARY` نیز کار می‌کند. منشی از طریق `UserActiveContextRepository` به `db_uuid` entity مربوطه (doctor یا clinic) دسترسی پیدا می‌کند و اشتراک همان entity برگردانده می‌شود. **Response 200:** ```json { "success": true, "data": { "subscription": { "uuid": "...", "plan": { "name": "basic", "level": 1, "max_secretaries": 3, "features": {...} }, "period": { "label": "یک ماهه", "duration_months": 1, "price_rials": 290000 }, "is_trial": false, "starts_at": 1718000000, "expires_at": 1720678400, "days_remaining": 30, "is_active": true }, "used_trial": false } } ``` اگر اشتراک فعالی نداشت `subscription` برابر `null` است. --- ## POST /api/v1/subscription/trial فعال‌سازی تریال رایگان (یکبار برای هر entity). **Permission:** `IS_AUTHENTICATED_FULLY` **Response 201:** همان ساختار ClinicSubscription **Errors:** | Code | HTTP | توضیح | |------|------|-------| | ERR_TRIAL_ALREADY_USED | 422 | قبلاً از تریال استفاده شده | | ERR_TRIAL_DISABLED | 422 | تریال غیرفعال است (SiteConfig: trial_enabled=0) | | ERR_FORBIDDEN_001 | 403 | پروفایل doctor/clinic یافت نشد | --- ## POST /api/v1/subscription-payment شروع پرداخت اشتراک. **Permission:** `IS_AUTHENTICATED_FULLY` **Request Body:** ```json { "gateway": "mellat", "amount_rials": 290000, "period_uuid": "uuid-of-subscription-period", "frontend_address": "https://example.com/payment-result" } ``` | فیلد | نوع | الزامی | |------|-----|--------| | gateway | string (mellat\|sep) | ✅ | | amount_rials | integer | ✅ | | period_uuid | string (UUID) | ✅ | | frontend_address | string (URL) | ❌ | **Response 200:** ```json { "success": true, "data": { "payment_uuid": "...", "redirect_url": "https://gateway.shaparak.ir/...", "order_id": "ORD-XXXXXXXXXXXXXXXX" } } ``` --- ## GET /api/v1/subscription-payment/callback/{gateway} callback درگاه پرداخت — پس از پرداخت موفق، `ClinicSubscription` به صورت خودکار ایجاد می‌شود (بر اساس `period_uuid` ذخیره‌شده در metadata پرداخت). --- ## Admin Endpoints ### GET /api/v1/admin/subscription/plans **Permission:** `ROLE_ADMIN` — لیست همه پنل‌ها ### POST /api/v1/admin/subscription/plan **Permission:** `ROLE_ADMIN` ```json { "name": "enterprise", "level": 3, "max_secretaries": 20, "features": { "patient_records": true, "services": true, "sms_panel": true } } ``` ### PATCH /api/v1/admin/subscription/plan/{uuid} **Permission:** `ROLE_ADMIN` — ویرایش پنل (همه فیلدها اختیاری) ### POST /api/v1/admin/subscription/period **Permission:** `ROLE_ADMIN` ```json { "plan_uuid": "...", "label": "شش ماهه", "duration_months": 6, "price_rials": 1500000, "is_trial": false, "sort_order": 2 } ``` ### PATCH /api/v1/admin/subscription/period/{uuid} **Permission:** `ROLE_ADMIN` — ویرایش دوره ### DELETE /api/v1/admin/subscription/period/{uuid} **Permission:** `ROLE_ADMIN` — غیرفعال کردن دوره (soft delete: `active=false`) ### GET /api/v1/admin/subscription/report **Permission:** `ROLE_ADMIN` Query params: `page`, `limit` ```json { "success": true, "data": [ { "uuid": "...", "entity_type": "clinic", "entity_id": 5, "is_trial": false, "starts_at": 1718000000, "expires_at": 1720678400, "plan_name": "basic", "plan_level": 1 } ], "meta": { "totalRecords": 50, "totalPages": 3, "currentPage": 1 } } ``` --- ## Error Codes | Code | HTTP | توضیح | |------|------|-------| | ERR_SUBSCRIPTION_REQUIRED | 403 | قابلیت نیاز به پنل Basic+ دارد | | ERR_TRIAL_ALREADY_USED | 422 | تریال قبلاً استفاده شده | | ERR_TRIAL_DISABLED | 422 | تریال غیرفعال است | | ERR_SUBSCRIPTION_NOT_FOUND | 404 | پنل یافت نشد |