1. Overview
WHMS has a unified notification system that delivers notifications through three channels: database (in-app bell icon), email, and SMS. The NotificationService orchestrates all three channels from a single call point. Admin users see notifications in the top header bar with real-time polling (every 30 seconds).
2. Architecture
| Component | Location | Purpose |
| NotificationService | app/Services/NotificationService.php | Central orchestrator for all notification channels |
| GeneralNotification | app/Notifications/GeneralNotification.php | Laravel notification class for database channel |
| NotificationController | app/Http/Controllers/Admin/NotificationController.php | Admin endpoints: list, mark read, recent (JSON) |
| Notifications Table | Laravel default (UUID-based) | Stores notifications with type, data JSON, read_at |
3. Notification Channels
| Channel | Delivery | Description |
| Database |
Instant |
Stored in notifications table. Appears in admin header bell icon with unread count. Sent to the client user AND all admin users. |
| Email |
Instant |
Sent via configured mail driver using the matching EmailTemplate. Only sent if the template exists and is active. |
| SMS |
Instant |
Sent via configured SMS provider. Only sent if notification.sms_enabled is true AND user has a phone number. |
4. Notification Data Structure
Each database notification stores a JSON data object with these fields:
| Field | Type | Description |
| title | string | Notification title (e.g. "New Invoice Generated") |
| message | string | Notification body text |
| icon | string | Font Awesome icon class (default: "fa-bell") |
| color | string | Bootstrap color class (default: "info") |
| url | string | Link to relevant page (default: "#") |
| invoice_id | int (optional) | Related invoice ID |
| invoice_number | string (optional) | Related invoice number |
5. Event-Driven Notifications
Notifications are triggered automatically by invoice lifecycle events:
| Event | Listener | DB Title | Email Template |
| InvoiceCreated |
NotifyInvoiceCreated |
"New Invoice Generated" |
invoice-created |
| InvoicePaid |
NotifyInvoicePaid |
"Invoice Paid" |
invoice-paid |
| InvoiceOverdue |
NotifyInvoiceOverdue |
"Invoice Overdue" |
invoice-overdue |
| Scheduled |
SendInvoiceReminder |
"Invoice Payment Reminder" |
invoice-reminder / invoice-overdue-reminder |
6. NotificationService Flow
When an invoice event occurs, the NotificationService executes these steps in order:
- Step 1: Send database notification to the client user
- Step 2: Send database notification to all admin users
- Step 3: Look up the EmailTemplate by slug, send email if template is active
- Step 4: Check if SMS is enabled (
notification.sms_enabled), look up SMS template from settings, send SMS if user has phone number
7. Admin Notification Endpoints
| Route | Method | Description |
| /admin/notifications | GET | Paginated list of all notifications (25 per page) |
| /admin/notifications/recent | GET | JSON endpoint returning 10 latest unread notifications (polled every 30s) |
| /admin/notifications/{id}/read | POST | Mark a single notification as read |
| /admin/notifications/mark-all-read | POST | Mark all unread notifications as read |
8. Complete Event Listener Map
| Event | Listener | Action |
| InvoiceCreated | NotifyInvoiceCreated | DB notification + Email + SMS |
| InvoicePaid | NotifyInvoicePaid | DB notification + Email + SMS |
| InvoicePaid | ProvisionServicesOnPayment | Dispatches provisioning jobs for order items |
| InvoicePaid | UpdateServiceDueDatesOnRenewalPayment | Extends domain/hosting expiry for renewal invoices |
| InvoiceOverdue | NotifyInvoiceOverdue | DB notification + Email + SMS |
| OrderPlaced | CreateInitialInvoice | Creates initial invoice from order |
| MessageSent (Mail) | LogSentEmail | Logs all sent emails to ActivityLog |