Skip to main content

Notification

Delivers notifications on behalf of other modules over three channels: database (an inbox readable through the API — rendered by the admin panel's and storefront's notification bells), email, and web push (OS-level browser notifications via VAPID). Which channels each notification uses is mapped in the module's config/notifications.php; messages are rendered from per-locale Blade templates (en/fa today).

Notifications are queued on the database queue, so a queue worker must be running (the develop and production compose stacks both ship one).

Realtime delivery​

Database notifications are also broadcast over Laravel Reverb: the moment one is stored, a notification.created event is pushed to the recipient's private channel — notification.user.{id} or notification.admin.{id} — carrying the notification payload plus the audience-scoped unread count, so the admin and storefront bells (laravel-echo + pusher-js) update live instead of polling. Channel authorization rides the API's Sanctum middleware (POST /notification/broadcasting/auth). Both compose stacks run the Reverb websocket service; without it, the bells fall back to fetching on page load.

Web push is opt-in per browser: the SPAs register a service worker and subscribe through the endpoints below. Generate the key pair once with php artisan notification:generate-vapid; without keys the channel no-ops safely.

Events listened to​

EventRecipientsChannels
OtpRequestedEventuseremail
UserSignedInEventuser, adminsuser: database + email + web push; admins: database + web push
ContactMessageCreatedEventadminsemail
OrderCreatedEventuser, adminsdatabase + email + web push
OrderPaidEventuserdatabase + email + web push
OrderShippedEventuserdatabase + email + web push
OrderCompletedEventuserdatabase + web push
OrderCancelledEventuserdatabase + email + web push
PaymentSucceededEventadminsdatabase + web push
PaymentFailedEventuser, adminsdatabase + web push
TicketCreatedEventadminsdatabase + email
TicketMessageCreatedEventadmins, usercustomer reply → admins (database + email); admin answer → user (database + email + web push)

Admin recipients: emails go to ADMIN_NOTIFICATION_EMAILS (falling back to the mail sender address); database notifications fan out to all active staff by default, or to ADMIN_NOTIFICATION_USER_IDS when set.

Admin notifications for orders and support tickets carry order_id / ticket_id in their meta — the admin panel's bell uses them to deep-link straight to the order or ticket page.

Tables​

TableDescription
notification_notificationsStored database-channel notifications
notification_push_subscriptionsBrowser web-push registrations

Endpoints​

Identical read APIs for both audiences (auth: Sanctum; the admin set additionally requires permissions):

EndpointAudiencePurpose
GET /notification/user/notificationsUserPaginated inbox (15/page)
GET /notification/user/notifications/unread-countUserUnread badge count
PATCH /notification/user/notifications/{id}/readUserMark one as read
PATCH /notification/user/notifications/read-allUserMark all as read
GET /notification/admin/notificationsAdminPaginated inbox (15/page)
GET /notification/admin/notifications/unread-countAdminUnread badge count
PATCH /notification/admin/notifications/{id}/readAdminMark one as read
PATCH /notification/admin/notifications/read-allAdminMark all as read

Push subscriptions exist for both audiences (keyed by endpoint; delete takes it in the body), plus a public key discovery endpoint:

EndpointAudiencePurpose
GET /notification/webpush/vapid-public-keyPublicThe VAPID public key (null = web push unconfigured)
GET/POST/DELETE /notification/user/push-subscriptionsUserList / register / remove the browser's push registration
GET/POST/DELETE /notification/admin/push-subscriptionsAdminSame trio for staff browsers

Dependencies​

ModuleReason
CoreEvent contracts, recipient/user resolution support
AuthStaff resolution for admin recipients