WooCommerce will schedule a task to cancel any unpaid orders. The number of minutes after which the unpaid orders will be cancelled is specified at WooCommerce -> Settings -> Products -> Inventory -> Hold stock (minutes).
Ordinarily, this function will cancel any & all orders but it can be modified & overridden to, for example, only cancel orders which are of a specific status, or of a specific payment method.
The original wc_cancel_unpaid_orders function can be viewed at the WooCommerce Code Reference.
In the following code snippet, I’ve modified & overridden the function, changing it such that orders with the offline_cc payment method are not scheduled to be cancelled. See if you can spot where the change was made.
/** * Cancel all unpaid orders except offline_cc after held duration to prevent stock lock for those products. */ remove_action( 'woocommerce_cancel_unpaid_orders', 'wc_cancel_unpaid_orders' ); add_action( 'woocommerce_cancel_unpaid_orders', 'my_custom_wc_cancel_unpaid_orders' ); function my_custom_wc_cancel_unpaid_orders() { $held_duration = get_option( 'woocommerce_hold_stock_minutes' ); if ( $held_duration < 1 || 'yes' !== get_option( 'woocommerce_manage_stock' ) ) { return; } $data_store = WC_Data_Store::load( 'order' ); $unpaid_orders = $data_store->get_unpaid_orders( strtotime( '-' . absint( $held_duration ) . ' MINUTES', current_time( 'timestamp' ) ) ); if ( $unpaid_orders ) { foreach ( $unpaid_orders as $unpaid_order ) { $order = wc_get_order( $unpaid_order ); if ( apply_filters( 'woocommerce_cancel_unpaid_order', 'checkout' === $order->get_created_via(), $order ) && get_post_meta( $order->id, '_payment_method', true ) != 'offline_cc' ) { $order->update_status( 'cancelled', __( 'Unpaid order cancelled - time limit reached.', 'woocommerce' ) ); } } } wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' ); wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' ); }
No Comments Yet