boxcart.dev

Hooks & Filters

A reference for the most useful action and filter hooks provided by BoxCart, with parameters, source locations, and ready-to-use code examples. BoxCart fires many more hooks than are listed here; grep the source for do_action( 'boxcart_ and apply_filters( 'boxcart_ to discover the full set.

Overview

BoxCart follows standard WordPress conventions for extensibility by exposing action hooks and filter hooks throughout its codebase. These hooks allow theme and plugin developers to modify behaviour, inject custom logic, and integrate with external services without editing BoxCart core files.

Tip

All BoxCart hooks are prefixed with boxcart_ to avoid conflicts with other plugins. Hook callbacks should always be added in your theme's functions.php or in a custom plugin file.

Action Hooks

Action hooks let you execute custom code at specific points during BoxCart operations. Register your callback with add_action().

boxcart_order_created

Fired immediately after a new order is created during checkout. Use this hook to trigger external notifications, sync orders to a third-party system, or perform post-order processing.

ParameterTypeDescription
$order_idintThe ID of the newly created order

Fired from: BoxCart_Checkout

PHP
add_action( 'boxcart_order_created', 'my_notify_on_new_order' );
function my_notify_on_new_order( $order_id ) {
    // Example: send a Slack notification when a new order is placed
    $order = BoxCart_Order::get( $order_id );
    if ( ! $order ) {
        return;
    }
    wp_remote_post( 'https://hooks.slack.com/services/YOUR/WEBHOOK/URL', [
        'body' => wp_json_encode( [
            'text' => sprintf( 'New order #%s received!', $order->get_order_number() ),
        ] ),
        'headers' => [ 'Content-Type' => 'application/json' ],
    ] );
}

boxcart_order_status_changed

Fired when an order's status changes (e.g. Pending to Processing, Processing to Ready). Useful for integrating with fulfilment systems or sending custom notifications based on specific status transitions.

ParameterTypeDescription
$order_idintThe ID of the order
$old_statusstringThe previous status (e.g. 'pending', 'processing')
$new_statusstringThe new status (e.g. 'ready', 'completed')

Fired from: BoxCart_Order

PHP
add_action( 'boxcart_order_status_changed', 'my_on_order_ready', 10, 3 );
function my_on_order_ready( $order_id, $old_status, $new_status ) {
    if ( $new_status === 'ready' ) {
        // Send an SMS notification when the order is ready for collection
        my_send_sms( $order_id, 'Your order is ready for collection!' );
    }
}

boxcart_payment_status_changed

Fired when payment status changes on an order (e.g. when payment is confirmed as complete, fails, or is refunded). Use this to trigger accounting integrations, update external records, or send payment-specific notifications.

ParameterTypeDescription
$order_idintThe ID of the order
$old_statusstringThe previous payment status
$new_statusstringThe new payment status (e.g. 'paid', 'failed', 'refunded')

Fired from: BoxCart_Order

PHP
add_action( 'boxcart_payment_status_changed', 'my_log_payment_change', 10, 3 );
function my_log_payment_change( $order_id, $old_status, $new_status ) {
    if ( $new_status === 'paid' ) {
        // Record the payment in an external accounting system
        my_accounting_api_record_payment( $order_id );
    }
}

boxcart_after_add_to_basket

Fired after an item is successfully added to the basket. A companion hook boxcart_before_add_to_basket fires before the item is added, allowing you to perform validation or logging.

ParameterTypeDescription
$product_idintThe product being added
$quantityfloatThe quantity added
$basket_idintThe basket ID
$quantity_type_idintThe quantity type ID (e.g. per kg, each)

Fired from: BoxCart_Basket

PHP
add_action( 'boxcart_after_add_to_basket', 'my_track_add_to_basket', 10, 4 );
function my_track_add_to_basket( $product_id, $quantity, $basket_id, $quantity_type_id ) {
    // Track add-to-basket events for analytics
    if ( function_exists( 'my_analytics_track' ) ) {
        my_analytics_track( 'add_to_cart', [
            'product_id' => $product_id,
            'quantity'   => $quantity,
        ] );
    }
}

boxcart_before_add_to_basket

Fired before an item is added to the basket. Use this hook to perform pre-addition validation, logging, or conditional logic.

ParameterTypeDescription
$product_idintThe product being added
$quantityfloatThe quantity requested
$quantity_type_idintThe quantity type ID

Fired from: BoxCart_Basket

PHP
add_action( 'boxcart_before_add_to_basket', 'my_log_basket_addition', 10, 3 );
function my_log_basket_addition( $product_id, $quantity, $quantity_type_id ) {
    error_log( sprintf(
        'BoxCart: Adding product %d (qty: %s, type: %d) to basket',
        $product_id, $quantity, $quantity_type_id
    ) );
}

boxcart_basket_updated

Fired whenever the basket is updated (item quantity changed, item removed, etc.). Useful for recalculating custom totals or syncing basket state with an external service.

ParameterTypeDescription
$basket_idintThe ID of the updated basket

Fired from: BoxCart_Basket

PHP
add_action( 'boxcart_basket_updated', 'my_on_basket_update' );
function my_on_basket_update( $basket_id ) {
    // Invalidate any cached basket data
    wp_cache_delete( 'boxcart_basket_' . $basket_id, 'boxcart' );
}

boxcart_basket_cleared

Fired when all items are cleared from a basket.

ParameterTypeDescription
$basket_idintThe ID of the cleared basket

Fired from: BoxCart_Basket

PHP
add_action( 'boxcart_basket_cleared', 'my_on_basket_cleared' );
function my_on_basket_cleared( $basket_id ) {
    // Log basket clear events for analytics
    error_log( 'BoxCart: Basket ' . $basket_id . ' was cleared.' );
}

boxcart_before_checkout

Fired before the order creation process begins at checkout. Use this to perform pre-checkout validation, fraud checks, or logging.

ParameterTypeDescription
No parameters

Fired from: BoxCart_Checkout

PHP
add_action( 'boxcart_before_checkout', 'my_pre_checkout_log' );
function my_pre_checkout_log() {
    error_log( 'BoxCart: Checkout process starting at ' . current_time( 'mysql' ) );
}

boxcart_after_checkout

Fired after the order has been created at checkout. Similar to boxcart_order_created but fires specifically within the checkout flow context.

ParameterTypeDescription
$order_idintThe ID of the newly created order

Fired from: BoxCart_Checkout

PHP
add_action( 'boxcart_after_checkout', 'my_post_checkout_tasks' );
function my_post_checkout_tasks( $order_id ) {
    // Trigger a webhook to an external fulfilment service
    wp_remote_post( 'https://api.example.com/orders', [
        'body'    => wp_json_encode( [ 'order_id' => $order_id ] ),
        'headers' => [ 'Content-Type' => 'application/json' ],
    ] );
}

boxcart_checkout_validation

Fired during checkout validation, allowing you to inspect or log the posted form data.

ParameterTypeDescription
$posted_dataarrayThe sanitised checkout form data

Fired from: BoxCart_Checkout

PHP
add_action( 'boxcart_checkout_validation', 'my_validate_checkout_data' );
function my_validate_checkout_data( $posted_data ) {
    // Example: log checkout attempts for monitoring
    error_log( 'BoxCart: Checkout validation for ' . $posted_data['email'] );
}

boxcart_customer_details_updated

Fired after a customer updates their account details (name, email, phone, address).

ParameterTypeDescription
$customer_idintThe WordPress user ID
$dataarrayThe updated profile data

Fired from: BoxCart_Account

PHP
add_action( 'boxcart_customer_details_updated', 'my_sync_customer_profile', 10, 2 );
function my_sync_customer_profile( $customer_id, $data ) {
    // Sync updated details to a CRM
    my_crm_update_contact( $customer_id, $data );
}

boxcart_order_modified

Fired after a customer modifies an existing order (changes items, collection slot, or notes) within the allowed modification window.

ParameterTypeDescription
$order_idintThe ID of the modified order
$changesarrayAn array describing what was changed
$user_idintThe WordPress user ID of the customer who made the modification

Fired from: BoxCart_Order_Modification

PHP
add_action( 'boxcart_order_modified', 'my_on_order_modified', 10, 3 );
function my_on_order_modified( $order_id, $changes, $user_id ) {
    // Log order modifications for audit purposes
    error_log( sprintf(
        'BoxCart: Order #%d modified by user %d. Changes: %s',
        $order_id, $user_id, wp_json_encode( $changes )
    ) );
}

boxcart_slot_selected

Fired when a customer selects a collection time slot for their basket.

ParameterTypeDescription
$basket_idintThe basket ID
$location_idintThe selected collection location ID
$slot_datestringThe selected date (Y-m-d format)
$time_startstringSlot start time (H:i format)
$time_endstringSlot end time (H:i format)

Fired from: BoxCart_Basket

PHP
add_action( 'boxcart_slot_selected', 'my_on_slot_selected', 10, 5 );
function my_on_slot_selected( $basket_id, $location_id, $slot_date, $time_start, $time_end ) {
    // Track slot selection for demand analytics
    my_analytics_track( 'slot_selected', [
        'location_id' => $location_id,
        'date'        => $slot_date,
        'time'        => $time_start . ' - ' . $time_end,
    ] );
}

boxcart_favourite_added

Fired when a customer adds a product to their favourites list.

ParameterTypeDescription
$product_idintThe product that was favourited
$user_idintThe WordPress user ID

Fired from: BoxCart_Favourites

PHP
add_action( 'boxcart_favourite_added', 'my_track_favourite', 10, 2 );
function my_track_favourite( $product_id, $user_id ) {
    // Track which products are most favourited
    $count = (int) get_post_meta( $product_id, '_favourite_count', true );
    update_post_meta( $product_id, '_favourite_count', $count + 1 );
}

boxcart_favourite_removed

Fired when a customer removes a product from their favourites list.

ParameterTypeDescription
$product_idintThe product that was unfavourited
$user_idintThe WordPress user ID

Fired from: BoxCart_Favourites

PHP
add_action( 'boxcart_favourite_removed', 'my_untrack_favourite', 10, 2 );
function my_untrack_favourite( $product_id, $user_id ) {
    $count = max( 0, (int) get_post_meta( $product_id, '_favourite_count', true ) - 1 );
    update_post_meta( $product_id, '_favourite_count', $count );
}

boxcart_favourites_cleared

Fired when a customer clears all of their favourites in one go (e.g. via the "Clear all" button on the favourites view).

ParameterTypeDescription
$user_idintThe WordPress user ID whose favourites list was cleared

Fired from: BoxCart_Favourites

PHP
add_action( 'boxcart_favourites_cleared', 'my_on_favourites_cleared' );
function my_on_favourites_cleared( $user_id ) {
    // Reset any cached favourites data for this customer
    delete_user_meta( $user_id, 'my_favourites_cache' );
}

boxcart_admin_settings_saved

Fired after the admin saves BoxCart settings from the settings page.

ParameterTypeDescription
$settingsarrayThe full settings array that was saved

Fired from: BoxCart_Admin_Settings

PHP
add_action( 'boxcart_admin_settings_saved', 'my_on_settings_saved' );
function my_on_settings_saved( $settings ) {
    // Clear any caches when settings change
    wp_cache_flush();
    // Log which admin changed settings
    error_log( 'BoxCart settings updated by user ' . get_current_user_id() );
}

boxcart_admin_dashboard

Fired when the BoxCart admin dashboard view is rendered. Use this to inject custom widgets or content into the dashboard.

ParameterTypeDescription
No parameters

Fired from: dashboard.php (admin view)

PHP
add_action( 'boxcart_admin_dashboard', 'my_custom_dashboard_widget' );
function my_custom_dashboard_widget() {
    echo '<div class="boxcart-dashboard-widget">';
    echo '<h3>Custom Analytics</h3>';
    echo '<p>Your custom dashboard content here.</p>';
    echo '</div>';
}

Filter Hooks

Filter hooks let you modify data before BoxCart uses it. Register your callback with add_filter(). Your callback must return a value - either the original value unmodified or your modified version.

boxcart_basket_total

Filter the basket total before it is displayed or used in calculations. Use this to apply custom discounts, surcharges, or pricing logic.

ParameterTypeDescription
$totalfloatThe calculated basket total
$basketBoxCart_BasketThe basket instance (use $basket->get_items(), $basket->get_total(), etc.)

Returns: float - The filtered basket total.

PHP
add_filter( 'boxcart_basket_total', 'my_apply_bulk_discount', 10, 2 );
function my_apply_bulk_discount( $total, $basket ) {
    // Apply a 10% discount on orders over 50
    if ( $total > 50 ) {
        $total *= 0.9;
    }
    return $total;
}

boxcart_email_recipient

Filter the recipient email address before an email is sent. Use this to add CC recipients, redirect emails during testing, or conditionally change recipients.

ParameterTypeDescription
$tostringThe recipient email address
$orderBoxCart_OrderThe order object associated with the email (use getters like $order->get_customer_email())

Returns: string - The filtered email address.

PHP
add_filter( 'boxcart_email_recipient', 'my_redirect_test_emails', 10, 2 );
function my_redirect_test_emails( $to, $order ) {
    // During development, redirect all emails to a test address
    if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
        return 'dev-testing@example.com';
    }
    return $to;
}

