================================================================================ 👨‍đŸ’ŧ ADMIN FRONTEND API DOCUMENTATION - HishabPlus Backend ================================================================================ Complete API Reference for Building Admin Dashboard (admin.hishabplus.com) Technology-Agnostic Guide - Use with any frontend framework ================================================================================ 📋 TABLE OF CONTENTS ================================================================================ 1. Base URL & Authentication 2. Request/Response Format 3. Error Handling 4. Middleware & Permissions 5. Admin Authentication Endpoints 6. Dashboard (Admin) 7. User Management 8. Package Management 9. Payment Management 10. SMS Management (Admin) 11. SMS Templates (Admin) 12. Reports & Analytics 13. Settings Management 14. Database Structure Reference ================================================================================ 1ī¸âƒŖ BASE URL & AUTHENTICATION ================================================================================ Base URL: https://api.hishabplus.com/admin/api (Development: http://localhost:8000/admin/api) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Authentication Method: Laravel Sanctum (Bearer Token) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ All protected endpoints require: Header: Authorization: Bearer {admin_token} Token is obtained from: - POST /admin/api/auth/login (returns token) Token Storage: - Store token in localStorage, sessionStorage, or secure cookie - Include in every request header: Authorization: Bearer {token} - Admin tokens are separate from user tokens ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Admin Guard ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - Uses `auth.admin` middleware (custom middleware) - Middleware automatically handles Sanctum token authentication - Validates that the token belongs to an Admin model (not User model) - User tokens cannot access admin endpoints - Token authentication is handled internally by the middleware ================================================================================ 2ī¸âƒŖ REQUEST/RESPONSE FORMAT ================================================================================ Content-Type: application/json Accept: application/json All requests: JSON body All responses: JSON body Same format as user API (see user_frontend_api_guide.txt section 2) ================================================================================ 3ī¸âƒŖ ERROR HANDLING ================================================================================ Same error format as user API (see user_frontend_api_guide.txt section 3) Additional Admin-Specific Errors: - 403: Not an admin user - 403: Insufficient admin permissions (if superadmin checks exist) ================================================================================ 4ī¸âƒŖ MIDDLEWARE & PERMISSIONS ================================================================================ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ EnsureAdminAuthenticated Middleware (auth.admin) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Applied to: All protected admin routes Behavior: - Automatically extracts Bearer token from Authorization header - Validates token using Laravel Sanctum - Checks if token belongs to Admin model (not User model) - If token is missing/invalid → 401 error - If token belongs to User model → 403 error (Unauthorized. Admin access required.) - If token belongs to Admin model → Request proceeds Frontend Action: - On 401: Token expired/invalid - redirect to admin login, clear token - On 403: Not an admin user - redirect to admin login, clear token - Always include: Authorization: Bearer {admin_token} header ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Superadmin Checks ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Some operations may require `is_superadmin = true`: - Deleting packages with active subscriptions - Critical settings changes - System-wide operations Check `admin.is_superadmin` field to show/hide features in UI. ================================================================================ 5ī¸âƒŖ ADMIN AUTHENTICATION ENDPOINTS ================================================================================ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/auth/login ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Admin login Auth Required: NO Request Body: ```json { "email": "admin@hishabplus.com", "password": "admin_password" } ``` Validation Rules: - email: required|email - password: required|string Success Response (200): ```json { "message": "Login successful", "admin": { "id": 1, "name": "Super Admin", "email": "admin@hishabplus.com", "phone": "+8801318388963", "is_superadmin": true, "created_at": "2025-11-01T10:00:00.000000Z" }, "token": "1|admin_token_abcdefghijklmnopqrstuvwxyz" } ``` Error Responses: - 422: Invalid credentials ```json { "message": "The given data was invalid.", "errors": { "email": ["The provided credentials are incorrect."] } } ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/auth/logout ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Admin logout Auth Required: YES Request Body: None Success Response (200): ```json { "message": "Logout successful" } ``` Frontend Action: - Clear admin token - Redirect to admin login ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/auth/me ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Get current authenticated admin Auth Required: YES Success Response (200): ```json { "admin": { "id": 1, "name": "Super Admin", "email": "admin@hishabplus.com", "phone": "+8801234567890", "is_superadmin": true, "created_at": "2025-11-01T10:00:00.000000Z" } } ``` Use Cases: - Check authentication status - Display admin name in header - Check superadmin status for feature visibility ================================================================================ 6ī¸âƒŖ DASHBOARD (ADMIN) ================================================================================ Note: There is no dedicated admin dashboard endpoint. Build dashboard using: - GET /admin/api/users (with stats) - GET /admin/api/payments (with summary) - GET /admin/api/reports/sms-usage - GET /admin/api/reports/revenue Combine these endpoints to build admin dashboard statistics. ================================================================================ 7ī¸âƒŖ USER MANAGEMENT ================================================================================ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/users ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: List all users with filtering Auth Required: YES Query Parameters: - is_active: boolean - Filter by active status - subscription_status: string (trial|grace|active|expired) - Filter by subscription status - search: string - Search in name, email, phone, business_name - per_page: integer (default: 15) - page: integer (default: 1) Success Response (200) - Paginated: ```json { "users": { "data": [ { "id": 1, "name": "John Doe", "email": "john@example.com", "business_name": "John Properties", "phone": "+8801712345678", "is_active": true, "trial_ends_at": "2025-11-24T10:30:00.000000Z", "grace_ends_at": null, "current_subscription_id": 5, "created_at": "2025-11-10T10:30:00.000000Z", "current_subscription": { "id": 5, "package_id": 2, "status": "active", "package": { "id": 2, "name": "Basic", "price": "500.00" } } } ], "current_page": 1, "per_page": 15, "total": 100 }, "stats": { "total_users": 100, "active_users": 85, "trial_users": 10, "paid_users": 75 } } ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/users/{id} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Get user details with statistics Auth Required: YES Success Response (200): ```json { "user": { "id": 1, "name": "John Doe", "email": "john@example.com", "business_name": "John Properties", "phone": "+8801712345678", "is_active": true, "trial_ends_at": null, "grace_ends_at": null, "current_subscription_id": 5, "current_subscription": { "id": 5, "package_id": 2, "status": "active", "package": { "id": 2, "name": "Basic" } }, "properties": [ { "id": 3, "title": "Green Villa", "category": { "id": 1, "name": "House" } } ], "renters": [ { "id": 5, "name": "Ahmed Khan", "is_active": true } ] }, "stats": { "properties": { "total": 15, "by_category": { "House": 10, "Shop": 5 } }, "renters": { "active": 11, "total": 12 }, "transactions": { "total_collected": 500000.00, "total_subscription_payments": 2000.00, "total_sms_purchases": 500.00 }, "sms": { "balance": 45, "total_sent": 150 } }, "recent_activity": [ { "id": 100, "action": "property_created", "ip": "192.168.1.1", "created_at": "2025-11-10T10:30:00.000000Z", "meta": { "property_id": 3 } } ] } ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/users/{id}/adjust-sms ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Adjust user's SMS balance (add or deduct) Auth Required: YES Request Body: ```json { "adjustment": 50, "reason": "Promotional bonus" } ``` Validation Rules: - adjustment: required|integer|not_in:0 - Positive number = add SMS - Negative number = deduct SMS - reason: required|string|max:500 Balance Check: - If adjustment would result in negative balance → 422 error: ```json { "message": "Adjustment would result in negative balance.", "current_balance": 10, "requested_adjustment": -20 } ``` Success Response (200): ```json { "message": "SMS balance adjusted successfully", "previous_balance": 45, "adjustment": 50, "new_balance": 95 } ``` Note: - Creates SmsBalanceHistory entry with source='admin' - Balance is calculated in real-time ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/users/{id}/manual-transaction ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Create manual transaction for user (e.g., offline payment) Auth Required: YES Request Body: ```json { "type": "rent_payment", "amount": 15000, "property_id": 3, "renter_id": 5, "note": "Received via bank transfer" } ``` Validation Rules: - type: required|in:rent_payment,security_deposit,advance_payment,refund,subscription_payment - amount: required|numeric|min:0 - property_id: required_if:type,rent_payment,security_deposit,advance_payment|exists:properties,id - renter_id: required_if:type,rent_payment,security_deposit,advance_payment|exists:renters,id - note: required|string|max:500 Success Response (200): ```json { "message": "Transaction created successfully", "transaction": { "id": 200, "user_id": 1, "renter_id": 5, "property_id": 3, "type": "rent_payment", "amount": "15000.00", "method": "manual", "note": "Received via bank transfer", "created_at": "2025-11-10T10:30:00.000000Z" } } ``` Note: - Property and renter must belong to the user - Transaction method is automatically set to "manual" ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/users/{id}/toggle-status ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Activate or deactivate user account Auth Required: YES Request Body: ```json { "is_active": false, "reason": "Violation of terms of service" } ``` Validation Rules: - is_active: required|boolean - reason: nullable|string|max:500 Success Response (200): ```json { "message": "User status updated successfully", "user": { "id": 1, "is_active": false, ... } } ``` Note: - Creates ActivityLog entry - Deactivated users cannot access the app (403 error) ================================================================================ 8ī¸âƒŖ PACKAGE MANAGEMENT ================================================================================ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/packages ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: List all packages Auth Required: YES Query Parameters: - is_visible: boolean - Filter by visibility - per_page: integer (default: 15) - page: integer (default: 1) Success Response (200) - Paginated: ```json { "data": [ { "id": 1, "name": "Trial", "slug": "trial", "price": "0.00", "billing_period": "monthly", "description": "14-day free trial", "is_visible": true, "created_at": "2025-11-01T10:00:00.000000Z", "package_limits": [ { "id": 1, "property_category": "house", "max_properties": 2, "sms_limit": 10 }, { "id": 2, "property_category": "shop", "max_properties": 1, "sms_limit": 10 } ] } ], "current_page": 1, "per_page": 15, "total": 5 } ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/packages ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Create new package Auth Required: YES Request Body: ```json { "name": "Premium", "slug": "premium", "price": 2000, "billing_period": "monthly", "description": "Premium package with unlimited properties", "is_visible": true, "limits": [ { "property_category": "house", "max_properties": 20, "sms_limit": 500 }, { "property_category": "shop", "max_properties": 15, "sms_limit": 500 }, { "property_category": "other", "max_properties": 10, "sms_limit": 500 } ] } ``` Validation Rules: - name: required|string|max:255 - slug: required|string|unique:packages,slug|max:255 - price: required|numeric|min:0 - billing_period: required|in:monthly,yearly - description: nullable|string - is_visible: boolean - limits: required|array - limits.*.property_category: required|in:house,shop,other - limits.*.max_properties: required|integer|min:0 - limits.*.sms_limit: required|integer|min:0 Success Response (201): ```json { "message": "Package created successfully", "package": { "id": 6, "name": "Premium", "slug": "premium", "price": "2000.00", "billing_period": "monthly", "description": "Premium package with unlimited properties", "is_visible": true, "package_limits": [ { "id": 10, "property_category": "house", "max_properties": 20, "sms_limit": 500 } ], ... } } ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ PUT /admin/api/packages/{id} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Update package Auth Required: YES Request Body (all fields optional): ```json { "name": "Updated Premium", "price": 2500, "description": "Updated description", "is_visible": false, "limits": [ { "property_category": "house", "max_properties": 25, "sms_limit": 600 } ] } ``` Validation Rules: Same as POST (but all optional with "sometimes") Success Response (200): ```json { "message": "Package updated successfully", "package": { ... } } ``` Note: - Updating limits will update existing PackageLimit records - If limit doesn't exist, it will be created ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ DELETE /admin/api/packages/{id} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Delete package Auth Required: YES Error Responses: - 403: Package has active subscriptions ```json { "message": "Cannot delete package with active subscriptions." } ``` Success Response (200): ```json { "message": "Package deleted successfully" } ``` Frontend Action: - Check for active subscriptions before allowing delete - Show warning if package is in use ================================================================================ 9ī¸âƒŖ PAYMENT MANAGEMENT ================================================================================ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/payments ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: List all payments with filtering Auth Required: YES Query Parameters: - status: string (pending|completed|failed|cancelled|refunded) - Filter by status - type: string (subscription|topup|manual|refund) - Filter by type - user_id: integer - Filter by user - date_from: date - Filter from date - date_to: date - Filter to date - per_page: integer (default: 15) - page: integer (default: 1) Success Response (200) - Paginated: ```json { "payments": { "data": [ { "id": 20, "uuid": "550e8400-e29b-41d4-a716-446655440000", "user_id": 1, "package_id": 2, "type": "subscription", "amount": "500.00", "currency": "BDT", "status": "completed", "provider": "sslcommerz", "provider_transaction_id": "SSL123456", "meta": { "gateway_response": { ... } }, "created_at": "2025-11-10T10:30:00.000000Z", "user": { "id": 1, "name": "John Doe", "email": "john@example.com" }, "package": { "id": 2, "name": "Basic" }, "invoice": { "id": 5, "uuid": "invoice-uuid", "status": "paid" } } ], "current_page": 1, "per_page": 15, "total": 200 }, "summary": { "total_payments": 200, "completed_payments": 180, "pending_payments": 10, "failed_payments": 10, "total_revenue": 100000.00, "subscription_revenue": 90000.00, "topup_revenue": 10000.00 } } ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/payments/{id} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Get payment details Auth Required: YES Success Response (200): ```json { "payment": { "id": 20, "uuid": "550e8400-e29b-41d4-a716-446655440000", "user_id": 1, "package_id": 2, "type": "subscription", "amount": "500.00", "currency": "BDT", "status": "completed", "provider": "sslcommerz", "provider_transaction_id": "SSL123456", "meta": { "gateway_response": { "status": "VALID", "tran_id": "SSL123456", "val_id": "1234567890", "amount": "500.00", "store_amount": "490.00", "card_type": "VISA", "card_no": "411111XXXXXX1111", "bank_tran_id": "BANK123456" } }, "created_at": "2025-11-10T10:30:00.000000Z", "user": { "id": 1, "name": "John Doe", "email": "john@example.com" }, "package": { "id": 2, "name": "Basic" }, "invoice": { "id": 5, "uuid": "invoice-uuid", "status": "paid", "pdf_path": "/storage/invoices/invoice-5.pdf" }, "topup": null } } ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/payments/{id}/mark-completed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Manually mark payment as completed (for offline/bank transfers) Auth Required: YES Request Body: ```json { "reference": "BANK_TRANSFER_123456", "note": "Verified bank transfer receipt" } ``` Validation Rules: - reference: nullable|string|max:255 - note: nullable|string|max:500 Error Responses: - 400: Payment already completed ```json { "message": "Payment is already completed." } ``` Success Response (200): ```json { "message": "Payment marked as completed successfully", "payment": { "id": 20, "status": "completed", "provider_transaction_id": "BANK_TRANSFER_123456", ... } } ``` Note: - If payment type is "subscription", activates subscription - If payment type is "topup", applies SMS topup - Creates invoice if applicable - Sends notification to user ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/payments/{id}/refund ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Process refund for payment Auth Required: YES Request Body: ```json { "reason": "Customer requested refund", "amount": 500.00 } ``` Validation Rules: - reason: required|string|max:500 - amount: nullable|numeric|min:0|max:payment.amount - If not provided, refunds full amount Error Responses: - 400: Payment not completed ```json { "message": "Only completed payments can be refunded." } ``` - 400: Already refunded ```json { "message": "Payment is already refunded." } ``` Success Response (200): ```json { "message": "Payment refunded successfully", "payment": { "id": 20, "status": "refunded", "meta": { "refunded_at": "2025-11-10T15:30:00.000000Z", "refund_reason": "Customer requested refund", "refund_amount": 500.00 }, ... } } ``` Note: - Creates refund payment record (type='refund', amount negative) - If subscription payment, cancels subscription - Sends notification to user ================================================================================ 🔟 SMS MANAGEMENT (ADMIN) ================================================================================ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/sms/balance ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Get SMS provider balance and system statistics Auth Required: YES Success Response (200): ```json { "provider_balance": 10000, "error": null, "system_stats": { "total_users_balance": 5000, "total_sent_today": 150, "total_sent_this_month": 5000, "queued_messages": 5 }, "last_checked": "2025-11-10T10:30:00.000000Z" } ``` Error Response (if provider API fails): ```json { "provider_balance": null, "error": "Failed to fetch balance from provider", "system_stats": { ... }, "last_checked": "2025-11-10T10:30:00.000000Z" } ``` Note: - provider_balance: Balance from SMS provider API (may be null if API fails) - system_stats: Calculated from database - total_users_balance: Sum of all users' SMS balances ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/sms/broadcast ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Send broadcast SMS to multiple users Auth Required: YES Request Body: ```json { "recipient_type": "active_subscription", "user_ids": [1, 2, 3], "message": "Important announcement: System maintenance scheduled for tomorrow.", "notification_title": "System Maintenance Notice", "schedule_at": "2025-11-15 10:00:00" } ``` Validation Rules: - recipient_type: required|in:all,active_subscription,trial,specific - user_ids: required_if:recipient_type,specific|array - user_ids.*: exists:users,id - message: required|string|max:1000 - notification_title: required|string|max:255 - schedule_at: nullable|date|after:now Recipient Types: - all: All active users - active_subscription: Users with active paid subscription - trial: Users currently in trial period - specific: Users specified in user_ids array Success Response (200): ```json { "message": "Broadcast SMS initiated", "total_recipients": 50, "success_count": 48, "failed_count": 2, "scheduled_at": null } ``` Error Responses: - 404: No users found ```json { "message": "No users found for the selected criteria." } ``` Note: - Creates SMS message for each user - Creates notification for each user - SMS is sent asynchronously (queued) - Users without phone numbers are skipped (counted as failed) - If schedule_at provided, SMS is scheduled for future ================================================================================ 1ī¸âƒŖ1ī¸âƒŖ SMS TEMPLATES (ADMIN) ================================================================================ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/sms-templates ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: List all SMS templates (user + system defaults) Auth Required: YES Query Parameters: - type: string (rent_reminder|due_notice|trial_expiry|custom) - Filter by type - language: string (bn|en) - Filter by language - is_default: boolean - Filter by default status - per_page: integer (default: 15) - page: integer (default: 1) Success Response (200) - Paginated: ```json { "templates": { "data": [ { "id": 1, "slug": "bn_rent_reminder_default", "title": "Rent Reminder (Bangla)", "type": "rent_reminder", "language": "bn", "body": "āĻĒā§āϰāĻŋāϝāĻŧ {{renter_name}}, ...", "is_default": true, "is_editable": true, "user_id": null, "created_by": 1, "created_at": "2025-11-01T10:00:00.000000Z", "creator": { "id": 1, "name": "Super Admin" }, "user": null }, { "id": 10, "slug": "custom_template_1_1234567890", "title": "User Custom Template", "type": "custom", "language": "en", "body": "Hello {{renter_name}}", "is_default": false, "is_editable": true, "user_id": 5, "created_by": null, "created_at": "2025-11-10T10:00:00.000000Z", "creator": null, "user": { "id": 5, "name": "John Doe" } } ], "current_page": 1, "per_page": 15, "total": 20 }, "stats": { "total": 20, "default": 6, "user_created": 14, "by_language": { "bn": 10, "en": 10 } } } ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ POST /admin/api/sms-templates ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Create SMS template (admin can create system defaults) Auth Required: YES Request Body: ```json { "title": "New System Template", "type": "rent_reminder", "language": "en", "body": "Dear {{renter_name}}, your rent is due.", "slug": "new_system_template", "is_default": true, "is_editable": true } ``` Validation Rules: - title: required|string|max:255 - type: required|in:rent_reminder,due_notice,trial_expiry,custom - language: required|in:bn,en - body: required|string|max:1024 - slug: nullable|string|unique:sms_templates,slug - is_default: boolean - is_editable: boolean Success Response (201): ```json { "message": "Template created successfully", "template": { "id": 25, "title": "New System Template", "type": "rent_reminder", "language": "en", "body": "Dear {{renter_name}}, your rent is due.", "is_default": true, "is_editable": true, "created_by": 1, "creator": { "id": 1, "name": "Super Admin" }, ... } } ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ PUT /admin/api/sms-templates/{id} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Update any SMS template (admin privilege) Auth Required: YES Request Body (all optional): ```json { "title": "Updated Title", "body": "Updated body text", "language": "bn", "type": "due_notice", "is_default": false, "is_editable": true } ``` Validation Rules: Same as POST (but all optional with "sometimes") Success Response (200): ```json { "message": "Template updated successfully", "template": { ... } } ``` Note: - Admin can update any template (user or system) - Can change is_default and is_editable flags ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ DELETE /admin/api/sms-templates/{id} ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Delete SMS template Auth Required: YES Error Responses: - 403: Template is in use ```json { "message": "Cannot delete template that is in use.", "usage_count": 15 } ``` Success Response (200): ```json { "message": "Template deleted successfully" } ``` Note: - Checks if template has been used in SMS messages - If usage_count > 0, deletion is blocked ================================================================================ 1ī¸âƒŖ2ī¸âƒŖ REPORTS & ANALYTICS ================================================================================ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/reports/sms-usage ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: SMS usage report with statistics Auth Required: YES Query Parameters: - date_from: date (default: 1 month ago) - date_to: date (default: today) - group_by: string (day|week|month, default: day) Success Response (200): ```json { "usage_data": [ { "period": "2025-11-01", "message_count": 150, "total_cost": 200, "unique_users": 25 }, { "period": "2025-11-02", "message_count": 180, "total_cost": 250, "unique_users": 30 } ], "top_users": [ { "id": 1, "name": "John Doe", "email": "john@example.com", "sms_sent": 500 }, { "id": 5, "name": "Jane Smith", "email": "jane@example.com", "sms_sent": 300 } ], "status_breakdown": { "sent": 1000, "failed": 10, "queued": 5, "delivered": 950 }, "summary": { "total_messages": 1015, "sent_messages": 1000, "failed_messages": 10, "queued_messages": 5, "total_cost": 1500 }, "date_range": { "from": "2025-11-01", "to": "2025-11-10" } } ``` Use Cases: - Display usage trend chart (line/bar chart) - Show top users table - Display status breakdown (pie chart) - Show summary statistics ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/reports/revenue ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Revenue report with package performance and customer metrics Auth Required: YES Query Parameters: - date_from: date (default: 1 month ago) - date_to: date (default: today) - group_by: string (day|week|month, default: month) Success Response (200): ```json { "revenue_data": [ { "period": "2025-11", "subscription_revenue": 50000.00, "sms_revenue": 5000.00, "total_revenue": 55000.00 } ], "package_performance": [ { "id": 2, "name": "Basic", "price": "500.00", "active_subscriptions": 50, "new_subscriptions": 10, "revenue": 5000.00 }, { "id": 3, "name": "Gold", "price": "1500.00", "active_subscriptions": 20, "new_subscriptions": 5, "revenue": 7500.00 } ], "customer_metrics": { "new_users": 100, "paying_users": 75, "churn_rate": 5.5, "arpu": 733.33 }, "summary": { "total_revenue": 55000.00, "subscription_revenue": 50000.00, "sms_revenue": 5000.00 }, "date_range": { "from": "2025-11-01", "to": "2025-11-10" } } ``` Metrics Explanation: - new_users: Users registered in date range - paying_users: Users who made payment in date range - churn_rate: Percentage of users who cancelled/expired (calculated) - arpu: Average Revenue Per User (total revenue / active paying users) Use Cases: - Display revenue trend chart (stacked area chart) - Show package performance table - Display customer metrics cards - Show summary statistics ================================================================================ 1ī¸âƒŖ3ī¸âƒŖ SETTINGS MANAGEMENT ================================================================================ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ GET /admin/api/settings ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Get all application settings Auth Required: YES Success Response (200): ```json { "settings": { "app_name": { "value": "HishabPlus", "type": "string", "description": "Application name", "sensitive": false }, "sms_provider_url": { "value": "https://api.sms.net.bd/sendsms", "type": "string", "description": "SMS provider API URL", "sensitive": false }, "sms_api_key": { "value": "***hidden***", "type": "string", "description": "SMS provider API key", "sensitive": true }, "sms_price_per_unit": { "value": 0.50, "type": "number", "description": "Price per SMS unit in BDT", "sensitive": false }, "trial_days": { "value": 14, "type": "integer", "description": "Number of trial days for new users", "sensitive": false }, "grace_period_days": { "value": 7, "type": "integer", "description": "Number of grace period days after subscription expires", "sensitive": false }, "maintenance_mode": { "value": false, "type": "boolean", "description": "Enable maintenance mode", "sensitive": false }, "maintenance_message": { "value": "We are currently performing maintenance. Please check back later.", "type": "text", "description": "Maintenance mode message", "sensitive": false }, "support_email": { "value": "support@hishabplus.com", "type": "email", "description": "Support email address", "sensitive": false }, "support_phone": { "value": "+8801234567890", "type": "string", "description": "Support phone number", "sensitive": false } } } ``` Note: - Sensitive fields (like API keys) are hidden in response - Settings are stored in `settings` table (key-value pairs) - Default values come from .env or config files ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ PUT /admin/api/settings ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Description: Update application settings Auth Required: YES Request Body: ```json { "settings": [ { "key": "trial_days", "value": 30 }, { "key": "grace_period_days", "value": 15 }, { "key": "maintenance_mode", "value": true }, { "key": "maintenance_message", "value": "System is under maintenance. We'll be back soon!" } ] } ``` Validation Rules: - settings: required|array - settings.*.key: required|string - settings.*.value: nullable (can be string, number, boolean, null) Success Response (200): ```json { "message": "Settings updated successfully" } ``` Note: - Updates settings in database - Clears settings cache - Changes take effect immediately Frontend Action: - Group settings by category (SMS, Trial, Maintenance, Support) - Show input types based on setting.type (text, number, boolean, textarea) - Mask sensitive fields in UI - Show confirmation dialog for critical settings ================================================================================ 1ī¸âƒŖ4ī¸âƒŖ DATABASE STRUCTURE REFERENCE ================================================================================ This section documents the database fields you'll receive in admin API responses. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Admin Model Fields ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ { "id": integer, "name": string, "email": string (unique), "phone": string|null, "is_superadmin": boolean, "created_at": datetime, "updated_at": datetime } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ User Model Fields (Admin View) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Same as user API (see user_frontend_api_guide.txt section 17) Additional fields in admin context: - All user data is visible - Can see all relationships (properties, renters, transactions, etc.) - Can see activity logs ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Package Model Fields ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ { "id": integer, "name": string, "slug": string (unique), "price": decimal (2 decimal places), "billing_period": enum (monthly|yearly), "description": text|null, "is_visible": boolean, "created_at": datetime, "updated_at": datetime } PackageLimit: { "id": integer, "package_id": integer, "property_category": enum (house|shop|other), "max_properties": integer, "sms_limit": integer } ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Payment Model Fields (Admin View) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Same as user API (see user_frontend_api_guide.txt section 17) Additional in admin view: - Can see all payments (not just own) - Can see full gateway response in meta - Can see invoice and topup relationships ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ SmsTemplate Model Fields (Admin View) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ { "id": integer, "slug": string (unique), "title": string, "type": enum (rent_reminder|due_notice|trial_expiry|custom), "language": string (bn|en), "body": text, "is_default": boolean, "is_editable": boolean, "created_by": integer|null (FK to admins), "user_id": integer|null (FK to users), "created_at": datetime, "updated_at": datetime, "deleted_at": datetime|null } Relationships: - creator: Admin (if created_by is set) - user: User (if user_id is set) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Setting Model Fields ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ { "id": integer, "key": string (unique), "value": longText, "created_at": datetime, "updated_at": datetime } Note: Settings are key-value pairs. Value is stored as text but can represent: - String - Number - Boolean (stored as "true"/"false") - JSON (stored as JSON string) ================================================================================ 📝 IMPORTANT NOTES FOR ADMIN FRONTEND DEVELOPER ================================================================================ 1. Admin Authentication: - Separate from user authentication - Admin tokens cannot access user endpoints - User tokens cannot access admin endpoints 2. Superadmin Privileges: - Check admin.is_superadmin to show/hide features - Some operations may require superadmin (backend enforces) 3. User Management: - Can view all users and their data - Can adjust SMS balance (add/deduct) - Can create manual transactions - Can activate/deactivate users 4. Payment Management: - Can view all payments - Can manually mark payments as completed (for offline payments) - Can process refunds - Can view full gateway responses 5. SMS Broadcast: - Can send SMS to all users or filtered groups - Creates notifications for users - SMS is sent asynchronously - Can schedule broadcasts 6. Reports: - SMS usage report: Shows usage trends, top users, status breakdown - Revenue report: Shows revenue trends, package performance, customer metrics - Use date ranges and grouping for flexible reporting 7. Settings: - Sensitive fields (API keys) are hidden in GET response - When updating, send full value (not masked) - Changes take effect immediately - Some settings may require app restart (check backend docs) 8. Package Management: - Can create/edit/delete packages - Cannot delete packages with active subscriptions - Package limits are set per property category 9. SMS Templates: - Can view all templates (user + system) - Can create system default templates - Can edit any template - Cannot delete templates in use 10. Data Privacy: - Admin has access to all user data - Handle sensitive data carefully - Log admin actions (backend creates ActivityLog entries) ================================================================================ ✅ END OF ADMIN FRONTEND API DOCUMENTATION ================================================================================ This guide contains everything you need to build the admin dashboard. All endpoints, request/response formats, validation rules, and error handling are documented above. For user frontend, see: user_frontend_api_guide.txt ================================================================================