I want to dissable this option:
Whenever someone makes and order on my site and the payment is successfull the order status automaticaly changes from pending to processing.
However I don`t want this feature to have enabled. Rather I want to do it manually when i proces the orders.
I found this function in the woocommerce which is making this feature possible. I don`t want to directly change it there but rather with some kind of php snippet which overrides this function.
Here is the function which i need to change : http://woocommerce.wp-a2z.org/oik_api/wc_orderpayment_complete/
PS: I just having a hard time to do it correctly.
Update
May be this payment_complete() is not involved in the process you are looking for. Alternatively, what you could try is the woocommerce_thankyou action hook instead:
add_action( 'woocommerce_thankyou', 'thankyou_order_status', 10, 1 );
function thankyou_order_status( $order_id ){
if( ! $order_id ) return;
$order = new WC_Order( $order_id ); // Get an instance of the WC_Order object
if ( $order->has_status( 'processing' ) )
$order-> update_status( 'pending' )
}
You can use the same alternative hook: woocommerce_thankyou_{$order->get_payment_method()} (replacing $order->get_payment_method() by the payment method ID slug)
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on Woocommerce 3+ and works.
Using a custom function hooked in woocommerce_valid_order_statuses_for_payment_complete filter hook, where you will return the desired orders statuses that can be taken by the related function payment_complete() which is responsible of auto change the order status.
By default the array of order statuses in the filter is:
array( 'on-hold', 'pending', 'failed', 'cancelled' ).
And we can remove 'on-hold' order status this way:
add_filter( 'woocommerce_payment_complete_order_status', 'disable_auto_order_status', 10, 2 );
function disable_auto_order_status( $order_statuses, $order ) {
$return array( 'pending', 'failed', 'cancelled' );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested on Woocommerce 3+ and works.
Add the following code to your functions.php file.function
ja_order_status( $order_status, $order_id ) {
$order = new WC_Order( $order_id );
if ( 'processing' == $order_status ) {
return 'pending';
}
return $order_status;
}
add_filter( 'woocommerce_payment_complete_order_status', 'ja_order_status', 10, 2 );
Tested on WooCommerce with Storefront paid via Stripe test mode.
Related
In WooCommerce, I need all my orders to go immediately to "processing" status to have the order-processing email sent directly when the order is processed.
By default, this behavior exist for Paypal and COD orders, but not for BACS and Cheque where the default status is on-hold.
I tried several snippets like this one:
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_process_order' );
function custom_woocommerce_auto_process_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
$order->update_status( 'processing' );
}
But this doesn't work, the order still shows up in "on-hold" status and the processing email notification is not sent. Now I just found a this snippet:
add_filter( 'woocommerce_bacs_process_payment_order_status', function( $status = 'on_hold', $order = null ) {
return 'processing';
}, 10, 2 );
And it works, but only for "BACS". How can I adapt it to also work for "Cheque" orders?
The filter hook woocommerce_cheque_process_payment_order_status is not yet implemented in Woocommerce 3.5.7 … if you look to the file located in your woocommerce plugin under: includes > gateways > cheque > class-wc-gateway-cheque.php, the hook is missing (line 122):
$order->update_status( 'on-hold', _x( 'Awaiting check payment', 'Check payment method', 'woocommerce' ) );
But on Github WC version 3.5.7 for class-wc-gateway-cheque.php file, the hook exist (line 122):
$order->update_status( apply_filters( 'woocommerce_cheque_process_payment_order_status', 'on-hold', $order ), _x( 'Awaiting check payment', 'Check payment method', 'woocommerce' ) );
The hook will is planed to be available next WooCommerce 3.6 release, see the file change on Woocommerce Github. It's tagged 3.6.0-rc.2 and 3.6.0-beta.1
So it will be possible to change the default order status to "processing" for "bacs" and "cheque" payment methods, using the following:
add_filter( 'woocommerce_bacs_process_payment_order_status','filter_process_payment_order_status_callback', 10, 2 );
add_filter( 'woocommerce_cheque_process_payment_order_status','filter_process_payment_order_status_callback', 10, 2 );
function filter_process_payment_order_status_callback( $status, $order ) {
return 'processing';
}
Code goes in functions.php file of your active child theme (or active theme).
You're almost there. Right now you are adding a filter for the BACS hook. There is a similar hook for Cheque payment method.
Simply add the following code:
add_filter(
'woocommerce_cheque_process_payment_order_status',
function( $status = 'on_hold', $order = null ) {
return 'processing';
}, 10, 2
);
It does the exact same, but just for the Cheque orders.
In Woocommerce, when the payment option is COD, the orders go directly to the "Processing" state.
Source: https://docs.woocommerce.com/document/managing-orders/#prettyPhoto
I need this to work like this, except when the client's role is "X".
I have seen that this can be solved with this code:
function cod_payment_method_order_status_to_onhold( $order_id ) {
if ( ! $order_id )
return;
$order = wc_get_order( $order_id );
if ( get_post_meta($order->id, '_payment_method', true) == 'cod' )
$order->update_status( 'on-hold' );
}
add_action( 'woocommerce_thankyou', 'cod_payment_method_order_status_to_onhold', 10, 1 );
However, the problem is that it goes through "Processing", sends the email and then goes to "on hold". I want to avoid sending the "Processing" mail
Any way to do it? Thank you!
You should better use woocommerce_cod_process_payment_order_status dedicated filter hook. You will have to replace "administrator" user role by your "X" role.
The hooked function code:
add_filter( 'woocommerce_cod_process_payment_order_status', 'set_cod_process_payment_order_status_on_hold', 10, 2 );
function set_cod_process_payment_order_status_on_hold( $status, $order ) {
$user_data = get_userdata( $order->get_customer_id() );
if( ! in_array( 'administrator', $user_data->roles ) )
return 'on-hold';
return $status;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
In Woocommerce, I would like to automatically put all Woocommerce Subscriptions "on hold" rather than "active" when the order is still "processing". Once I mark the order as "completed" that subscription should change to "active".
I've tried everything I can think of, if somebody knows how to do this please let me know.
I'm running wordpress 4.8.1 / Woocommerce 3.1.2 / Woocommerce Subscriptions 2.2.7 / and the payment gateway is Stripe 3.2.3.
This can be done in two steps:
1) With a custom function hooked in woocommerce_thankyou action hook, when the order has a 'processing' status and contains subscriptions, we update the subscriptions status to 'on-hold':
add_action( 'woocommerce_thankyou', 'custom_thankyou_subscription_action', 50, 1 );
function custom_thankyou_subscription_action( $order_id ){
if( ! $order_id ) return;
$order = wc_get_order( $order_id ); // Get an instance of the WC_Order object
// If the order has a 'processing' status and contains a subscription
if( wcs_order_contains_subscription( $order ) && $order->has_status( 'processing' ) ){
// Get an array of WC_Subscription objects
$subscriptions = wcs_get_subscriptions_for_order( $order_id );
foreach( $subscriptions as $subscription_id => $subscription ){
// Change the status of the WC_Subscription object
$subscription->update_status( 'on-hold' );
}
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
2) With a custom function hooked in woocommerce_order_status_completed action hook, when the order status is changed to "completed", it will auto change the subscription status to "active":
// When Order is "completed" auto-change the status of the WC_Subscription object to 'on-hold'
add_action('woocommerce_order_status_completed','updating_order_status_completed_with_subscription');
function updating_order_status_completed_with_subscription($order_id) {
$order = wc_get_order($order_id); // Get an instance of the WC_Order object
if( wcs_order_contains_subscription( $order ) ){
// Get an array of WC_Subscription objects
$subscriptions = wcs_get_subscriptions_for_order( $order_id );
foreach( $subscriptions as $subscription_id => $subscription ){
// Change the status of the WC_Subscription object
$subscription->update_status( 'active' );
}
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
All code is tested on Woocommerce 3+ and works.
When a woocommerce order is created the status of the order is "processing". I need to change the default order-status to "pending".
How can I achieve this?
The default order status is set by the payment method or the payment gateway.
You could try to use this custom hooked function, but it will not work (as this hook is fired before payment methods and payment gateways):
add_action( 'woocommerce_checkout_order_processed', 'changing_order_status_before_payment', 10, 3 );
function changing_order_status_before_payment( $order_id, $posted_data, $order ){
$order->update_status( 'pending' );
}
Apparently each payment method (and payment gateways) are setting the order status (depending on the transaction response for payment gateways)…
For Cash on delivery payment method, this can be tweaked using a dedicated filter hook, see:
Change Cash on delivery default order status to "On Hold" instead of "Processing" in Woocommerce
Now instead you can update the order status using woocommerce_thankyou hook:
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 );
if( $order->get_status() == 'processing' )
$order->update_status( 'pending' );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works
Note: The hook woocommerce_thankyou is fired each time the order received page is loaded and need to be used with care for that reason...
Now the function above will update the order status only the first time. If customer reload the page, the condition in the IF statement will not match anymore and nothing else will happen.
Related thread: WooCommerce: Auto complete paid Orders (depending on Payment methods)
Nowadays, if the payment gateway that you use properly sets the order status using WC_Order->payment_complete(), you can use the woocommerce_payment_complete_order_status filter.
This is better than using woocommerce_thankyou hook since we are setting the order status immediately, rather than applying it after it has been already set.
function h9dx3_override_order_status($status, $order_id, $order) {
if ($status === 'processing') {
$status = 'pending';
}
return $status;
}
add_filter('woocommerce_payment_complete_order_status', 'h9dx3_override_order_status', 10, 3);
Again, this will only work if the payment gateway uses the proper payment_complete wrapper method rather than setting status directly with set_status. You can just search the gateway code for 'payment_complete(' and 'set_status(' to see what it does.
If you develop a plugin for everyone, you will be better off with using woocommerce_thankyou, or you could use a combined approach and use woocommerce_thankyou as the fallback if the order status was not updated.
The hook woocommerce_thankyou suffers from the problem that you can pay for an order and then close the browser or go somewhere else and therefore never click "Return to Merchant" (which is displayed after paying via paypal) to get to the thankyou page. And then the code will never be executed.
// Rename order status 'Processing' to 'Order Completed' in admin main view - different hook, different value than the other places
add_filter( 'wc_order_statuses', 'wc_renaming_order_status' );
function wc_renaming_order_status( $order_statuses ) {
foreach ( $order_statuses as $key => $status ) {
if ( 'wc-processing' === $key )
$order_statuses['wc-processing'] = _x( 'Order Completed', 'Order status', 'woocommerce' );
}
return $order_statuses;
}
I need to make WooCommerce push payments made by check into the "processing" status rather than the "on hold" status. I tried the snippet below however it doesn't seem to have an effect.
Here is my code:
add_filter( 'woocommerce_payment_complete_order_status', 'sf_wc_autocomplete_paid_orders' );
function sf_wc_autocomplete_paid_orders( $order_status, $order_id ) {
$order = wc_get_order( $order_id );
if ($order->status == 'on-hold') {
return 'processing';
}
return $order_status;
}
How can I achieve this?
Thanks.
Here is the function you are looking at hooked in woocommerce_thankyou hook:
add_action( 'woocommerce_thankyou', 'cheque_payment_method_order_status_to_processing', 10, 1 );
function cheque_payment_method_order_status_to_processing( $order_id ) {
if ( ! $order_id )
return;
$order = wc_get_order( $order_id );
// Updating order status to processing for orders delivered with Cheque payment methods.
if ( get_post_meta($order->id, '_payment_method', true) == 'cheque' )
$order->update_status( 'processing' );
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This is tested and works.
Related thread: WooCommerce: Auto complete paid Orders (depending on Payment methods)
I didn't want to use the Thank You filter in case the order still got set to On Hold at a previous step, before changing it to my desired status in the filter (a custom status in my case, or Processing in yours). So I used the filter in the Cheque gateway:
add_filter( 'woocommerce_cheque_process_payment_order_status', 'myplugin_change_order_to_agent_processing', 10, 1 );
function myplugin_change_order_to_agent_processing($status){
return 'agent-processing';
}
I hope this helps someone else out there to know that there is another option.
Previous answer from LoicTheAztec is outdated and gives error about accessing object fields directly on the order object.
Correct code should be
add_action( 'woocommerce_thankyou', 'cheque_payment_method_order_status_to_processing', 10, 1 );
function cheque_payment_method_order_status_to_processing( $order_id ) {
if ( ! $order_id )
return;
$order = wc_get_order( $order_id );
// Updating order status to processing for orders delivered with Cheque payment methods.
if ( get_post_meta($order->get_id(), '_payment_method', true) == 'cheque' )
$order->update_status( 'processing' );
}