boxcart_email_subject

Filter the subject line of emails sent by BoxCart.

ParameterTypeDescription
$subjectstringThe email subject line
$template_typestringThe email template type. This filter fires for 'order_confirmation', 'order_modified', and 'order_message_to_customer'.
$orderBoxCart_OrderThe order object (use getter methods)

Returns: string - The filtered subject line.

PHP
add_filter( 'boxcart_email_subject', 'my_custom_email_subject', 10, 3 );
function my_custom_email_subject( $subject, $template_type, $order ) {
    // Add a store name prefix to all email subjects
    $store_name = BoxCart_Helpers::get_settings()['business_name'] ?? 'Our Store';
    return '[' . $store_name . '] ' . $subject;
}

boxcart_email_content

Filter the HTML content of emails before they are sent. Use this to add custom sections, banners, or modify the email body.

ParameterTypeDescription
$contentstringThe email HTML content
$template_typestringThe email template type
$orderBoxCart_OrderThe order object (use getter methods)

Returns: string - The filtered email content.

PHP
add_filter( 'boxcart_email_content', 'my_add_email_footer', 10, 3 );
function my_add_email_footer( $content, $template_type, $order ) {
    // Add a promotional footer to order confirmation emails
    if ( $template_type === 'order_confirmation' ) {
        $content .= '<div style="margin-top:20px;padding:15px;background:#f8f8f8;">';
        $content .= '<p>Thank you for your order! Use code COLLECT10 for 10% off your next order.</p>';
        $content .= '</div>';
    }
    return $content;
}

