14

I want to write a custom plugin that does some action after woocommerce order is completed, but I can't get this hook to work. I can see this question asked many times.

Like here: https://wordpress.stackexchange.com/questions/134463/woocommerce-order-status-completed-action-hook-not-working

Here: https://wordpress.org/support/topic/woocommerce_order_status_completed-is-not-working

And here: https://wordpress.org/support/topic/woocommerce_order_status_completed-action-hook-not-working

But I cannot help myself with answers that these guys received.

I tried to add the action a few different ways:

add_action( 'woocommerce_order_status_completed', 'ikwoocommerceorderstatuscompleted_func');

add_action( 'woocommerce_order_status_completed', array($this,'ikwoocommerceorderstatuscompleted_func'), 10, 1);

add_action( 'woocommerce_order_status_completed', array(&$this,'ikwoocommerceorderstatuscompleted_func'), 10, 1);

Also tried with a class:

class IKHooks {
    function __construct() {
        add_action( 'woocommerce_order_status_completed', array($this,'ikwoocommerceorderstatuscompleted_func'), 10, 1);
    }

    public function ikwoocommerceorderstatuscompleted_func( $order_id ) {

    }
}

I even tried to put the action outside of the class:

add_action( 'woocommerce_order_status_completed', array(IKHooks,'ikwoocommerceorderstatuscompleted_func'), 10, 1);

None of these examples work. :(

Community
  • 1
  • 1
user568021
  • 1,426
  • 5
  • 28
  • 55

6 Answers6

14

Check the following steps before calling your hook.

  1. Check if order completion email is sent.

  2. Hook is properly registered in plugin file or theme functions.php

add_action( 'woocommerce_order_status_completed','callback_function_name' );

function callback_function_name(){
  global $wp_filter;
  print_r($wp_filter);
  exit;
}

Check if the name of your callback function is in the hook array:

[woocommerce_order_status_completed] => Array
    (
        [10] => Array
            (
                [wc_paying_customer] => Array
                    (
                        [function] => wc_paying_customer
                        [accepted_args] => 1
                    )

                [wc_downloadable_product_permissions] => Array
                    (
                        [function] => wc_downloadable_product_permissions
                        [accepted_args] => 1
                    )

                [callback_function_name] => Array
                    (
                        [function] => callback_function_name
                        [accepted_args] => 3
                    )

            )

    )

If you find it then everything is ok, it means that probably there's an issue with your theme or functions.php file. Check for the hook or callback function in your files and then look for remove_action or remove_all_actions that's probably what's preventing your hook from being called.

You can also check in this way

add_action( 'woocommerce_order_status_completed', 'callback_function_name', 1);

Change the priority of your hook from 10 to 1 so it is called first than any other action or hook.

Ruvee
  • 8,611
  • 4
  • 18
  • 44
user5200704
  • 1,689
  • 11
  • 10
  • Thanks. I must try this tomorrow. – user568021 Apr 03 '16 at 21:26
  • Can I ask, how this helped for you? My actions aren't firing, even though they are in in `$wp_filter` – Patrick Jul 15 '16 at 01:26
  • You can check before execute any wordpress action and filter. What is available your registered hook and callback function. print_r($wp_filter); // same as code to check above answer. do_action( 'woocommerce_order_status_completed') – user5200704 Jul 15 '16 at 15:59
  • @user5200704 On my website, it seems `woocommerce_order_status_completed` is not firing when a user places and completes an order. But if I go to the backend and manually change an order from "on hold" to "completed" , it will fire. Anyone knows why? – shenkwen Jan 29 '22 at 19:16
10

You can use this hook

add_action( 'woocommerce_order_status_changed', 'your_function', 99, 4 );

And the function will look like

function your_function( $order_id, $old_status, $new_status, $order ){
    if( $new_status == "completed" ) {
        //your code here
    }
}

Hope this will be helpful.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
hemnath mouli
  • 2,617
  • 2
  • 17
  • 35
2

I faced the similar issue earlier and solved it as:

Following code update the order status as completed

add_action( 'woocommerce_thankyou', 'your_wc_autocomplete_order' );

function your_wc_autocomplete_order( $order_id ) {

 if ( ! $order_id ) {
   return;
 }

 $order = wc_get_order( $order_id );

 $order->update_status( 'completed' );

}

Once order is completed, if you want to do something, see the following code:

add_action('woocommerce_order_status_completed','payment_complete');

function payment_complete($order_id)
{
   //global $items;
   //$order = new WC_Order($order_id);
   // do something ...
}

Hopefully, it will work :)

StreetCoder
  • 9,871
  • 9
  • 44
  • 62
2

woocommerce_order_status_changed and woocommerce_order_status_completed actually work for me. After struggling for 2 days i realized that you just can't var_dump or var_export or print_r or whatever in the admin panel, it just won't work.

So if you are a newbie like me and thought those actions weren't working, just try triggering another action like sending a mail for example.

This code works:

function your_function( $order_id ){
   $order = new WC_Order( $order_id );
    $to_email = 'testing_mail@sample.com';
    $payment = $order->get_payment_method_title();
    $headers = 'From: Your Name <Your_site_mail@address.com>' . "\r\n";
    wp_mail($to_email, 'subject', $payment, $headers );
}

add_action( 'woocommerce_order_status_completed', 'your_function');
Macr1408
  • 785
  • 7
  • 9
1

Try using action hook woocommerce_order_status_changed.
It takes 4 parameters. order id, old status new status and order. Further code reference HERE

This may not be exactly suitable to your requirement, but seems to be worth of an alternative. Hope this helps.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
zipkundan
  • 1,754
  • 1
  • 12
  • 16
  • I think this actually gets triggered. But I only get one call with $old_status "pending" and $new_status "on-hold" although I did make a payment via paypal and order should be completed. :( – user568021 Mar 31 '16 at 11:56
  • I've just noticed that all orders in a database have status "wc-on-hold". Why is that? Is there something wrong in woocommerce? – user568021 Mar 31 '16 at 11:57
  • Oh.. I've just realized that you have to manually 'complete' the order in the admin panel. But for some reason in my case the hook doesn't get triggered when I click Complete action... This is strange. On every step I get some behaviour that is not what's expected.. – user568021 Mar 31 '16 at 12:07
  • You are right. You need to manually 'complete' the order in admin panel. Just for your reference, if you want check the payment complete action, you can use action hook `woocommerce_payment_complete`. – zipkundan Mar 31 '16 at 12:27
  • woocommerce_payment_complete is also ignored. WHAT IS HAPPENING TO ME?!?! :( – user568021 Apr 01 '16 at 06:46
  • I've currently got woocommerce_payment_complete wokring, but all the woocommerce_order_status_* doing absolutley nothing – Patrick Jul 15 '16 at 01:25
0

I think you might be after this guy. woocommerce_payment_complete

function mysite_woocommerce_payment_complete( $order_id ) {
    error_log( "Payment has been received for order $order_id", 0 );
}
add_action( 'woocommerce_payment_complete', 'mysite_woocommerce_payment_complete' );
Patrick
  • 1,089
  • 14
  • 17
  • 2
    This was months ago but I remember that I was also trying this one with no success. And I have already accepted the correct answer.. – user568021 Jul 15 '16 at 06:16