wc_cancel_unpaid_orders()WC 1.0

Cancel all unpaid orders after held duration to prevent stock lock for those products.

Returns

null. Nothing (null).

Usage

wc_cancel_unpaid_orders();

wc_cancel_unpaid_orders() code WC 10.5.0

function wc_cancel_unpaid_orders() {
	$held_duration = get_option( 'woocommerce_hold_stock_minutes', '60' );

	// Clear existing scheduled events (both Action Scheduler and WP-Cron).
	if ( function_exists( 'as_unschedule_all_actions' ) ) {
		as_unschedule_all_actions( 'woocommerce_cancel_unpaid_orders' );
	}
	// Always clear WP-Cron events as well in case they exist.
	wp_clear_scheduled_hook( 'woocommerce_cancel_unpaid_orders' );

	// Check if we should reschedule. Don't reschedule if stock management is disabled or hold duration is not set.
	if ( $held_duration < 1 || 'yes' !== get_option( 'woocommerce_manage_stock' ) ) {
		return;
	}

	/**
	 * Filters the interval at which to cancel unpaid orders in minutes.
	 *
	 * @since 5.1.0
	 *
	 * @param int $cancel_unpaid_interval The interval at which to cancel unpaid orders in minutes.
	 */
	$cancel_unpaid_interval = apply_filters( 'woocommerce_cancel_unpaid_orders_interval_minutes', absint( $held_duration ) );

	// Don't reschedule if the interval is 0 to prevent endless loops.
	if ( $cancel_unpaid_interval < 1 ) {
		return;
	}

	// Schedule the next event using Action Scheduler if available, otherwise fall back to WordPress cron.
	if ( function_exists( 'as_schedule_single_action' ) ) {
		as_schedule_single_action( time() + ( absint( $cancel_unpaid_interval ) * 60 ), 'woocommerce_cancel_unpaid_orders', array(), 'woocommerce', false );
	} else {
		wp_schedule_single_event( time() + ( absint( $cancel_unpaid_interval ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
	}

	$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 ) ) {
				$order->update_status( OrderStatus::CANCELLED, __( 'Unpaid order cancelled - time limit reached.', 'woocommerce' ) );
			}
		}
	}
}