boxcart_email_headers

Filter the email headers (e.g. to add CC, BCC, or Reply-To addresses).

ParameterTypeDescription
$headersstring|arrayThe email headers
$tostringThe recipient email address
$subjectstringThe email subject

Returns: string|array - The filtered headers.

PHP
add_filter( 'boxcart_email_headers', 'my_add_bcc_to_emails', 10, 3 );
function my_add_bcc_to_emails( $headers, $to, $subject ) {
    // BCC the store manager on all outgoing emails
    if ( is_array( $headers ) ) {
        $headers[] = 'Bcc: manager@example.com';
    } else {
        $headers .= "\r\nBcc: manager@example.com";
    }
    return $headers;
}

boxcart_show_prices and members-only pricing filters

These filters drive the members-only pricing feature. They live in the free core so BoxCart Pro (or your own code) can hide prices and the add-to-cart controls from logged-out visitors. On the free build they return their defaults unless you filter them yourself.

FilterTypeDescription
boxcart_show_pricesboolWhether product prices are shown. Return false to hide prices.
boxcart_show_add_to_cartboolWhether the add-to-cart control is shown. Return false to hide it.
boxcart_hidden_price_textstringMessage shown in place of a hidden price (default 'Log in to see prices and order').
boxcart_hidden_price_cta_labelstringLabel for the call-to-action shown with a hidden price (default 'Log in').
boxcart_can_add_to_basketboolServer-side guard on the add-to-basket AJAX action. Return false to block it.
boxcart_can_place_orderboolServer-side guard on placing an order. Return false to block checkout.

Defined in: BoxCart_Helpers and BoxCart_Ajax.

Additional hooks

BoxCart fires many more action and filter hooks than are catalogued here. If you need a hook at a specific point that is not listed, grep the source for do_action( 'boxcart_ / apply_filters( 'boxcart_, consider extending BoxCart, or raise a feature request.