How to automatically change woocommerce processing status to completed - php

How to change in woocommerce order status from processing to completed
?
I found snippet, but it only changes status if you go to thank you page, but if my customer decides just to close paypal page and don't go to thank you page ?
Then it is still processing, tested it already. I need automatically to detect processing status and change it to processing.

This will check for when the order changes status. If the status changes to processing, it will set the status to completed. Note that it does go through processing, so the user will probably get two emails back to back. You can disable one of the emails in the WC settings dashboard.
function wc_status_change($order_id,$old_status,$new_status) {
$order = new WC_Order( $order_id );
if($order->status == 'processing'){
$order->update_status('completed');
}
}

In your case you have two options the first may not work as it is related to previous versions of woocommerce but the second one should work
add the code to your functions.php
1º
add_filter( 'woocommerce_payment_complete_order_status', 'update_order_status_woo', 10, 2 );
function update_order_status_woo( $order_status, $order_id ) {
$order = new WC_Order( $order_id );
if ( $order_status == 'processing' && ( 'on-hold' == $order->status || 'pending' == $order->status || 'failed' == $order->status ) ) {
return 'completed';
}
return $order_status;
}
2º
add_action('woocommerce_order_status_changed', 'auto_update_processing_to_complete');
function auto_update_processing_to_complete($order_id)
{
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
if ($order->data['status'] == 'processing') {
$order->update_status( 'completed' );
}
}

Related

Woocommerce change status based on payment method

I would like to immidialtey change the order status from specific orders (payment method = stripe_sofort) to a custom status, that I already have in use:
add_action( 'woocommerce_thankyou', 'woocommerce_auto_processing_orders');
function woocommerce_auto_processing_orders( $order_id ) {
if ( ! $order_id )
return;
$order = wc_get_order( $order_id );
// If order is "on-hold" update status to "processing-melle"
if( $order->get_payment_method() == 'stripe_sofort' && $order->has_status( 'on-hold' ) ) {
$order->update_status( 'my_status' );
}
}
this code does not work, but I actually don't understand why. do you guys have an idea?
thanks!

PHP code for automatically change WooCommerce order status

I would like to change the status of every new WooCommerce order depending on a custom field (shopart) with PHP.
I already tried to write a function in the functions.php file but I failed.
// set Custom Order Status at WooCommerce Checkout Process
add_action( 'woocommerce_thankyou', 'uebes_thankyou_change_order_status' );
function uebes_thankyou_change_order_status( $order_id ){
if( ! $order_id ) return;{
$order = wc_get_order( $order_id );
// update order status dependimg to custom field shopart
if(get_post_meta($order->id,'shopart',true) == 'Shop Vorbestellungen'){
$order->update_status( 'vorbestellung' );
}else{
$order->update_status( 'bestellung-neu' );
}
}
}
// set Custom Order Status at WooCommerce Checkout Process
add_action('woocommerce_thankyou', 'uebes_thankyou_change_order_status', 10, 1);
function uebes_thankyou_change_order_status($order_id) {
if (!$order_id)
return;
//create an order instance
$order = wc_get_order($order_id);
// update order status dependimg to custom field shopart
if (get_post_meta($order_id, 'shopart', true) == 'Shop Vorbestellungen') {
$order->update_status('vorbestellung');
} else {
$order->update_status('bestellung-neu');
}
}

Hide order statuses in dropdown based on order status in WooCommerce edit order page

I want to hide order statuses in the WooCommerce order status dropdown under specific scenarios:
If status is pending payment hide completed
If status is processing hide pending payment
I still want to display all these order statuses in the order overview list.
All I can find is to unset an order status completely:
function so_39252649_remove_processing_status ($statuses) {
if (isset($statuses['wc-processing'])) {
unset($statuses['wc-processing']);
}
return $statuses;
}
add_filter('wc_order_statuses', 'so_39252649_remove_processing_status');
But this will of course also remove it from the order overview list, I just want to hide it in the dropdown on the order edit page, but I cant find a hook for this.
Is jQuery my only choice for this?
You can use the following, comments with explanations added in the code.
So you get:
// Admin order edit page: order status dropdown
function filter_wc_order_statuses( $order_statuses ) {
global $post, $pagenow;
// Target edit pages
if( $pagenow === 'post.php' && isset($_GET['post']) && $_GET['action'] == 'edit' && get_post_type($_GET['post']) === 'shop_order' ) {
// Get ID
$order_id = $post->ID;
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
// Is a WC order
if ( is_a( $order, 'WC_Order' ) ) {
// Get current order status
$order_status = $order->get_status();
// Compare
if ( $order_status == 'pending' ) {
unset( $order_statuses['wc-completed'] );
} elseif ( $order_status == 'processing' ) {
unset( $order_statuses['wc-pending'] );
}
}
}
return $order_statuses;
}
add_filter( 'wc_order_statuses', 'filter_wc_order_statuses', 10, 1 );

