Notifications
This guide explains how to use CartThrob’s notification system from a custom ExpressionEngine module or extension. It assumes basic PHP knowledge and familiarity with EE add-on install/update methods.
CartThrob notifications have two developer surfaces:
- Notification events — triggers that appear in the CartThrob Notifications control panel
- Notification plugins — delivery drivers that send those notifications (email is built in)
Most add-on authors only need to register a custom event and dispatch it. Building a new delivery plugin is optional.
For admin setup of templates, recipients, and built-in events, see the Notifications control panel docs.
Start Here
To fire a custom notification from your add-on:
- Register your event in
cartthrob_notification_eventsduring install/update - Ask the site admin to create a notification in CartThrob Notifications for that event
- When your event happens, call
ee('cartthrob:NotificationsService')->dispatch(...)
At that point CartThrob loads matching notification configs and delivers them through the selected notification plugin.
Events vs Plugins
| Piece | What it does | Where it lives |
|---|---|---|
| Event | Names the trigger shown in the CP dropdown | exp_cartthrob_notification_events table |
| Notification config | Admin-created row: event, template, recipients, type | CartThrob Notifications settings |
| Notification plugin | Delivers the notification | cartthrob/plugins/notification/ |
Built-in delivery plugins:
Cartthrob_email_notification.php— sends emailCartthrob_dummy_notification.php— stub/example plugin
Path:
system/user/addons/cartthrob/cartthrob/plugins/notification/
Registering a Custom Event
Register events during your add-on’s install and update routines. CartThrob’s own add-on builder uses this same pattern.
$module_name = 'My_module'; // arbitrary label shown in the CP
$notification_events = [
'my_notification_event',
'my_other_event',
];
if (ee()->db->table_exists('cartthrob_notification_events')) {
ee()->db->select('notification_event')
->from('cartthrob_notification_events')
->like('application', ucwords($module_name), 'after');
$existing = [];
foreach (ee()->db->get()->result() as $row) {
$existing[] = $row->notification_event;
}
foreach ($notification_events as $event) {
if ($event && !in_array($event, $existing)) {
ee()->db->insert('cartthrob_notification_events', [
'application' => ucwords($module_name),
'notification_event' => $event,
]);
}
}
}
What this does:
- Stores your application name and event short name
- Avoids inserting duplicates on update
- Makes the event selectable in CartThrob Notifications
In the control panel, the event key becomes:
My_module_my_notification_event
That combined string is what you must dispatch later.
Notes:
$module_namedoes not have to match your filename. It is the label used for registration.- Use
ee(), not$this->EE =& get_instance(). - Language keys for the application/event names improve the CP labels when present.
Configure the Notification
After registration, a site admin still has to create the notification in CartThrob:
- Create an EE template for the message body
- Open CartThrob Notifications settings
- Add a notification
- Choose your custom event from the Application Events list
- Set recipients, subject, template, and notification type
Details and built-in template variables are covered in the Notifications CP docs.
If no notification is configured for your event, dispatch() will simply find nothing to send.
Dispatching an Event
When your custom event occurs, dispatch it through CartThrob’s notifications service:
ee('cartthrob:NotificationsService')->dispatch(
'My_module_my_notification_event',
[
'customer_email' => '[email protected]',
'customer_name' => 'Buyer Name',
'order_id' => 123,
// any other variables your template needs
]
);
There is also a thin wrapper:
ee('cartthrob:EmailService')->dispatchEvent(
'My_module_my_notification_event',
$variables
);
Both call the same service.
What happens next:
- CartThrob finds notification configs whose
eventmatches your event string - It builds the matching notification plugin for each config
- Each plugin runs
send($data), which may log and/or deliver - Delivery goes through the plugin’s
deliver()method
Important:
- The event string must match the CP value exactly:
Application_event - Pass any dynamic values your templates or email fields need
{customer_email}and similar placeholders are not magic; provide the data in$variablesor ensure order fields are present for CartThrob’s built-in replacements
Passing Template Variables
The second argument to dispatch() becomes available to notification parsing.
Common keys for order-related emails:
$variables = [
'customer_email' => $customerEmail,
'customer_name' => $customerName,
'order_id' => $orderId,
];
For custom application emails, pass whatever your template expects:
$variables = [
'member_id' => $memberId,
'download_url' => $url,
'expires_at' => $expiresAt,
];
If your notification uses {customer_email} in the To/From fields, make sure that value is present in the data you dispatch, or that order field mappings can supply it.
Uninstalling Events
If your add-on uninstalls, remove the events you registered:
$module_name = 'My_module';
if (ee()->db->table_exists('cartthrob_notification_events')) {
ee()->db->delete('cartthrob_notification_events', [
'application' => ucwords($module_name),
]);
}
Use the application column, not class. Deleting by class will not remove your registered events.
If you skip uninstall cleanup, your events remain listed in the Notifications dropdown even after the add-on is gone.
Built-in Events
CartThrob registers these events itself. You do not need to insert them.
Payment triggers
completeddeclinedfailedoffsiteprocessingrefundedexpiredcanceledpending
CartThrob payment flows dispatch these through NotificationsService.
Other events
low_stockstatus_change
status_change is special: matching also depends on starting and ending order statuses configured on the notification.
Custom registered events appear under Application Events as Application_event.
Building a Notification Plugin
Only needed if you want a new delivery type, such as Slack, SMS, or a custom webhook. Most add-ons can use the built-in email plugin.
File location and naming
system/user/addons/cartthrob/cartthrob/plugins/notification/
Example:
Filename: Cartthrob_webhook_notification.php
Class: Cartthrob_webhook_notification
Minimum plugin
Extend CartThrob\Plugins\Notification\NotificationPlugin and implement deliver().
<?php
use CartThrob\Plugins\Notification\NotificationPlugin;
class Cartthrob_webhook_notification extends NotificationPlugin
{
public $title = 'Webhook Notification';
public $short_title = 'webhook';
public string $type = 'webhook';
public $settings = [
[
'name' => 'Webhook URL',
'short_name' => 'webhook_url',
'type' => 'text',
],
];
protected array $rules = [
'webhook_url' => 'required',
];
public function deliver(array $data): bool
{
$url = $this->getSetting('webhook_url');
// Send $data / parsed template content to your endpoint
return true;
}
}
Required pieces:
$title— label in the CP$type— stored on notification configs and used to select the plugindeliver(array $data): bool— performs the actual send
Useful base methods:
getSetting('short_name')— read plugin settingsparse($template, $variables, $constants)— parse EE/template contentshouldSend($data)— override to skip delivery conditionallypreProcess($data)— mutate data before logging/delivery
Best references:
Cartthrob_email_notification.phpfor a full production pluginCartthrob_dummy_notification.phpfor a minimal stub
Logging and send behavior
NotificationPlugin::send() checks CartThrob’s log_notifications setting:
no— deliver onlylog_only— log onlylog_and_send— log and deliver
Your plugin usually only needs to implement deliver(). Logging is handled by the base class.
Extension Hook
Before delivery, CartThrob fires cartthrob_send_notification.
public function cartthrob_send_notification($notification)
{
// $notification is a NotificationPlugin instance
}
Set ee()->extensions->end_script = true to skip CartThrob’s normal delivery after your hook runs.
See the hooks reference for full details.
Legacy Email Library Path
Older docs and some internal tools still use cartthrob_emails directly:
ee()->load->library('cartthrob_emails');
$emails = ee()->cartthrob_emails->get_email_for_event('My_module_my_notification_event');
foreach ($emails as $email) {
ee()->cartthrob_emails->sendEmail($email, $variables);
}
Notes:
- Prefer
NotificationsService->dispatch()for new code - The current method name is
sendEmail(), notsend_email() get_email_for_event()only returns notifications whose type isemailNotificationsServicecan deliver any notification plugin type
Checklist
Before testing a custom notification event:
- Event rows are inserted into
cartthrob_notification_eventson install/update - Application name and event name match what you plan to dispatch
- A notification is configured in CartThrob Notifications for that event
- Your code dispatches
Application_event, not just the short event name - Template/recipient variables are included in the dispatch data
- Uninstall deletes by
application, notclass - You use
ee(), not$this->EE
If the event never appears in the CP, check the cartthrob_notification_events table. If dispatch runs but nothing sends, confirm a notification is configured for that exact event string and that logging is not set to block delivery unexpectedly.