0
votes

I Need to cancel the on-hold orders in a certain scenario after 4 hours from creating the order.

Example: 2 Customers

1st Customer Make Order at 5:00 PM so its on-hold status ( i want it to be canceled after 4 hours from the creation date of the order if he didn't pay so it has to be canceled on 9:00 PM )

2nd Customer Make Order at 5:37 so Its on-hold status ( i want it to be canceled after 4 hours too from the creation date of the order if he didn't pay so it has to be canceled on 9:37 )

I want it to cancel the orders immediately after each order is expired after 4 hours from the creation date of the order separately not as a cron job to work each 4 hours so in the previous example if the cron event starts at 6:00 PM and will run each 4 hours so the first customer order will expire on 10:00 PM and the 2nd will expire on 10:00 PM too.

I have tried the solution here Automatically cancel order after X days if no payment in WooCommerce

but couldn't make it expire after 4 hours as its defined in days only, also didn't know which answer of them is the best for me scenario to run for each order to be canceled separately after 4 hours from the creation date not as a cron event,

I used many of the solutions mentioned in the related question above but only that works the first answer as i remember which is when admin/shop manager visits the orders page .. i need it to be done automatically without any actions from humans.

Here is my code in the plugin to cancel the orders

<?php


function ash2osh_faw_get_unpaid_submitted() {        
        global $wpdb;
          $options = get_option('woocommerce_' . ASH2OSH_FAW_PAYMENT_METHOD . '_settings');
        $expire_hours =  $options['unpaid_expire'];
        if(!trim($expire_hours)){
            $expire_hours='48';
        }
        $unpaid_submitted = $wpdb->get_col( $wpdb->prepare( "
                SELECT posts.ID
                FROM {$wpdb->posts} AS posts
                WHERE posts.post_status = 'wc-on-hold'
                AND posts.post_date < %s
        ", date( 'Y-m-d H:i:s', strtotime('-'.$expire_hours.' hours') ) ) ); 

        return $unpaid_submitted;
}

function ash2osh_faw_wc_cancel_unpaid_submitted() {        
        $unpaid_submit = ash2osh_faw_get_unpaid_submitted();

        if ( $unpaid_submit ) {                
                foreach ( $unpaid_submit as $unpaid_order ) {                        
                        $order = wc_get_order( $unpaid_order );
                        $cancel_order = True;

                        foreach  ( $order->get_items() as $item_key => $item_values) {                                
                                $manage_stock = get_post_meta( $item_values['variation_id'], '_manage_stock', true );
                                if ( $manage_stock == "no" ) {                                        
                                        $payment_method = $order->get_payment_method();                                        
                                        if ( $payment_method == "cheque" ) {
                                                $cancel_order = False;
                                        }
                                }                                
                        }
                        if ( $cancel_order == True ) {
                                $order -> update_status( 'cancelled', __( 'Unpaid submission expired after hours set in payment plugin options.', 'woocommerce') );
                        }
                }
        }        
}
add_action( 'woocommerce_cancel_unpaid_submitted', 'ash2osh_faw_wc_cancel_unpaid_submitted' );//for customization purposes

This third solution here: Automatically cancel order after X days if no payment in WooCommerce is tested and works fine: BUT i want it to be canceled when the order is on-hold status not completed/processing and to be canceled if its passed 4 hours after the order creation date and this to be scheduled and run each 30 min not daily

1

1 Answers

0
votes

have you tried this? Woocommerce auto cancel On-Hold after X days. I have the same problem as you (but with a 72 hour cancellation time) and also no payment gateway restriction, so this is my code:

function get_unpaid_submitted() {        
    global $wpdb;

    $unpaid_submitted = $wpdb->get_col( $wpdb->prepare( "
        SELECT posts.ID
        FROM {$wpdb->posts} AS posts
        WHERE posts.post_status = 'wc-on-hold'
        AND posts.post_date < %s
        ", date( 'Y-m-d H:i:s', strtotime('-72 hours') ) ) );

    return $unpaid_submitted;
}
function wc_cancel_unpaid_submitted() {
    $unpaid_submit = get_unpaid_submitted();
    if ( $unpaid_submit ) {                
        foreach ( $unpaid_submit as $unpaid_order ) {                        
            $order = wc_get_order( $unpaid_order );
            $order -> update_status( 'cancelled', __( 'Orden cancelada por falt de pago.', 'woocommerce') );
        }
    }        
}
add_action('woocommerce_cancel_unpaid_submitted', 'wc_cancel_unpaid_submitted',10);