We sell a combination of multiple products as one product, these products can't be added separte to WordPress so we use a normal product type for the combination.
These products have seperate tax classes (a 9% and a 21% part), so I created a plugin to save the 2 tax values as meta values.

When I place an order I save a custom meta field with the order item with the average tax calculated (like 15% for example).
Within the function calculate_taxes I can get this meta value and use it to calculate the correct tax, but when I do this I will override the core file and I don't want that because of updates.
How can I override the calculate_taxes function?

I also tried to use the filter woocommerce_find_rates, but I don't know if I can get the order item inside this filter, otherwise I can use that filter.

The code I use for adding the custom tax inside woocommerce/includes/class-wc-order-item.php

public function calculate_taxes( $calculate_tax_for = array() ) {
    if ( ! isset( $calculate_tax_for['country'], $calculate_tax_for['state'], $calculate_tax_for['postcode'], $calculate_tax_for['city'] ) ) {
        return false;
    if ( '0' !== $this->get_tax_class() && 'taxable' === $this->get_tax_status() && wc_tax_enabled() ) {
        $calculate_tax_for['tax_class'] = $this->get_tax_class();
        $tax_rates                      = WC_Tax::find_rates( $calculate_tax_for );

        /* CUSTOM PART */
        foreach ($tax_rates as $k => $t) {
            if (!empty($this->get_meta('_line_tax_rate'))) $t['rate'] = $this->get_meta('_line_tax_rate');
            $tax_rates[$k] = $t;
        /* ENDOF CUSTOM PART */

        $taxes                          = WC_Tax::calc_tax( $this->get_total(), $tax_rates, false );

        if ( method_exists( $this, 'get_subtotal' ) ) {
            $subtotal_taxes = WC_Tax::calc_tax( $this->get_subtotal(), $tax_rates, false );
                    'total'    => $taxes,
                    'subtotal' => $subtotal_taxes,
        } else {
            $this->set_taxes( array( 'total' => $taxes ) );
    } else {
        $this->set_taxes( false );

    do_action( 'woocommerce_order_item_after_calculate_taxes', $this, $calculate_tax_for );

    return true;
  • Please add all necessary related code + the one that overwrites the core function, in your question… Without that nobody can guess what you have done, and how to manage that. – LoicTheAztec Apr 29 at 18:09
  • I don't think the code self is relevant because I just want to know if I can override a function, or if I can use the order item inside the woocommerce_find_rates filter. But I added it as a reference – FamousWolluf Apr 30 at 8:39

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.