I want to update the status of any and all orders (paid or unpaid) to completed, triggering the emails from woocommerce. Sounds counter intuitive but it needs to happen.
I thought something like this would work:
add_action('woocommerce_order_status_changed','status_changed_processsing');
function status_changed_processsing( $order_id, $checkout = null ) {
global $woocommerce;
$order = new WC_Order( $order_id );
//assign statu to that order
$order->status = 'completed';
}
}
But I have not been successful.
TIA. Appreciate any help!
Have a try with this one:
add_action( 'woocommerce_thankyou', 'status_changed_processsing' );
function status_changed_processsing( $order_id ) {
$order = new WC_Order( $order_id );
$order->update_status( 'completed' );
}
$order = new WC_Order($order_id);
if (!empty($order)) {
$order->update_status( 'completed' );
}
try like this
Related
I use WooCommerce with WordPress and I would like to update a custom field for the purchase of a single product at the time of payment validation with the display of the thank you page.
I started from this code but it does not work for the moment.
add_action( 'woocommerce_thankyou', 'checkout_update_user_meta' );
function checkout_update_user_meta( $order_id ) {
$order = new WC_Order( '$order_id' );
$user_id = $order->get_user_id();
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( $product_id == '777' ) {
update_user_meta( $user_id, 'masterclass-1', 'ok' );
}
}
}
add_action( 'woocommerce_thankyou', 'checkout_update_user_meta' );
function checkout_update_user_meta( $order_id ) {
$order = new WC_Order( $order_id );
$user_id = $order->get_user_id();
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item['product_id'];
if ( $product_id === 777 ) {
update_user_meta( $user_id, 'masterclass-1', 'ok' );
}
}
}
The issue with your code was that you wrapped the $order_id in single quotes. This line $order = new WC_Order( $order_id ); can also be replaced as $order = wc_get_order( $order_id );
I just modified your code to Update user meta field after woocommerce checkout according to your need. Please check my changes and hope it will work 👍
add_action( 'woocommerce_thankyou', 'checkout_update_user_meta' );
function checkout_update_user_meta( $order_id ) {
$order = wc_get_order( $order_id );
$user_id = $order->get_user_id();
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
if ( $product_id == 777 ) {
update_user_meta( $user_id, 'masterclass-1', 'ok' );
}
}
}
I am currently using the code below to automatically complete virtual and downloadable products.
add_action('woocommerce_thankyou', 'wpd_autocomplete_virtual_orders', 10, 1 );
function wpd_autocomplete_virtual_orders( $order_id ) {
if( ! $order_id ) return;
// Get order
$order = wc_get_order( $order_id );
// get order items = each product in the order
$items = $order->get_items();
// Set variable
$only_virtual = true;
foreach ( $items as $item ) {
// Get product id
$product = wc_get_product( $item['product_id'] );
// Is virtual
$is_virtual = $product->is_virtual();
// Is_downloadable
$is_downloadable = $product->is_downloadable();
if ( ! $is_virtual && ! $is_downloadable ) {
$only_virtual = false;
}
}
// true
if ( $only_virtual ) {
$order->update_status( 'completed' );
}
}
The issue I am facing is that woocommerce sends out two emails in this scenario to the customer. Order Received + Order Completed. I am wondering if there is anyway to stop the order received email from going through to the customer and only have the order completed email sent.
Thank You
To prevent the "Order Received" email from being sent to the customer, you can use the woocommerce_email_enabled_customer_processing_order filter hook to disable the email.
Please try to add the following code inside your if ( $only_virtual )
add_filter( 'woocommerce_email_enabled_customer_processing_order', '__return_false' );
The easiest way to achieve this would be to bypass the WooCommerce update_status function as the email sending is built-in to the function.
Instead just update the order in wp_posts:
Replace: $order->update_status( 'completed' );
With:
wp_update_post(['ID' => $order_id, 'post_status' => 'wc-completed']);
You will then only receive the Order Received email!
I do not want Woocommerce to automatically update the order status from "On hold" to "Completed". I want it to remain as as "On hold" since we are sending a Replacement Item and we are waiting for the original item to come back to us. Basically, I want it to set as "On-hold" even after the Item has been shipped. Is there a way to achieve this?
I tried using the code below but no luck:
add_action( 'woocommerce_payment_complete', 'cancel_completed_status' );
function cancel_completed_status( $order_id ){
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item_id => $item ) {
$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();
if ( $order->has_status( 'on-hold' )) {
$order->update_status( 'on-hold' );
$order->save();
}
}
}
add_action('woocommerce_order_status_completed', 'completed_to_onhold');
function completed_to_onhold($order_id) {
$order = new WC_Order($order_id);
$order->update_status('on-hold');
}
Is it possible to redirect users to custom order-thank you pages depending on order status?
Order Complete -> /standard-order-received-page/
Order Processing -> /custom-redirect-page
Hope help:
add_action( 'woocommerce_thankyou', 'func_redirectcustom');
function func_redirectcustom( $order_id ){
$order = wc_get_order( $order_id );
$url = 'https://yoursite.com/custom-url';
if ( $order->has_status( 'processing' ) ) {
wp_redirect( $url );
exit;
}
// etc
}
I need to change the default order status that Woocommerce is applying to orders which are paid by Cash on delivery. The default is processing and I need to set it to on-hold. I have tried this
add_action( 'woocommerce_thankyou', 'my_order_status', 50 );
function my_order_status( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
if ( ( get_post_meta( $order->id, '_payment_method', true ) == 'cod' ) && ( $order->status == 'processing' ) ) {
$order->update_status('on-hold');
}
}
but it's not working. Any thoughts?
this solved my problem
add_action('woocommerce_thankyou_cod', 'action_woocommerce_thankyou_cod', 10, 1);
function action_woocommerce_thankyou_cod($order_id)
{
$order = wc_get_order($order_id);
$order->update_status('on-hold');
}
put this in your functions.php
To resolve the issue please use below code:
add_action( 'woocommerce_thankyou', 'wc_change_status' );
function wc_change_status( $order ) {
$order = new WC_Order($order);
$order->update_status('on-hold', 'This is the change status');
//print('<pre>');
// print_r($order);
}