Update order status based on an external service response in Woocommerce 3

If the external delivery service status "Order Complete", then in woocommerce update to "Completed". If the external delivery service status "Order Cancelled", then in woocommerce update to "Cancelled".

Need part "Update order status".

function get_order_ids_to_check(){
    global $wpdb;

    return $wpdb->get_col( "
        SELECT p.ID
        FROM {$wpdb->prefix}posts as p
        WHERE p.post_type LIKE 'shop_order'
        AND p.post_status IN ('wc-on-hold','wc-processing')
        AND UNIX_TIMESTAMP(p.post_date) >= (UNIX_TIMESTAMP(NOW()) - 86400)
    " );

    // Get the Orders IDs to check
    $orders_ids = get_order_ids_to_check();

    // Loop through each order Ids
    foreach( $orders_ids as $order_id ){
        // Get the delivery order ID related to your external shipping service
        $delivery_order_id = get_post_meta( $order_id, 'delivery_order_id', true );

        $param['secret']   = "";
        $param['order_id'] = $delivery_order_id;

        foreach ($param as $key => $value) {
            $data .= "&".$key."=".$value;
        }

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://app.example.com/api/index.php?get_status");
        curl_setopt($ch, CURLOPT_FAILONERROR, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $result = curl_exec($ch);
        curl_close($ch);

        $decoded = (array) json_decode($result);

        // Update order status
        if( isset($decoded['result']) && $decoded['result'] == 'success' && isset($decoded['status']) && !empty($decoded['status']) ){
            // If the received order status from the external delivery service is "Order completed", then change it in woocommerce "Completed"
        }
    }
}

Upvotes: 2

Views: 1957

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253784

To update the order status, you will use the WC_Order method update_status().
I Have revisited your code a bit. Try the following:

function get_order_ids_to_check(){
    global $wpdb;

    return $wpdb->get_col( "
        SELECT p.ID
        FROM {$wpdb->prefix}posts as p
        WHERE p.post_type LIKE 'shop_order'
        AND p.post_status IN ('wc-on-hold','wc-processing')
        AND UNIX_TIMESTAMP(p.post_date) >= (UNIX_TIMESTAMP(NOW()) - 86400)
    " );
}

function send_daily_orders_to_delivery(){

    // Loop through each order Ids
    foreach( get_order_ids_to_check() as $order_id ){
        // Get an instance of the WC_Order object
        $order  = wc_get_order($order_id); 

        $secret = ''; // <== Secret key to be set

        $data   = '&secret='.$secret.'&order_id='.get_post_meta( $order_id, 'delivery_order_id', true );

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://app.example.com/api/index.php?get_status");
        curl_setopt($ch, CURLOPT_FAILONERROR, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $result = curl_exec($ch);
        curl_close($ch);

        $decoded = (array) json_decode($result);

        // Update order status
        if( isset($decoded['result']) && $decoded['result'] == 'success' && isset($decoded['status']) && ! empty($decoded['status']) ){
            if( $decoded['status'] == "Order Completed" )
                $order->update_status( 'completed' );
            elseif( $decoded['status'] == "Order Cancelled" )
                $order->update_status( 'cancelled' );
        }
    }
}

Then you will use:

send_daily_orders_to_delivery();

Inside a scheduler function or in any action hook of your choice.

Code goes in function.php file of the active child theme (or active theme). It should work.

Upvotes: 1

Related Questions