Developer documentation
Developer Hooks for Packing Station for WooCommerce.
Packing Station exposes a focused set of WordPress actions and filters so developers can adapt the order feed, print payload, staff access, and workflow events without forking the plugin.
Extension approach
Controlled extension points, not a fork.
The hooks are intended for store-specific customisations such as adding delivery data to prints, limiting the order feed, reacting when staff complete an order, or adjusting access rules for a particular operation.
Custom code should live in a small site plugin or child-theme helper, not directly inside Packing Station. That keeps updates clean while preserving the custom workflow.
- Order feed Adjust WooCommerce order queries or add optional data to prepared order responses.
- Print payload Add fields or sections sent to the Android Print App while keeping required core keys intact.
- Workflow events React to completed orders, stock status updates, and emergency order pause or resume changes.
Hook reference
Available actions and filters.
All hook names use the psfw_ prefix.
| Hook | Type | Arguments | Purpose |
|---|---|---|---|
psfw_order_feed_query_args |
Filter | $args, $context |
Adjust the wc_get_orders() query for order feed endpoints. |
psfw_order_feed_order_data |
Filter | $order_data, $order, $context |
Add or modify one prepared order object before it is returned by the REST API. |
psfw_print_field_registry |
Filter | $registry |
Register additional selectable fields in WooCommerce > Packing Station. |
psfw_enabled_print_fields |
Filter | $fields, $context |
Adjust the final enabled field keys after saved settings or defaults are loaded. |
psfw_print_payload |
Filter | $payload, $order, $context |
Customize the order payload consumed by the Android companion app. |
psfw_print_payload_required_keys |
Filter | $required, $context, $order |
Adjust the required payload keys restored after psfw_print_payload. |
psfw_user_can_access |
Filter | $allowed, $user_id, $area |
Customize access to order_feed, order_control, or stock_control. |
psfw_order_datetime_format |
Filter | $format |
Customize the full order date/time format used in order payloads. |
psfw_order_card_datetime_format |
Filter | $format |
Customize the compact order date/time format used on order cards. |
psfw_order_status_update_allowed |
Filter | $allowed, $order, $new_status, $user_id |
Allow or block a staff-triggered status update. |
psfw_after_order_status_update |
Action | $order_id, $old_status, $new_status, $user_id |
Run logic after Packing Station changes an order status. |
psfw_after_stock_status_update |
Action | $product_id, $new_status, $user_id, $old_status |
Run logic after stock status is changed from Stock Control. |
psfw_after_order_control_change |
Action | $is_paused, $user_id, $reason |
Run logic after emergency order pause or resume changes. |
psfw_companion_app_config |
Filter | $config, $context |
Add small front-end or app config values exposed through PSCFG. |
Print payload safety
Developers can customize the Android print payload with psfw_print_payload. After that filter runs, the plugin restores required core keys where possible so the Print App still receives the minimum structure it expects.
idstatusitemscreated_fullcreated_card_sections
Where to put custom code
Put hook callbacks in a small custom plugin for the store. That keeps custom behaviour separate from Packing Station itself, so plugin updates do not overwrite local work.
Avoid removing core payload data unless you have also updated the consuming Android print workflow to understand the change.
Examples
Common customisations.
Add a selectable delivery slot field
This adds an order meta field to the admin field registry, then adds it to the payload when that field is enabled.
add_filter( 'psfw_print_field_registry', function ( $registry ) {
$registry['delivery'] = [
'label' => __( 'Delivery', 'my-plugin' ),
'fields' => [
'delivery_slot' => __( 'Delivery Slot', 'my-plugin' ),
],
];
return $registry;
} );
add_filter( 'psfw_print_payload', function ( $payload, $order, $context ) {
if ( empty( $context['enabled_fields'] ) || ! in_array( 'delivery_slot', $context['enabled_fields'], true ) ) {
return $payload;
}
$slot = $order->get_meta( '_delivery_slot' );
if ( '' === $slot ) {
return $payload;
}
$payload['delivery_slot'] = $slot;
$payload['_sections'][] = [
'key' => 'delivery',
'label' => __( 'Delivery', 'my-plugin' ),
'fields' => [
[
'key' => 'delivery_slot',
'label' => __( 'Delivery Slot', 'my-plugin' ),
'value' => $slot,
],
],
];
return $payload;
}, 10, 3 );
Limit the feed to collection orders
add_filter( 'psfw_order_feed_query_args', function ( $args, $context ) {
$args['meta_query'][] = [
'key' => '_order_type',
'value' => 'collection',
];
return $args;
}, 10, 2 );
Notify another system when staff complete an order
add_action( 'psfw_after_order_status_update', function ( $order_id, $old_status, $new_status, $user_id ) {
if ( 'completed' !== $new_status ) {
return;
}
// Send a webhook, write an audit log, or notify a fulfilment system.
}, 10, 4 );
Related pages
Use hooks when the base workflow needs a local adjustment.
For the general product overview, start with the plugin page. For installation and setup, use the support page.