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 ****/
            $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(
            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_total( $new_total );        

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

  • Hi KGreene, welcome to WordPress Development. As a rule, the community considers questions about third-party plugins (such as Woocommerce) off-topic so you might notice some down-votes. That said, Woocommerce questions sometimes attract good answers anyway. You can find out what questions are always seen as a good fit here. Sep 12, 2019 at 3:01


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.