Avoid repetitive emails notification on some auto completed orders

I'm using this little peace of code on WooCommerce from this answer to auto-complete paid processing orders based on payment gateways:
/**
* AUTO COMPLETE PAID ORDERS IN WOOCOMMERCE
*/
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_paid_order', 10, 1 );
function custom_woocommerce_auto_complete_paid_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
// No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
if ( ( get_post_meta($order->id, '_payment_method', true) == 'bacs' ) || ( get_post_meta($order->id, '_payment_method', true) == 'cod' ) || ( get_post_meta($order->id, '_payment_method', true) == 'cheque' ) ) {
return;
}
// "completed" updated status for paid Orders with all others payment methods
else {
$order->update_status( 'completed' );
}
}
This is working mostly perfect
Mainly using a special payment gateway by SMS which API is bridged on 'cod' payment method and that can process payment after 'woocommerce_thankyou, out side frontend. In that case the ON HOLD status orders are passed afterward to PROCESSING status. To automate an autocomplete behavior on those cases, I use this other peace of code from this answer and it works:
function auto_update_orders_status_from_processing_to_completed(){
// Get all current "processing" customer orders
$processing_orders = wc_get_orders( $args = array(
'numberposts' => -1,
'post_status' => 'wc-processing',
) );
if(!empty($processing_orders))
foreach($processing_orders as $order)
$order->update_status( 'completed' );
}
add_action( 'init', 'auto_update_orders_status_from_processing_to_completed' );
THE PROBLEM: I am getting repetitive emails notifications concerning the new completed orders.
How can I avoid this repetitive email notifications cases?
Thanks
Updated (2019)
Added version code for Woocommerce 3+ - Added Woocommerce version compatibility.
To avoid this strange fact of repetitive email notifications, is possible to create a custom meta key/value for each processed order, when changing order status to completed, using WordPress update_post_meta() function. Then we will test before in a condition, if this custom meta data key/value exist with get_post_meta() function for each processed order.
So your two code snippets will be now:
1) AUTO COMPLETE PAID ORDERS IN WOOCOMMERCE (2019 update)
For woocommerce 3+:
add_action( 'woocommerce_payment_complete_order_status', 'wc_auto_complete_paid_order', 10, 3 );
function wc_auto_complete_paid_order( $status, $order_id, $order ) {
if ( ! $order->has_status('completed') && $order->get_meta('_order_processed') != 'yes') {
$order->update_meta_data('_order_processed', 'yes');
$status = 'completed';
}
return $status;
}
For all woocommerce versions (compatibility since version 2.5+):
add_action( 'woocommerce_payment_complete_order_status', 'wc_auto_complete_paid_order', 10, 3 );
function wc_auto_complete_paid_order( $status, $order_id, $order = null ) {
// Getting the custom meta value regarding this autocomplete status process
$order_processed = get_post_meta( $order_id, '_order_processed', true );
// Getting the WC_Order object from the order ID
$order = wc_get_order( $order_id );
if ( ! $order->has_status( 'completed' ) && $order_processed != 'yes' ) {
$order = wc_get_order( $order_id );
// setting the custom meta data value to yes (order updated)
update_post_meta($order_id, '_order_processed', 'yes');
$order->update_status( 'completed' ); // Update order status to
}
return $status;
}
2) SCAN ALL "processing" orders to auto-complete them (added Woocommerce compatibility)
add_action( 'init', 'auto_update_orders_status_from_processing_to_completed' );
function auto_update_orders_status_from_processing_to_completed(){
if( version_compare( WC_VERSION, '3.0', '<' ) {
$args = array('numberposts' => -1, 'post_status' => 'wc-processing'); // Before WooCommerce version 3
} else {
$args = array('limit' => -1, 'status' => 'processing'); // For WooCommerce 3 and above
}
// Get all current "processing" customer orders
$processing_orders = (array) wc_get_orders( $args );
if( sizeof($processing_orders) > 0 ){
foreach($processing_orders as $order ) {
// Woocommerce compatibility
$order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
// Checking if this custom field value is set in the order meta data
$order_processed = get_post_meta( $order_id, '_order_processed', true );
if (! $order->has_status( 'completed' ) && $order_processed != 'yes' ) {
// Setting (updating) custom meta value in the order metadata to avoid repetitions
update_post_meta( $order_id, '_order_processed', 'yes' );
$order->update_status( 'completed' ); // Updating order status
}
}
}
}
Code goes in function.php file of your active child theme (or theme). Or also in any plugin php files.
I have test this code and it should work for you (due to your particular SMS bridged payment method)

Auto completed status for all existing processing orders in WooCommerce

I am using on WooCommerce this little peace of code from this answer to autocomplete paid processing orders:
/**
* AUTO COMPLETE PAID ORDERS IN WOOCOMMERCE
*/
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_complete_paid_order', 10, 1 );
function custom_woocommerce_auto_complete_paid_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
// No updated status for orders delivered with Bank wire, Cash on delivery and Cheque payment methods.
if ( ( get_post_meta($order->id, '_payment_method', true) == 'bacs' ) || ( get_post_meta($order->id, '_payment_method', true) == 'cod' ) || ( get_post_meta($order->id, '_payment_method', true) == 'cheque' ) ) {
return;
}
// "completed" updated status for paid Orders with all others payment methods
else {
$order->update_status( 'completed' );
}
}
But the problem is that I use a special payment gateway by SMS which API is bridged on 'cod' payment method, and the orders stay sometimes in on-hold status on this 'woocommerce_thankyou' hook.
So I will need to scan all the time the 'processing' orders to pass them in complete status. I have tried different things and hooks, but I cant get it work as expected.
How can I do this?
Thanks
To get this working you just need a little function that will scan all orders with a "processing" status on the 'init' hook, and that will update this status to "completed".
Here is that code:
function auto_update_orders_status_from_processing_to_completed(){
// Get all current "processing" customer orders
$processing_orders = wc_get_orders( $args = array(
'numberposts' => -1,
'post_status' => 'wc-processing',
) );
if(!empty($processing_orders))
foreach($processing_orders as $order)
$order->update_status( 'completed' );
}
add_action( 'init', 'auto_update_orders_status_from_processing_to_completed' );
This code is tested and works.
Code goes in function.php file of your active child theme (or theme). Or also in any plugin php files.
ADVICE & UPDATE
There is a little bug around email notifications sent twice that is solved in here:
Avoid repetitive emails notification on some auto completed orders
WooCommerce virtual orders can be automatically marked as ‘completed’ after payment with a little bit of code added to a custom plugin, or your themes functions.php file. By default WooCommerce will mark virtual-downloadable orders as ‘completed’ after successful payment, which makes sense, but some store owners will want to be able to automatically mark even a virtual order as complete upon payment, for instance in the case of a site which takes donations where no further action is required. To do so, use the following code, which is based on the core virtual-downloadable completed order status:
add_filter( 'woocommerce_payment_complete_order_status', 'virtual_order_payment_complete_order_status', 10, 2 );
function virtual_order_payment_complete_order_status( $order_status, $order_id ) {
$order = new WC_Order( $order_id );
if ( 'processing' == $order_status &&
( 'on-hold' == $order->status || 'pending' == $order->status || 'failed' == $order->status ) ) {
$virtual_order = null;
if ( count( $order->get_items() ) > 0 ) {
foreach( $order->get_items() as $item ) {
if ( 'line_item' == $item['type'] ) {
$_product = $order->get_product_from_item( $item );
if ( ! $_product->is_virtual() ) {
// once we've found one non-virtual product we know we're done, break out of the loop
$virtual_order = false;
break;
} else {
$virtual_order = true;
}
}
}
}
// virtual order, mark as completed
if ( $virtual_order ) {
return 'completed';
}
}
// non-virtual order, return original status
return $order_status;
}
OR
You can also use plugin for auto complete order
Here is the plugin URL : https://wordpress.org/plugins/woocommerce-autocomplete-order/screenshots/
Please let me know which is use full to you.
Thnaks.

Categories