Cancel WooCommerce not-paid Orders automatically

One way to keep your online store clean and organized is using the order status. Complete, Cancelled, Awaiting Payment are type of status which helps you to pay attention at the most important orders.

But when you have a lot of “Awaiting payment” orders and you don’t know until when you need to consider that order? Well I’m writing today because of that. A client of mine gave me this problem: I want to cancel my pending orders (awaiting payment) after 4 days.

Before the solution we discuss about:

  • Should we need to consider all the payment methods?
  • The client should be receive any type of email confirm?
  • Which order status we need to consider?

Well, those answers aren’t too important for this post. 🙂 But after that, I started to code. Follow me, step by step:

1. Create a query with WooCommerce orders.

$query = ( 
   array(
	'limit'   => 5,
	'orderby' => 'date',
	'order'   => 'DESC',
	'status'  => array( 'pending' )
   ) 
);

$orders = wc_get_orders( $query );

// our orders loop
foreach( $orders as $order ){		
		
}

For performance reasons, I’m getting only 5 orders each time I run my snippet. Pay attention at “status” array, where you need to replace by the status you want to consider. We have a lot of status in WooCommerce, like “on-hold”, “completed”, “cancelled”, etc…

2. Check the number of days between order name and today

Inside the loop I wrote above, we will check the time difference and to know the “age” of your order.

foreach( $orders as $order ){		
  
  // date of our order
  $date = new DateTime( $order->get_date_created() );
  // today's date
  $today = new DateTime();
  
  $interval = $date->diff($today);
  // days between order name and today	
  $datediff = $interval->format('%a');
   
  // 4: minimum of days the order can be considered
  if( $datediff >= 4 ){
    $order->update_status('cancelled', 'Cancelled for missing payment);
   }
		
	}

Right now, the code says: “If the order is pending (as we defined on query) and it has more than 4 days, we will update the order status to “cancelled”, adding a status note (Cancelled for missing payment).

3. Tell to WordPress when to run our function

Considering that you put our code into a function like that:


function autocancel_wc_orders(){
	$query = ( array(
		'limit'   => 5,
		'orderby' => 'date',
		'order'   => 'DESC',
		'status'  => array( 'pending' )
	) );
	$orders = wc_get_orders( $query );
	foreach( $orders as $order ){		

		$date     = new DateTime( $order->get_date_created() );
		$today    = new DateTime();
		$interval = $date->diff($today);
	
		$datediff = $interval->format('%a');

		if( $datediff >= 4 ){
			$order->update_status('cancelled', 'Cancelled for missing payment');
		}
		
	}

}

Now we just need to select a WordPress action to run this. Just as it is only 5 orders each time, I decided to use the simple admin_init action. We can use a lot of alternatives, like WPcron or something, but for this case I think it was the best way: nice performance, admin security and without dependencies need 🙂

add_action( 'admin_init', 'autocancel_wc_orders' );

That’s all. It was simple? If you want to discuss this or you have a better way to make this, please let me know at the comment area.

Cheers.

Leave a comment

Your email address will not be published. Required fields are marked *