Woocommerce REST API - updating an order changes custom tax calculations

by KGreene   Last Updated September 11, 2019 19:08 PM

We have a online woocommerce store that processes two types of orders: shipping and instore pickup. Shipping calculates taxes based on billing address and instore uses the store address (zip).

add_filter( 'woocommerce_customer_taxable_address', array( $this, 'alter_taxable_address'), 1, 1);  

public function alter_taxable_address($address) {
        $order = wc_get_order( get_the_ID() );

        /**** If WC order exists ****/
        if($order){
            $order_id = $order->get_id();       

            if( $this->get_order_type($order_id) == 'pickup' ){

                $store_id = get_post_meta($order_id, '_pickup_store', true);
                $store_number = $this->get_store_code($store_id);

                $store_zip = $this->get_store_zip($store_number);
                $tax_rate = $this->get_store_tax_rate($store_number);           
                $store_name = $this->get_store_name($store_id);

                $address = array(
                    'US',
                    'TX',
                    $store_zip,
                    $store_name
                );          
            }
            return $address;            
        }
}

The store has a pos system (not wordpress) which receives the orders, the store can edit them on customer request, then uses the woocommerce REST API to edit/update the orders on the original website. Everything works fine in the process except that when the order is updated via API, it seems to ignore the hook and uses the customers billing address to recalculate taxes.

You can pass a tax class, but not a tax rate via the API. Docs Here: https://woocommerce.github.io/woocommerce-rest-api-docs/#order-properties

My current solution is awful, It sets the customer's billing address zip:

add_action( 'woocommerce_order_status_completed', array( $this, 'instore_woocommerce_order_status_completed'), 10, 1 );
public function instore_woocommerce_order_status_completed($order_id){      
        if( $this->get_order_type($order_id) != 'pickup') return;       

        $order = wc_get_order( $order_id ); 
        $db = new POS_DB();
        $pos_db = $db->db_connection();     

        $sql = "SELECT store_number FROM orders WHERE order_id = {$order_id}";
        $result = mysqli_query($pos_db, $sql);
        $pos_order = $result->fetch_object();

        $store_number = $pos_order->store_number;
        $store_zip = $this->get_store_zip($store_number);       

        $new_total = $pos_order->final_total;           

        /**** Changing the billing address!?!. I need a better solution  ****/
        $order->set_billing_postcode($store_zip);
        $order->set_total( $new_total );        
}

My first time posting a question, so any advice or pointers are welcome.



Related Questions


Updated November 14, 2016 07:32 AM

Updated June 14, 2016 08:03 AM

Updated May 24, 2017 17:08 PM

Updated December 11, 2016 08:03 AM

Updated November 20, 2017 19:08 PM