Skip to main content

Order fulfillments hooks

WooCommerce exposes lifecycle hooks, status filters, provider filters, notification actions, and email template hooks for order fulfillments. These hooks let extensions validate fulfillment data, synchronize external systems, customize tracking behavior, and adjust merchant or customer-facing output.

Data lifecycle filters​

These filters run before WooCommerce persists fulfillment changes. Each filter receives the Fulfillment object and must return it (optionally modified). To cancel the operation — for example, to enforce a validation rule — throw a FulfillmentException inside the callback. The exception message is surfaced to the caller as an error response.

HookPurpose
woocommerce_fulfillment_before_createModify a Fulfillment object before it is inserted into the database. Throw a FulfillmentException to block creation.
woocommerce_fulfillment_before_fulfillModify a Fulfillment object immediately before it transitions into a fulfilled state during create or update operations.
woocommerce_fulfillment_before_updateModify a Fulfillment object before changes are written to the database. Throw a FulfillmentException to block the update.
woocommerce_fulfillment_before_deleteModify a Fulfillment object before WooCommerce soft-deletes it. Throw a FulfillmentException to block deletion.
use Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentException;

// Require a tracking number before a fulfillment can be created in fulfilled status.
add_filter( 'woocommerce_fulfillment_before_create', function( $fulfillment ) {
if ( $fulfillment->get_is_fulfilled() && ! $fulfillment->get_tracking_number() ) {
throw new FulfillmentException(
__( 'A tracking number is required to create a fulfilled fulfillment.', 'my-plugin' )
);
}

return $fulfillment;
} );

Data lifecycle actions​

These actions fire after WooCommerce saves or deletes the fulfillment.

HookParametersPurpose
woocommerce_fulfillment_after_createFulfillment $fulfillmentReact after a fulfillment is created.
woocommerce_fulfillment_after_fulfillFulfillment $fulfillmentReact when a fulfillment becomes fulfilled.
woocommerce_fulfillment_after_updateFulfillment $fulfillment, array $changes, string $previous_statusReact after an update and inspect the changed core fields or metadata.
woocommerce_fulfillment_after_deleteFulfillment $fulfillmentReact after a fulfillment is soft-deleted.
add_action( 'woocommerce_fulfillment_after_update', function( $fulfillment, $changes, $previous_status ) {
$meta_changes = $changes['meta_data'] ?? array();

if ( array_key_exists( '_tracking_number', $meta_changes ) ) {
// Push the new tracking number to an external system.
}

if ( $previous_status !== $fulfillment->get_status() ) {
// React to a status transition.
}
}, 10, 3 );

Notification actions​

These actions back the built-in customer fulfillment emails and any additional notification channel an extension wants to add.

HookParametersPurpose
woocommerce_fulfillment_created_notificationint $order_id, Fulfillment $fulfillment, WC_Order $orderNotify the customer that a fulfilled fulfillment was created.
woocommerce_fulfillment_updated_notificationint $order_id, Fulfillment $fulfillment, WC_Order $orderNotify the customer that a fulfilled fulfillment was updated.
woocommerce_fulfillment_deleted_notificationint $order_id, Fulfillment $fulfillment, WC_Order $orderNotify the customer that a fulfilled fulfillment was deleted.
add_action( 'woocommerce_fulfillment_created_notification', function( $order_id, $fulfillment, $order ) {
$phone = $order->get_billing_phone();

if ( $phone && $fulfillment->get_tracking_number() ) {
// Send an SMS in parallel with the built-in email.
}
}, 10, 3 );

Status, provider, and tracking filters​

These filters change how WooCommerce calculates fulfillment state and resolves shipping providers.

