I use the following code to send an admin email when the order status changes from pending to cancelled.
add_action('woocommerce_order_status_pending_to_cancelled', 'cancelled_send_an_email_notification', 10, 2 );
function cancelled_send_an_email_notification( $order_id, $order ){
// Getting all WC_emails objects
$email_notifications = WC()->mailer()->get_emails();
// Sending the email
$email_notifications['WC_Email_Cancelled_Order']->trigger( $order_id );
}
Now I am looking to achieve the same whenever orders are stuck with the status "pending payment".
Does anyone have a solution to this?
As each created order get an initial pending status, to avoid being notified for all orders, you can use the following approach, that will send a daily custom email notification to the admin, with the linked list of pending orders (if any):
add_action('woocommerce_order_status_changed', 'pending_orders_daily_notification', 10, 4 );
function pending_orders_daily_notification( $order_id, $from, $to, $order ){
// Check daily for pending orders
if ( get_option('wc_daily_check_for_pending_orders', date("Y-m-d") ) >= date("Y-m-d") ) {
// Get pending orders
$_orders = wc_get_orders( array(
'limit' => -1,
'status' => 'pending',
'date_created' => '<' . date('Y-m-d H:i:s', strtotime("-1 day") ), // 1 day older at least
) );
$email_subject = __( 'List of remaining pending orders' );
$message_body = '<html>
<head></head>
<body>
<h1>'. __( 'Pending Orders List' ) .'</h1>';
$count = 0; // Initialize counter
// Loop through WC_Order objects
foreach ( $_orders as $_order ) {
if ( ! $_order->get_meta('_pending_notification') ) {
$message_body .= sprintf(
'<p><a href="%s">' . __('Order number #%s created on %s') . '</a></p>',
admin_url('admin.php?page=wc-orders&action=edit&id=' . $_order->get_id() ), $_order->get_id(),
$_order->get_date_created()->format('Y-m-d')
);
$_order->update_meta_data('_pending_notification', '1'); // Tag the order as notified
$count++;
}
}
$message_body .= '</body></html>';
if ( $count > 0 ) {
$mailer = WC()->mailer(); // load the mailer class.
$recipient = $mailer->get_emails()['WC_Email_New_Order']->recipient; // Get admin recipient
$message = $mailer->wrap_message( $email_subject, $message_body );
$mailer->send( $recipient, $email_subject, $message ); // Sending email notification
}
// Add one day to the initial check
update_option('wc_daily_check_for_pending_orders', date("Y-m-d", strtotime("+1 day") ) );
}
}
Untested, it could work.
Note: Listed orders are at least 1 day old, to avoid listing orders that are being processed by WooCommerce. You can adjust fine tune that by changing "-1 day" to "-3 hours" for example.
Here, the links for each order are going to the admin edit order for High Performance order Storage enabled. If it's not the case you will have to adjust the string inside admin_url()
function.