skip to Main Content

based on Automatically cancel order after X days if no payment in WooCommerce answer code, I have make some changes trying to autocomplete paid orders after x Minutes (or x hours):

    add_action( 'woocommerce_order_status_changed', 'hourly_update_status_orders', 10, 4 );
function hourly_update_status_orders( $order_id, $old_status, $new_status, $order ) {
    // Set Your shop time zone (http://php.net/manual/en/timezones.php)
    date_default_timezone_set('Europe/London');

    // Enable the process to be executed daily
    if( in_array( $new_status, array('processing') )
        && get_option( 'paid_orders_hourly_process' ) < time() ) :
    
        $time_delay       = 60 * 5; // <=== SET the time delay (here 1 hour)
        $current_time     = strtotime(str_replace(':','-', date('Y-m-d h:i:s') ));
        $targeted_time    = $current_time - $time_delay;

    // Get paid orders (10 mints old)
    $paid_orders = (array) wc_get_orders( array(
        'limit'        => -1,
        'status'       => 'processing',
        'date_created' => '<' . $targeted_time,
        'return' => 'ids',
    ) );

    if ( sizeof($paid_orders) > 0 ) {
        $completed_text = __("The order is Completed.", "woocommerce");

        // Loop through WC_Order Objects
        foreach ( $paid_orders as $paid_order ) {
            $order->update_status( 'completed', $complted_text );
        }
    }
    // Schedule the process to the next day (executed once restriction)
    update_option( 'paid_orders_hourly_process', $current_time + $time_delay );

    endif;
}

I can only make it work for a daily change, but not for an hourly changeā€¦

Could someone help me to check where I am wrong?

2

Answers


  1. Chosen as BEST ANSWER

    Now i am using this code its look more efficient then previous. but still having interval problem. when status change from processing to complete no interval between them.

    add_action( 'woocommerce_thankyou', 'woocommerce_thankyou_change_order_status', 10, 1 );
    function woocommerce_thankyou_change_order_status( $order_id ){
        if( ! $order_id ) return;
    
        $order = wc_get_order( $order_id );
    
        $time_order     = strtotime($order->get_date_created()->date('Y-m-d H:i:s'));
        $time_current   = time();
        $time_interval  = $time_current - $time_order;
    
        //Case refresh page after 3 hours at order, no changed status
        if( $order->get_status() == 'processing' && $time_interval < 18000 ) {
            $order->update_status( 'completed' );
        }
    }
    

  2. Updated

    Those solutions are really not made and not very effective for an hourly delay (or less) as the code is triggered when a new order is made (or when admin make a manual change on an order status.

    Now there are some mistakes in your code, try the following instead (untested):

    add_action( 'woocommerce_order_status_changed', 'hourly_update_status_orders', 10, 4 );
    function hourly_update_status_orders( $order_id, $old_status, $new_status, $order ) {
        // Set Your shop time zone (http://php.net/manual/en/timezones.php)
        date_default_timezone_set('Europe/Paris');
    
        // Enable the process to be executed daily
        if( in_array( $new_status, array('processing') )
            && get_option( 'paid_orders_hourly_process' ) < time() ) :
    
        $time_delay       = 60 * 60; // <=== SET the time delay (here 1 hour)
        $current_time     = strtotime( date('Y-m-d H:00:00') );
        $targeted_time    = $current_time - $time_delay;
    
        // Get paid orders (10 mints old)
        $paid_orders = (array) wc_get_orders( array(
            'limit'        => -1,
            'status'       => 'processing',
            'date_created' => '<' . $targeted_time,
            'return' => 'ids',
        ) );
    
        if ( sizeof($paid_orders) > 0 ) {
            $completed_text = __("The order is Completed.", "woocommerce");
    
            // Loop through WC_Order Objects
            foreach ( $paid_orders as $paid_order ) {
                $order->update_status( 'completed', $complted_text );
            }
        }
        // Schedule the process to the next day (executed once restriction)
        update_option( 'paid_orders_hourly_process', $current_time + $time_delay );
    
        endif;
    }
    

    Code goes in functions.php file of the active child theme (or active theme).


    If you use minutes instead of hours, you should change:

    $current_time     = strtotime( date('Y-m-d H:00:00') );
    

    to:

    $current_time     = strtotime( date('Y-m-d H:i:00') );
    

    Final note – A better alternative.

    Is better to use something else like the free plugin Action scheduler made by Automatic (the owners of WordPress and WooCommerce) that is a robust scheduling library already included and used by WooCommerce and the plugin Subscriptions.

    You can use it in any code and it’s a much better alternative than anything else.

    Here is the documentation usage: https://actionscheduler.org/usage/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search