WooCommerce: Run some code only once on order status change

I would like to trigger an action hook (or something similar) on specific order status change. The code should be run only once from order status "processing" to "completed".

Here is m code attempt:

   function payment_complete( $order_id, $old_status, $new_status ){
            if( $new_status == "completed" && $old_status == "processing") {
               // $this->generate_order_file($order_id); 
               echo '<script>alert("Working now, but not once:()")</script>'; 
    add_action( 'woocommerce_order_status_changed', 'payment_complete', 99, 3 );

But it seems that my code runs multiple times. I am stuck for instance. Any help will be appreciated.

Answers 1

  • You can use the following to make the order status change from "processing" to "complete" to be triggered only once for your code:

    add_action( 'woocommerce_order_status_processing_to_completed', 'order_processing_to_completed', 100, 2 );
    function order_processing_to_completed( $order_id, $order ) {
        // Avoid hook to be triggered multiple times at once
        if ( did_action( 'woocommerce_order_status_processing_to_completed' ) > 1 ) {
        // Check that this action hook has not been triggered before
        if ( ! $order->get_meta( '_processing_to_completed' ) ) {
            // Grab the action in WordPress error logs (for testing)
            error_log('"processing_to_completed" Run once only.');
            // Add a custom meta data to flag the action as triggered
            $order->update_meta_data( '_processing_to_completed', 'yes' );
            $order->save(); // Save
            // Here add your code to be run once

    Note: You should not use payment_complete function name as it could be used by another plugin.

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.

    The code inside the if statement will get triggered only once.

Related Articles