In this post I’ll show you how to customize Woocommerce orders page with the help of simple code snippets. Now, in order to make this work add your chosen snippets shown to your child theme’s functions.php file or better yet, use a snippet manager like Code Snippets.
WpCodeBox is my favorite code snippets manager for WordPress. This is a premium plugin and if you’re interested, then grab WPCodeBox with a nice 20% discount here (SAVE 20% Coupon WPSH20).
Video: How to Customize Woocommerce Orders page?
In case you have a hard time using or following snippets shown below, take a look at the video. In it I’ll show you how to use them.
How to add an Woocommerce order number search field to the WP Admin top bar?
At the moment you have to go to the Woocommerce >> Orders page in order to search orders. With the help of this hack you can do it directly from your WordPress admin bar (see screenshot)
add_action('wp_before_admin_bar_render', function() {
if(!current_user_can('administrator')) {
return;
}
global $wp_admin_bar;
$search_query = '';
if (!empty($_GET['post_type']) && $_GET['post_type'] == 'shop_order' ) {
$search_query = !empty($_GET['s']) ? $_GET['s'] : '';
if($search_query) {
$order = get_post(intval($search_query));
if($order) {
wp_redirect(get_edit_post_link($order->ID, ''));
exit;
}
}
}
$wp_admin_bar->add_menu(array(
'id' => 'admin_bar_shop_order_form',
'title' => '<form method="get" action="'.get_site_url().'/wp-admin/edit.php?post_type=shop_order">
<input name="s" type="text" placeholder="Order ID" value="' . esc_attr($search_query) . '" style="width:100px; height: 25px; padding-left: 5px;">
<button class="button button-primary" style="height: 25px; padding: 0px 10px 0px 10px; margin-left: -5px;">Check this order</button>
<input name="post_type" value="shop_order" type="hidden">
// Add an Woocommerce order number search field to the WP Admin top bar
add_action('wp_before_admin_bar_render', function() {
if(!current_user_can('administrator')) {
return;
}
global $wp_admin_bar;
$search_query = '';
if (!empty($_GET['post_type']) && $_GET['post_type'] == 'shop_order' ) {
$search_query = !empty($_GET['s']) ? $_GET['s'] : '';
if($search_query) {
$order = get_post(intval($search_query));
if($order) {
wp_redirect(get_edit_post_link($order->ID, ''));
exit;
}
}
}
$wp_admin_bar->add_menu(array(
'id' => 'admin_bar_shop_order_form',
'title' => '<form method="get" action="'.get_site_url().'/wp-admin/edit.php?post_type=shop_order">
<input name="s" type="text" placeholder="Order ID" value="' . esc_attr($search_query) . '" style="width:100px; height: 25px; padding-left: 5px;">
<button class="button button-primary" style="height: 25px; padding: 0px 10px 0px 10px; margin-left: -5px;">Check this order</button>
<input name="post_type" value="shop_order" type="hidden">
</form>'
));
},100
);
How to send a custom reminder email for WooCommerce On-Hold orders after two days?
By default, Woocommerce doesn’t send out reminder emails for the on-hold emails. With the help of this snippet here you can send a custom reminder email for WooCommerce On-Hold orders after two days of order completion.
NB! Pay attention to the line 8. In it, you can change the remider delay.
add_action( 'restrict_manage_posts', 'wpsh_payment_reminder' );
function wpsh_payment_reminder() {
global $pagenow, $post_type;
if( 'shop_order' === $post_type && 'edit.php' === $pagenow
&& get_option( 'unpaid_orders_reminder_daily_process' ) < time() ) :
$days_delay = 2; // 24 hours
$one_day = 24 * 60 * 60;
$today = strtotime( date('Y-m-d') );
$unpaid_orders = (array) wc_get_orders( array(
'limit' => -1,
'status' => 'on-hold',
'date_created' => '<' . ( $today – ($days_delay * $one_day) ),
) );
if ( sizeof($unpaid_orders) > 0 ) {
$reminder_text = __("Payment reminder email sent to customer $today.", "woocommerce");
foreach ( $unpaid_orders as $order ) {
$order->update_meta_data( '_send_on_hold', true );
$order->update_status( 'reminder', $reminder_text );
$wc_emails = WC()->mailer()->get_emails(); // Get all WC_emails objects instances
$wc_emails['WC_Email_Customer_On_Hold_Order']->trigger( $order->get_id() ); // Send email
}
}
update_option( 'unpaid_orders_reminder_daily_process', $today + $one_day );
endif;
}
add_action ( 'woocommerce_email_order_details', 'wpsh_payment_reminder_notification', 5, 4 );
function wpsh_payment_reminder_notification( $order, $sent_to_admin, $plain_text, $email ){
if ( 'customer_on_hold_order' == $email->id && $order->get_meta('_send_on_hold') ){
$order_id = $order->get_id();
$order_link = wc_get_page_permalink('myaccount').'view-order/'.$order_id.'/';
$order_number = $order->get_order_number();
echo '<h2>'.__("Do not forget about your order.").'</h2>
<p>'.sprintf( __("CUSTOM MESSAGE HERE… %s"),
'<a href="'.$order_link.'">'.__("Your My account order #").$order_number.'<a>'
) .'
// Send a custom reminder email for WooCommerce On-Hold orders after two days of order completion
add_action( 'restrict_manage_posts', 'wpsh_payment_reminder' );
function wpsh_payment_reminder() {
global $pagenow, $post_type;
if( 'shop_order' === $post_type && 'edit.php' === $pagenow
&& get_option( 'unpaid_orders_reminder_daily_process' ) < time() ) :
$days_delay = 2; // 24 hours
$one_day = 24 * 60 * 60;
$today = strtotime( date('Y-m-d') );
$unpaid_orders = (array) wc_get_orders( array(
'limit' => -1,
'status' => 'on-hold',
'date_created' => '<' . ( $today - ($days_delay * $one_day) ),
) );
if ( sizeof($unpaid_orders) > 0 ) {
$reminder_text = __("Payment reminder email sent to customer $today.", "woocommerce");
foreach ( $unpaid_orders as $order ) {
$order->update_meta_data( '_send_on_hold', true );
$order->update_status( 'reminder', $reminder_text );
$wc_emails = WC()->mailer()->get_emails(); // Get all WC_emails objects instances
$wc_emails['WC_Email_Customer_On_Hold_Order']->trigger( $order->get_id() ); // Send email
}
}
update_option( 'unpaid_orders_reminder_daily_process', $today + $one_day );
endif;
}
add_action ( 'woocommerce_email_order_details', 'wpsh_payment_reminder_notification', 5, 4 );
function wpsh_payment_reminder_notification( $order, $sent_to_admin, $plain_text, $email ){
if ( 'customer_on_hold_order' == $email->id && $order->get_meta('_send_on_hold') ){
$order_id = $order->get_id();
$order_link = wc_get_page_permalink('myaccount').'view-order/'.$order_id.'/';
$order_number = $order->get_order_number();
echo '<h2>'.__("Do not forget about your order.").'</h2>
<p>'.sprintf( __("CUSTOM MESSAGE HERE… %s"),
'<a href="'.$order_link.'">'.__("Your My account order #").$order_number.'<a>'
) .'</p>';
$order->delete_meta_data('_send_on_hold');
$order->save();
}
}
How to create custom order status for Woocommerce?
Now let’s take a look at how to create custom order status for Woocommerce. With the help of this snippet I’m going to create a custom status called “In-progress” that is displayed on both backend and front-end order pages.
function register_in_progress_order_status() {
register_post_status( 'wc-invoiced', array(
'label' => _x( 'In-progress', 'Order Status', 'woocommerce' ),
'public' => true,
'exclude_from_search' => false,
'show_in_all_admin_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'In-progress <span class="count">(%s)</span>', 'In-progress <span class="count">(%s)</span>', 'woocommerce' )
)
);
}
add_action( 'init', 'register_in_progress_order_status' );
function my_invoiced_order_status( $order_statuses ){
$order_statuses['wc-invoiced'] = _x( 'In-progress', 'Order Status', 'woocommerce' );
return $order_statuses;
}
add_filter( 'wc_order_statuses', 'my_invoiced_order_status' );
function show_in_bulk_actions() {
global $post_type;
if( 'shop_order' == $post_type ) {
?>
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery('<option>').val('mark_invoiced').text('<?php _e( 'Change Status to In-progress','woocommerce' ); ?>').appendTo("select[name='action']");
jQuery('<option>').val('mark_invoiced').text('<?php _e( 'Change Status to In-progress','woocommerce' ); ?>').appendTo("select[name='action2']");
});
</script>
// Add custom Woocommerce order status
function register_in_progress_order_status() {
register_post_status( 'wc-invoiced', array(
'label' => _x( 'In-progress', 'Order Status', 'woocommerce' ),
'public' => true,
'exclude_from_search' => false,
'show_in_all_admin_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'In-progress <span class="count">(%s)</span>', 'In-progress <span class="count">(%s)</span>', 'woocommerce' )
)
);
}
add_action( 'init', 'register_in_progress_order_status' );
function my_invoiced_order_status( $order_statuses ){
$order_statuses['wc-invoiced'] = _x( 'In-progress', 'Order Status', 'woocommerce' );
return $order_statuses;
}
add_filter( 'wc_order_statuses', 'my_invoiced_order_status' );
function show_in_bulk_actions() {
global $post_type;
if( 'shop_order' == $post_type ) {
?>
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery('<option>').val('mark_invoiced').text('<?php _e( 'Change Status to In-progress','woocommerce' ); ?>').appendTo("select[name='action']");
jQuery('<option>').val('mark_invoiced').text('<?php _e( 'Change Status to In-progress','woocommerce' ); ?>').appendTo("select[name='action2']");
});
</script>
<?php
}
}
add_action( 'admin_footer', 'show_in_bulk_actions' );
How to Filter Woocommerce orders by coupons used?
If you would like to know how to filter Woocommerce orders by coupons used, then it’s just a snippet away. That is, use this one here below.
defined( 'ABSPATH' ) or exit;
// fire it up!
add_action( 'plugins_loaded', 'wc_filter_orders_by_coupon' );
class WC_Filter_Orders_By_Coupon {
const VERSION = '1.1.0';
/** @var WC_Filter_Orders_By_Coupon single instance of this plugin */
protected static $instance;
public function __construct() {
// load translations
add_action( 'init', array( $this, 'load_translation' ) );
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
// adds the coupon filtering dropdown to the orders page
add_action( 'restrict_manage_posts', array( $this, 'filter_orders_by_coupon_used' ) );
// makes coupons filterable
add_filter( 'posts_join', array( $this, 'add_order_items_join' ) );
add_filter( 'posts_where', array( $this, 'add_filterable_where' ) );
}
}
public function filter_orders_by_coupon_used() {
global $typenow;
if ( 'shop_order' === $typenow ) {
$args = array(
'posts_per_page' => – 1,
'orderby' => 'title',
'order' => 'asc',
'post_type' => 'shop_coupon',
'post_status' => 'publish',
);
$coupons = get_posts( $args );
if ( ! empty( $coupons ) ) : ?>
<select name="_coupons_used" id="dropdown_coupons_used">
<option value="">
<?php esc_html_e( 'Filter by coupon used', 'wc-filter-orders' ); ?>
</option>
<?php foreach ( $coupons as $coupon ) : ?>
<option value="<?php echo esc_attr( $coupon->post_title ); ?>" <?php echo esc_attr( isset( $_GET['_coupons_used'] ) ? selected( $coupon->post_title, $_GET['_coupons_used'], false ) : '' ); ?>>
<?php echo esc_html( $coupon->post_title ); ?>
</option>
<?php endforeach; ?>
</select>
// Filter Woocommerce orders by coupons used
defined( 'ABSPATH' ) or exit;
// fire it up!
add_action( 'plugins_loaded', 'wc_filter_orders_by_coupon' );
class WC_Filter_Orders_By_Coupon {
const VERSION = '1.1.0';
/** @var WC_Filter_Orders_By_Coupon single instance of this plugin */
protected static $instance;
public function __construct() {
// load translations
add_action( 'init', array( $this, 'load_translation' ) );
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
// adds the coupon filtering dropdown to the orders page
add_action( 'restrict_manage_posts', array( $this, 'filter_orders_by_coupon_used' ) );
// makes coupons filterable
add_filter( 'posts_join', array( $this, 'add_order_items_join' ) );
add_filter( 'posts_where', array( $this, 'add_filterable_where' ) );
}
}
public function filter_orders_by_coupon_used() {
global $typenow;
if ( 'shop_order' === $typenow ) {
$args = array(
'posts_per_page' => - 1,
'orderby' => 'title',
'order' => 'asc',
'post_type' => 'shop_coupon',
'post_status' => 'publish',
);
$coupons = get_posts( $args );
if ( ! empty( $coupons ) ) : ?>
<select name="_coupons_used" id="dropdown_coupons_used">
<option value="">
<?php esc_html_e( 'Filter by coupon used', 'wc-filter-orders' ); ?>
</option>
<?php foreach ( $coupons as $coupon ) : ?>
<option value="<?php echo esc_attr( $coupon->post_title ); ?>" <?php echo esc_attr( isset( $_GET['_coupons_used'] ) ? selected( $coupon->post_title, $_GET['_coupons_used'], false ) : '' ); ?>>
<?php echo esc_html( $coupon->post_title ); ?>
</option>
<?php endforeach; ?>
</select>
<?php endif;
}
}
public function add_order_items_join( $join ) {
global $typenow, $wpdb;
if ( 'shop_order' === $typenow && isset( $_GET['_coupons_used'] ) && ! empty( $_GET['_coupons_used'] ) ) {
$join .= "LEFT JOIN {$wpdb->prefix}woocommerce_order_items woi ON {$wpdb->posts}.ID = woi.order_id";
}
return $join;
}
public function add_filterable_where( $where ) {
global $typenow, $wpdb;
if ( 'shop_order' === $typenow && isset( $_GET['_coupons_used'] ) && ! empty( $_GET['_coupons_used'] ) ) {
// Main WHERE query part
$where .= $wpdb->prepare( " AND woi.order_item_type='coupon' AND woi.order_item_name='%s'", wc_clean( $_GET['_coupons_used'] ) );
}
return $where;
}
public function load_translation() {
// localization
load_plugin_textdomain( 'wc-filter-orders', false, dirname( plugin_basename( __FILE__ ) ) . '/i18n/languages' );
}
public static function instance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
public function __clone() {
/* translators: Placeholders: %s - plugin name */
_doing_it_wrong( __FUNCTION__, sprintf( esc_html__( 'You cannot clone instances of %s.', 'wc-filter-orders' ), 'Filter WC Orders by Coupon' ), '1.1.0' );
}
public function __wakeup() {
/* translators: Placeholders: %s - plugin name */
_doing_it_wrong( __FUNCTION__, sprintf( esc_html__( 'You cannot unserialize instances of %s.', 'wc-filter-orders' ), 'Filter WC Orders by Coupon' ), '1.1.0' );
}
}
function wc_filter_orders_by_coupon() {
return WC_Filter_Orders_By_Coupon::instance();
}
How to filter WooCommerce orders by payment method?
Now let’s see how to filter WooCommerce orders by payment method. Just use this snippet here below.
defined( 'ABSPATH' ) or exit;
// fire it up!
add_action( 'plugins_loaded', 'wc_filter_orders_by_payment' );
class WC_Filter_Orders_By_Payment {
const VERSION = '1.0.0';
/** @var WC_Filter_Orders_By_Payment single instance of this plugin */
protected static $instance;
public function __construct() {
if ( is_admin() ) {
// add bulk order filter for exported / non-exported orders
add_action( 'restrict_manage_posts', array( $this, 'filter_orders_by_payment_method') , 20 );
add_filter( 'request', array( $this, 'filter_orders_by_payment_method_query' ) );
}
}
public function filter_orders_by_payment_method() {
global $typenow;
if ( 'shop_order' === $typenow ) {
// get all payment methods, even inactive ones
$gateways = WC()->payment_gateways->payment_gateways();
?>
<select name="_shop_order_payment_method" id="dropdown_shop_order_payment_method">
<option value="">
<?php esc_html_e( 'All Payment Methods', 'wc-filter-orders-by-payment' ); ?>
</option>
<?php foreach ( $gateways as $id => $gateway ) : ?>
<option value="<?php echo esc_attr( $id ); ?>" <?php echo esc_attr( isset( $_GET['_shop_order_payment_method'] ) ? selected( $id, $_GET['_shop_order_payment_method'], false ) : '' ); ?>>
<?php echo esc_html( $gateway->get_method_title() ); ?>
</option>
<?php endforeach; ?>
</select>
// Filter Woocommerce orders by payment method
defined( 'ABSPATH' ) or exit;
// fire it up!
add_action( 'plugins_loaded', 'wc_filter_orders_by_payment' );
class WC_Filter_Orders_By_Payment {
const VERSION = '1.0.0';
/** @var WC_Filter_Orders_By_Payment single instance of this plugin */
protected static $instance;
public function __construct() {
if ( is_admin() ) {
// add bulk order filter for exported / non-exported orders
add_action( 'restrict_manage_posts', array( $this, 'filter_orders_by_payment_method') , 20 );
add_filter( 'request', array( $this, 'filter_orders_by_payment_method_query' ) );
}
}
public function filter_orders_by_payment_method() {
global $typenow;
if ( 'shop_order' === $typenow ) {
// get all payment methods, even inactive ones
$gateways = WC()->payment_gateways->payment_gateways();
?>
<select name="_shop_order_payment_method" id="dropdown_shop_order_payment_method">
<option value="">
<?php esc_html_e( 'All Payment Methods', 'wc-filter-orders-by-payment' ); ?>
</option>
<?php foreach ( $gateways as $id => $gateway ) : ?>
<option value="<?php echo esc_attr( $id ); ?>" <?php echo esc_attr( isset( $_GET['_shop_order_payment_method'] ) ? selected( $id, $_GET['_shop_order_payment_method'], false ) : '' ); ?>>
<?php echo esc_html( $gateway->get_method_title() ); ?>
</option>
<?php endforeach; ?>
</select>
<?php
}
}
public function filter_orders_by_payment_method_query( $vars ) {
global $typenow;
if ( 'shop_order' === $typenow && isset( $_GET['_shop_order_payment_method'] ) && ! empty( $_GET['_shop_order_payment_method'] ) ) {
$vars['meta_key'] = '_payment_method';
$vars['meta_value'] = wc_clean( $_GET['_shop_order_payment_method'] );
}
return $vars;
}
public static function instance() {
if ( is_null( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
}
function wc_filter_orders_by_payment() {
return WC_Filter_Orders_By_Payment::instance();
}
How to filter Woocommerce orders by user role?
Next, let’s filter Woocommerce orders by user role. The end result is the one you see on the screenshot here below.
function wpsh_user_role_filter() {
global $typenow, $wp_query;
if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ) ) ) {
$user_role = '';
// Get all user roles
$user_roles = array( 'guest' => 'Guest' );
foreach ( get_editable_roles() as $key => $values ) {
$user_roles[ $key ] = $values['name'];
}
// Set a selected user role
if ( ! empty( $_GET['_user_role'] ) ) {
$user_role = sanitize_text_field( $_GET['_user_role'] );
}
// Display drop down
?><select name='_user_role'>
<option value=''><?php _e( 'Select a user role', 'woocommerce' ); ?></option><?php
foreach ( $user_roles as $key => $value ) :
?><option <?php selected( $user_role, $key ); ?> value='<?php echo $key; ?>'><?php echo $value; ?></option><?php
endforeach;
?></select>
// Filter Woocommerce orders by user role
function wpsh_user_role_filter() {
global $typenow, $wp_query;
if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ) ) ) {
$user_role = '';
// Get all user roles
$user_roles = array( 'guest' => 'Guest' );
foreach ( get_editable_roles() as $key => $values ) {
$user_roles[ $key ] = $values['name'];
}
// Set a selected user role
if ( ! empty( $_GET['_user_role'] ) ) {
$user_role = sanitize_text_field( $_GET['_user_role'] );
}
// Display drop down
?><select name='_user_role'>
<option value=''><?php _e( 'Select a user role', 'woocommerce' ); ?></option><?php
foreach ( $user_roles as $key => $value ) :
?><option <?php selected( $user_role, $key ); ?> value='<?php echo $key; ?>'><?php echo $value; ?></option><?php
endforeach;
?></select><?php
}
}
add_action( 'restrict_manage_posts', 'wpsh_user_role_filter' );
function wpsh_user_role_filter_where( $query ) {
if ( ! $query->is_main_query() || empty( $_GET['_user_role'] ) || $_GET['post_type'] !== 'shop_order' ) {
return;
}
if ( $_GET['_user_role'] != 'guest' ) {
$ids = get_users( array( 'role' => sanitize_text_field( $_GET['_user_role'] ), 'fields' => 'ID' ) );
$ids = array_map( 'absint', $ids );
} else {
$ids = array( 0 );
}
$query->set( 'meta_query', array(
array(
'key' => '_customer_user',
'compare' => 'IN',
'value' => $ids,
)
) );
if ( empty( $ids ) ) {
$query->set( 'posts_per_page', 0 );
}
}
add_filter( 'pre_get_posts', 'wpsh_user_role_filter_where' );
How to display used coupons on WooCommerce admin orders list?
If you would like to display used coupons on WooCommerce admin orders list then use this snippet here below. If no coupons is used then “No coupons used” is displayed. See the screenshot above.
add_filter( 'manage_edit-shop_order_columns', 'woo_customer_order_coupon_column_for_orders' );
function woo_customer_order_coupon_column_for_orders( $columns ) {
$new_columns = array();
foreach ( $columns as $column_key => $column_label ) {
if ( 'order_total' === $column_key ) {
$new_columns['order_coupons'] = __('Coupons', 'woocommerce');
}
$new_columns[$column_key] = $column_label;
}
return $new_columns;
}
add_action( 'manage_shop_order_posts_custom_column' , 'woo_display_customer_order_coupon_in_column_for_orders' );
function woo_display_customer_order_coupon_in_column_for_orders( $column ) {
global $the_order, $post;
if( $column == 'order_coupons' ) {
if( $coupons = $the_order->get_coupon_codes() ) {
echo implode(', ', $coupons) . ' ('.count($coupons).')';
} else {
echo '<small><em>'. __('No coupon used') . '</em>
// Display used coupons on WooCommerce admin orders list
add_filter( 'manage_edit-shop_order_columns', 'woo_customer_order_coupon_column_for_orders' );
function woo_customer_order_coupon_column_for_orders( $columns ) {
$new_columns = array();
foreach ( $columns as $column_key => $column_label ) {
if ( 'order_total' === $column_key ) {
$new_columns['order_coupons'] = __('Coupons', 'woocommerce');
}
$new_columns[$column_key] = $column_label;
}
return $new_columns;
}
add_action( 'manage_shop_order_posts_custom_column' , 'woo_display_customer_order_coupon_in_column_for_orders' );
function woo_display_customer_order_coupon_in_column_for_orders( $column ) {
global $the_order, $post;
if( $column == 'order_coupons' ) {
if( $coupons = $the_order->get_coupon_codes() ) {
echo implode(', ', $coupons) . ' ('.count($coupons).')';
} else {
echo '<small><em>'. __('No coupon used') . '</em></small>';
}
}
}
How to display used coupons on Woocommerce order preview template?
With the previous snippet we’re displaying coupons in the Woocommerce admin orders list. Now, with the help of this one here we’re going to display used coupons on Woocommerce order preview template.
add_filter( 'woocommerce_admin_order_preview_get_order_details', 'wpsh_coupon_in_order_preview', 10, 2 );
function wpsh_coupon_in_order_preview( $data, $order ) {
// Replace '_custom_meta_key' by the correct postmeta key
if( $coupons = $order->get_used_coupons() ) {
$data['coupons_count'] = count($coupons); // <= Store the count in the data array.
$data['coupons_codes'] = implode(', ', $coupons); // <= Store the count in the data array.
}
return $data;
}
// Display coupon in Order preview
add_action( 'woocommerce_admin_order_preview_end', 'wpsh_coupon_in_order_preview_data' );
function wpsh_coupon_in_order_preview_data(){
// Call the stored value and display it
echo '<div><strong>' . __('Coupons used') . ' ({{data.coupons_count}})<strong>: {{data.coupons_codes}}</div>
// Display used coupons on Woocommerce order preview template
add_filter( 'woocommerce_admin_order_preview_get_order_details', 'wpsh_coupon_in_order_preview', 10, 2 );
function wpsh_coupon_in_order_preview( $data, $order ) {
// Replace '_custom_meta_key' by the correct postmeta key
if( $coupons = $order->get_used_coupons() ) {
$data['coupons_count'] = count($coupons); // <= Store the count in the data array.
$data['coupons_codes'] = implode(', ', $coupons); // <= Store the count in the data array.
}
return $data;
}
// Display coupon in Order preview
add_action( 'woocommerce_admin_order_preview_end', 'wpsh_coupon_in_order_preview_data' );
function wpsh_coupon_in_order_preview_data(){
// Call the stored value and display it
echo '<div><strong>' . __('Coupons used') . ' ({{data.coupons_count}})<strong>: {{data.coupons_codes}}</div><br>';
}
How to display customer phone and email in Woocommerce orders table?
Take a look at the screenshot below, and you’ll see that there is a customer phone and email that is displayed in Woocommerce orders table. If you would like to achieve the same result, then use this snippet here below.
add_action( 'manage_shop_order_posts_custom_column' , 'wpsh_phone_and_email_column', 50, 2 );
function wpsh_phone_and_email_column( $column, $post_id ) {
if ( $column == 'order_number' )
{
global $the_order;
// Display customer phone in Woocommerce orders table
if( $phone = $the_order->get_billing_phone() ){
$phone_wp_dashicon = '<span class="dashicons dashicons-phone"></span> ';
echo '<br><a href="tel:'.$phone.'">' . $phone_wp_dashicon . $phone.'</a></strong>';
}
// Display customer email in Woocommerce orders table
if( $email = $the_order->get_billing_email() ){
echo '<br><strong><a href="mailto:'.$email.'">' . $email . '</a>
// Display customer phone and email in Woocommerce orders table
add_action( 'manage_shop_order_posts_custom_column' , 'wpsh_phone_and_email_column', 50, 2 );
function wpsh_phone_and_email_column( $column, $post_id ) {
if ( $column == 'order_number' )
{
global $the_order;
// Display customer phone in Woocommerce orders table
if( $phone = $the_order->get_billing_phone() ){
$phone_wp_dashicon = '<span class="dashicons dashicons-phone"></span> ';
echo '<br><a href="tel:'.$phone.'">' . $phone_wp_dashicon . $phone.'</a></strong>';
}
// Display customer email in Woocommerce orders table
if( $email = $the_order->get_billing_email() ){
echo '<br><strong><a href="mailto:'.$email.'">' . $email . '</a></strong>';
}
}
}
How to add custom button to Woocommerce orders page (and products page)
It’s time to add custom button to Woocommerce orders page (and products page). See the screenshot.
add_action( 'manage_posts_extra_tablenav', 'wpsh_button_on_orders_page', 20, 1 );
function wpsh_button_on_orders_page( $which ) {
global $typenow;
if ( 'shop_order' === $typenow && 'top' === $which ) {
?>
<div class="alignright actions custom">
<button type="submit" name="custom_" style="height:32px;" class="button" value=""><?php
// Change your URL and button text here
echo __( '<a style="text-decoration: none;" href="/wp-admin/edit.php?post_type=product">
Go to products »
</a>', 'woocommerce' ); ?></button>
</div>
<?php
}
}
// Add custom button to Woocommerce products page
add_action( 'manage_posts_extra_tablenav', 'wpsh_button_on_products_page', 20, 1 );
function wpsh_button_on_products_page( $which ) {
global $typenow;
if ( 'product' === $typenow && 'top' === $which ) {
?>
<div class="alignleft actions custom">
<button type="submit" name="custom_" style="height:32px;" class="button" value=""><?php
// Change your URL and button text here
echo __( '<a style="text-decoration: none;" href="/wp-admin/edit.php?post_type=shop_order">
Go to orders »
</a>', 'woocommerce' ); ?></button>
</div>
// Add custom button to Woocommerce orders page
add_action( 'manage_posts_extra_tablenav', 'wpsh_button_on_orders_page', 20, 1 );
function wpsh_button_on_orders_page( $which ) {
global $typenow;
if ( 'shop_order' === $typenow && 'top' === $which ) {
?>
<div class="alignright actions custom">
<button type="submit" name="custom_" style="height:32px;" class="button" value=""><?php
// Change your URL and button text here
echo __( '<a style="text-decoration: none;" href="/wp-admin/edit.php?post_type=product">
Go to products »
</a>', 'woocommerce' ); ?></button>
</div>
<?php
}
}
// Add custom button to Woocommerce products page
add_action( 'manage_posts_extra_tablenav', 'wpsh_button_on_products_page', 20, 1 );
function wpsh_button_on_products_page( $which ) {
global $typenow;
if ( 'product' === $typenow && 'top' === $which ) {
?>
<div class="alignleft actions custom">
<button type="submit" name="custom_" style="height:32px;" class="button" value=""><?php
// Change your URL and button text here
echo __( '<a style="text-decoration: none;" href="/wp-admin/edit.php?post_type=shop_order">
Go to orders »
</a>', 'woocommerce' ); ?></button>
</div>
<?php
}
}
How to set default Woocommerce login page to “Orders” page?
This snippet here below will redirect you to the Woocommerce “Orders” after login.
// Set default Woocommerce login page to "Orders" page
add_action( 'load-index.php', 'wpsh_redirect_to_orders' );
function wpsh_redirect_to_orders(){
wp_redirect( admin_url( 'edit.php?post_type=shop_order' ) );
}
add_filter( 'login_redirect', 'wpsh_redirect_to_orders_dashboard', 9999, 3 );
function wpsh_redirect_to_orders_dashboard( $redirect_to, $request, $user ){
$redirect_to = admin_url( 'edit.php?post_type=shop_order' );
return $redirect_to;
}
How to autocomplete Woocommerce processing orders?
Why would you need to autocomplete Woocommerce processing orders? For example, if you’re selling virtual product (Courses etc.) and you would like to add an access to it right after payments.
// Autocomplete Woocommerce processing orders
add_filter( 'woocommerce_payment_complete_order_status', 'processing_orders_autocomplete', 9999 );
function processing_orders_autocomplete() {
return 'completed';
}
How to autocomplete all Woocommerce orders?
But (just “but) what if you would like to autocomplete all Woocommerce orders? That is evan on-hold orders? If this is the case then use this nippet here below.
// Auto Complete all WooCommerce orders.
add_action( 'woocommerce_thankyou', 'wpsh_complete_all_orders' );
function wpsh_complete_all_orders( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
$order->update_status( 'completed' );
}
How to add the product image to Woocommerce my account order view at My account page?
What do I mean by that? Take a look at the screenshot below, and you’ll see that there’s an image on Woocommerce orders view at My account page.
add_filter( 'woocommerce_order_item_name', 'wpsh_display_product_image_in_order_item', 20, 3 );
function wpsh_display_product_image_in_order_item( $item_name, $item, $is_visible ) {
// Targeting view order pages only
if( is_wc_endpoint_url( 'view-order' ) ) {
$product = $item->get_product(); // Get the WC_Product object (from order item)
$thumbnail = $product->get_image(array( 50, 50)); // Get the product thumbnail (from product object)
if( $product->get_image_id() > 0 )
$item_name = '<div class="item-thumbnail">' . $thumbnail . '
// Display the product thumbnail in Woocommerce order view pages
add_filter( 'woocommerce_order_item_name', 'wpsh_display_product_image_in_order_item', 20, 3 );
function wpsh_display_product_image_in_order_item( $item_name, $item, $is_visible ) {
// Targeting view order pages only
if( is_wc_endpoint_url( 'view-order' ) ) {
$product = $item->get_product(); // Get the WC_Product object (from order item)
$thumbnail = $product->get_image(array( 50, 50)); // Get the product thumbnail (from product object)
if( $product->get_image_id() > 0 )
$item_name = '<div class="item-thumbnail">' . $thumbnail . '</div>' . $item_name;
}
return $item_name;
}