CartThrob 9 documentation for ExpressionEngine commerce teams Visit CartThrob.com
CartThrob.com

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:

  1. Notification events — triggers that appear in the CartThrob Notifications control panel
  2. 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:

  1. Register your event in cartthrob_notification_events during install/update
  2. Ask the site admin to create a notification in CartThrob Notifications for that event
  3. 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 email
  • Cartthrob_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_name does 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:

  1. Create an EE template for the message body
  2. Open CartThrob Notifications settings
  3. Add a notification
  4. Choose your custom event from the Application Events list
  5. 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:

  1. CartThrob finds notification configs whose event matches your event string
  2. It builds the matching notification plugin for each config
  3. Each plugin runs send($data), which may log and/or deliver
  4. 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 $variables or 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

  • completed
  • declined
  • failed
  • offsite
  • processing
  • refunded
  • expired
  • canceled
  • pending

CartThrob payment flows dispatch these through NotificationsService.

Other events

  • low_stock
  • status_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 plugin
  • deliver(array $data): bool — performs the actual send

Useful base methods:

  • getSetting('short_name') — read plugin settings
  • parse($template, $variables, $constants) — parse EE/template content
  • shouldSend($data) — override to skip delivery conditionally
  • preProcess($data) — mutate data before logging/delivery

Best references:

  • Cartthrob_email_notification.php for a full production plugin
  • Cartthrob_dummy_notification.php for a minimal stub

Logging and send behavior

NotificationPlugin::send() checks CartThrob’s log_notifications setting:

  • no — deliver only
  • log_only — log only
  • log_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(), not send_email()
  • get_email_for_event() only returns notifications whose type is email
  • NotificationsService can deliver any notification plugin type

Checklist

Before testing a custom notification event:

  1. Event rows are inserted into cartthrob_notification_events on install/update
  2. Application name and event name match what you plan to dispatch
  3. A notification is configured in CartThrob Notifications for that event
  4. Your code dispatches Application_event, not just the short event name
  5. Template/recipient variables are included in the dispatch data
  6. Uninstall deletes by application, not class
  7. 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.