# Tracking Number on Orders, My Account and Emails

> Adds carrier and tracking number fields to the order screen, then shows a tracking link to the customer on their order page and in the completed order email.

- Type: PHP
- Runs: Run everywhere
- Category: [WooCommerce](https://wpide.com/library/category/woocommerce/)
- Requires: WooCommerce
- Tags: woocommerce, shipping, tracking, orders
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/woo-order-tracking-number/

## Code

```php
$wpide_carriers = array( // Carrier => tracking URL ({number} is replaced).
    'Royal Mail' => 'https://www.royalmail.com/track-your-item#/tracking-results/{number}',
    'DHL'        => 'https://www.dhl.com/global-en/home/tracking.html?tracking-id={number}',
    'UPS'        => 'https://www.ups.com/track?tracknum={number}',
    'USPS'       => 'https://tools.usps.com/go/TrackConfirmAction?tLabels={number}',
    'FedEx'      => 'https://www.fedex.com/fedextrack/?trknbr={number}',
);

add_action( 'add_meta_boxes', function () use ( $wpide_carriers ) {
    if ( ! function_exists( 'wc_get_page_screen_id' ) ) {
        return;
    }

    add_meta_box( 'wpide-tracking', 'Shipment tracking', function ( $post_or_order ) use ( $wpide_carriers ) {
        $order = $post_or_order instanceof WC_Order ? $post_or_order : wc_get_order( $post_or_order->ID );

        if ( ! $order ) {
            return;
        }

        wp_nonce_field( 'wpide_tracking', 'wpide_tracking_nonce' );
        echo '<p><label for="wpide-carrier">' . esc_html( 'Carrier' ) . '</label><br><select id="wpide-carrier" name="wpide_carrier" style="width:100%"><option value="">—</option>';

        foreach ( array_keys( $wpide_carriers ) as $carrier ) {
            printf( '<option %s>%s</option>', selected( $order->get_meta( '_wpide_carrier' ), $carrier, false ), esc_html( $carrier ) );
        }

        echo '</select></p>';
        printf( '<p><label for="wpide-tracking">%s</label><br><input type="text" id="wpide-tracking" name="wpide_tracking" value="%s" style="width:100%%"></p>', esc_html( 'Tracking number' ), esc_attr( $order->get_meta( '_wpide_tracking' ) ) );
    }, wc_get_page_screen_id( 'shop-order' ), 'side', 'default' );
} );

add_action( 'woocommerce_process_shop_order_meta', function ( $order_id ) use ( $wpide_carriers ) {
    if ( ! isset( $_POST['wpide_tracking_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['wpide_tracking_nonce'] ), 'wpide_tracking' ) || ! current_user_can( 'edit_shop_orders' ) ) {
        return;
    }

    $order   = wc_get_order( $order_id );
    $carrier = isset( $_POST['wpide_carrier'] ) ? sanitize_text_field( wp_unslash( $_POST['wpide_carrier'] ) ) : '';

    if ( $order ) {
        $order->update_meta_data( '_wpide_carrier', isset( $wpide_carriers[ $carrier ] ) ? $carrier : '' );
        $order->update_meta_data( '_wpide_tracking', isset( $_POST['wpide_tracking'] ) ? sanitize_text_field( wp_unslash( $_POST['wpide_tracking'] ) ) : '' );
        $order->save();
    }
} );

$wpide_tracking_html = function ( $order ) use ( $wpide_carriers ) {
    $number  = $order->get_meta( '_wpide_tracking' );
    $carrier = $order->get_meta( '_wpide_carrier' );

    if ( ! $number ) {
        return '';
    }

    $label = $carrier ? $carrier . ': ' . $number : $number;
    $url   = isset( $wpide_carriers[ $carrier ] ) ? str_replace( '{number}', rawurlencode( $number ), $wpide_carriers[ $carrier ] ) : '';

    return '<p class="wpide-tracking"><strong>' . esc_html( 'Tracking:' ) . '</strong> ' . ( $url ? '<a href="' . esc_url( $url ) . '">' . esc_html( $label ) . '</a>' : esc_html( $label ) ) . '</p>';
};

add_action( 'woocommerce_order_details_after_order_table', function ( $order ) use ( $wpide_tracking_html ) {
    echo wp_kses_post( $wpide_tracking_html( $order ) );
} );

add_action( 'woocommerce_email_before_order_table', function ( $order, $sent_to_admin, $plain_text, $email ) use ( $wpide_tracking_html ) {
    if ( $sent_to_admin || ! $email || 'customer_completed_order' !== $email->id ) {
        return;
    }

    $html = $wpide_tracking_html( $order );
    echo $plain_text ? esc_html( wp_strip_all_tags( $html ) ) . "\n\n" : wp_kses_post( $html );
}, 10, 4 );
```

## Notes

Add carriers and their tracking URLs to $wpide_carriers ({number} is replaced); works with HPOS and legacy orders.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Tracking Number on Orders, My Account and Emails" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
