woocommerce_checkout_order_processed hook executing function twice

13,277

I always use the hook woocommerce_payment_complete This will fire as the name suggests after the order has been paid.

function order_payment_complete( $order_id ){
    $order = wc_get_order( $order_id );
    /* Insert your code */
}

add_action( 'woocommerce_payment_complete', 'order_payment_complete' );
Share:
13,277

Related videos on Youtube

xGeo
Author by

xGeo

Self-taught developer with 6+ years of experience (as of 2022). I love learning new things!

Updated on June 04, 2022

Comments

  • xGeo
    xGeo almost 2 years

    I have attached a function to the woocommerce_checkout_order_processed hook:

    //check if woocommerce is acive
    if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
        add_action('woocommerce_checkout_order_processed', 'wc_on_place_order');
    }
    

    The wc_on_place_order function is to be executed after the user clicks on the PLACE ORDER button. However, it's so odd that the function is executed twice.

    My wc_on_place_order function calls an external api written in C#:

    function wc_on_place_order( $order_id ) {
        global $wpdb;
    
        // get order object and order details
        $order = new WC_Order( $order_id ); 
        
        // get product details
        $items = $order->get_items();
        //return $items;
        
        $products = array();
        foreach ($items as $item) {
            array_push($products, 
                array('userid' => $order->user_id, 'descr' => $item['name'], 'amt' => (float)$item['line_total'])
            );
        }
    
        //passing $products to external api using `curl_exec`
        . . . .
    
        //on successful call, the page should be showing an `alert`, however, it does not
        // the handle response    
        if (strpos($response,'ERROR') !== false) {
                print_r($response);
        } else {
            echo "<script type='text/javascript'>alert($response)</script>";
        }
    }
    

    After debugging on C# API, I noticed that it the service is being called twice, thus, the checkout is being saved twice to the API database.

    Is there something wrong with the wc_on_place_order function or is woocommerce_checkout_order_processed called twice when clicking the PLACE ORDER?

    Interestingly, adding return $items after $items = $order->get_items() somehow, the C# api was only called once:

    // get product details
    $items = $order->get_items();
    return $items; //this line
    

    Why is that so?

    One more question I would like to ask, is woocommerce_checkout_order_processed the right hook I should use? I have been searching the web for the correct hook to use and it seems that woocommerce_checkout_order_processed is used in the most post. I can't use the woocommerce_thankyou hook as it is also calling the API if I refresh the page.

    Any idea will be really appreciated.

    EDIT:

    I used woocommerce_after_checkout_validation hook which fires after pre-validations on checkout. I can't remember though why woocommerce_checkout_order_processed is being fired twice but I just changed some kind of settings in WooCommerce options page. I can't remember which.

    Useful Links from the Comments:

  • xGeo
    xGeo over 6 years
    this works but ill be looking for a better hook. seems i can't stop woocommerce from redirecting to the "thank you" page from this hook
  • Andrew Schultz
    Andrew Schultz over 6 years
    You can redirect the user to a different page after checkout, would that solve your issue?
  • xGeo
    xGeo over 6 years
    I would like to remain to the current page. See, I am calling an external api to check if the current user has a balance on that endpoint and then, if the user has no balance, i would like to show an error message or something.
  • Andrew Schultz
    Andrew Schultz over 6 years
    Then you're using the wrong hooks. Try the action woocommerce_checkout_process where you can create an error via wc_add_notice() function which will inform the user of zero balance.
  • Madivad
    Madivad over 5 years
    @andrew, where is the best place to learn about the order of hooks here? Is there somebody sort of flow chart of hooks and when they are called?
  • Andrew Schultz
    Andrew Schultz over 5 years
    @Madivad i don't know of any resources. I just view the source code if I want to know the order of actions or want to find an appropriate action or filter to use. WordPress has an action list that shows the order but I have never seen one for WooCommerce codex.wordpress.org/Plugin_API/Action_Reference
  • Madivad
    Madivad over 5 years
    Thanks @AndrewSchultz, I usually get overwhelmed by the source code, so much happening, but I'm certainaly getting a better understanding by doing it. Although I did find a good visual reference for a lot of the woocommerce stuff (I'm just posting this for general info, this is just one example, this guy has posted oodles of examples like this, just click the visual hook series link in the intro. for me this is perfect: businessbloomer.com/… )