Packing Station Developer Hooks

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.

  • id
  • status
  • items
  • created_full
  • created_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.