HookPurpose
woocommerce_fulfillment_order_fulfillment_statusesRegister or modify order-level fulfillment statuses.
woocommerce_fulfillment_fulfillment_statusesRegister or modify fulfillment record statuses.
woocommerce_fulfillment_calculate_order_fulfillment_statusOverride how WooCommerce derives an order's fulfillment state from its fulfillment records.
woocommerce_fulfillments_auto_fulfill_productsReturn an array of product or variation IDs to fulfill automatically. Receives the IDs array and the WC_Order object.
woocommerce_fulfillment_order_fulfillment_status_textCustomize the display label for an order-level fulfillment state.
woocommerce_fulfillment_shipping_providersAdd or modify shipping providers available to the feature.
woocommerce_fulfillment_shipment_provider_labelCustomize the provider label used in fulfillment emails, order notes, and the orders list column, after WooCommerce resolves it from the provider list or from fulfillment metadata. Receives the label and the Fulfillment object. A value that cannot be rendered as text is ignored.
woocommerce_rest_prepare_fulfillments_providersAdd or modify the provider list returned by the fulfillments providers REST endpoint. Receives the providers array and the WP_REST_Request. Entries missing label, icon, value, or url are dropped.
woocommerce_fulfillment_parse_tracking_numberParse or normalize tracking numbers based on origin and destination countries.
woocommerce_fulfillment_meta_key_translationsCustomize the translation map for fulfillment metadata labels.
woocommerce_fulfillment_translate_meta_keyCustomize the label for one metadata key before it is rendered in emails or other UI.
add_filter( 'woocommerce_fulfillment_shipping_providers', function( $providers ) {
// Option 1: Register a provider class name
$providers['my-carrier'] = 'My_Carrier_Provider';

// Option 2: Register a provider instance
$providers['my-carrier-alt'] = new My_Carrier_Provider();

return $providers;
} );

Order note filters​

WooCommerce writes order notes when fulfillments are created, updated, deleted, or when fulfillment-related status changes occur. These filters let extensions rewrite those note messages.

HookPurpose
woocommerce_fulfillment_created_order_noteCustomize the order note written after a fulfillment is created.
woocommerce_fulfillment_updated_order_noteCustomize the order note written after a fulfillment is updated.
woocommerce_fulfillment_deleted_order_noteCustomize the order note written after a fulfillment is deleted.
woocommerce_fulfillment_order_status_changed_order_noteCustomize the note written when the order-level fulfillment status changes.
woocommerce_fulfillment_status_changed_order_noteCustomize the note written when an individual fulfillment status changes.

Email template hooks​

The fulfillment email templates expose the standard extension points below.

HookParametersPurpose
woocommerce_email_fulfillment_detailsWC_Order $order, Fulfillment $fulfillment, bool $sent_to_admin, bool $plain_text, WC_Email $emailRender the fulfillment details block in the email.
woocommerce_email_fulfillment_metaWC_Order $order, Fulfillment $fulfillment, bool $sent_to_admin, bool $plain_text, WC_Email $emailRender additional metadata inside the email.
woocommerce_email_before_fulfillment_tableWC_Order $order, Fulfillment $fulfillment, bool $sent_to_admin, bool $plain_text, WC_Email $emailInject content before the fulfillment items table.
woocommerce_email_after_fulfillment_tableWC_Order $order, Fulfillment $fulfillment, bool $sent_to_admin, bool $plain_text, WC_Email $emailInject content after the fulfillment items table.
woocommerce_email_fulfillment_items_argsTemplate arguments arrayCustomize how fulfillment line items are rendered in the email templates.
woocommerce_get_email_fulfillment_items_tablestring $html, WC_Order $order, Fulfillment $fulfillmentFilter and return the rendered fulfillment items table HTML.

Privacy filters​

When an order is anonymized, through the WordPress personal-data eraser or the automatic retention cleanup, WooCommerce clears the personal data stored on its fulfillments. This also runs on a store where the fulfillments feature has since been disabled, as long as its tables were created while it was on, since any tracking data they hold is still stored.

HookParametersPurpose
woocommerce_privacy_remove_fulfillment_personal_data_metastring[] $meta_keys, WC_Order $orderAdd or remove the fulfillment meta keys cleared during erasure. Defaults to _tracking_number and _tracking_url.
add_filter( 'woocommerce_privacy_remove_fulfillment_personal_data_meta', function( $meta_keys, $order ) {
// Redact a shipping label URL stored by this extension.
$meta_keys[] = '_shipping_label_url';

return $meta_keys;
}, 10, 2 );