The "official" Table Rates Shipping plugin is not compatible with a multi-currency environment, because it's designed with the strict assumption that all values it encounters are in shop's base currency. Due to that, its rules may not always work correctly in a multi-currency environment. This article will show you how to address some of the most common issues.


Notes

  • The solutions in this article are provided as a courtesy, and they are considered customisations for a 3rd party plugin. As such, we cannot provide support in relation to them. If you need assistance with their implementation please feel free to contact us to avail of our customisation services.
  • The solutions in this article must be considered a temporary workaround, and they may break if the Table Rates Shipping plugin will change in the future. If you wish to use such plugin in a multi-currency environment, we strongly recommend to contact its authors and request them to add native support for multi-currency sites (it's something that they should do on their side).
  • Due to limitations in its design, it's not possible to extend the "official" Table Rates plugin to allow entering shipping costs manually, in each currency. If you need such feature, we would recommend to switch to the Table Rates Shipping plugin developed by BolderElements, which is fully supported by our Shipping Pricing Addon for the WooCommerce Currency Switcher.

Common issues and workarounds

1. The Min/Max Prices ranges only work with base currency
This issue occurs because the shipping plugin compares the value of the cart, which may or may not be in base currency, with the price ranges, which are always in base currency.

To fix the issue, the Table Rates plugin should take into account the active currency and convert the ranges before comparing them with the cart total. Unfortunately, the plugin doesn't do it, and it cannot be done "from the outside either", because the min/max ranges are fetched and compared with a single SQL query, which cannot be modified.

Despite this limitation in the plugin design, we can adopt the opposite approach, converting the cart total to base currency before it's compared to the ranges. In other words, instead of converting everything to the active currency, we can convert everything to the base currency. The result is the same, as the values will all be in the same currency.

The following code snippet converts the cart total before it's compared to the min/max thresholds, ensuring that rule matching remains consistent. 
/**
 * Fix for the "official" Table Rates Shipping plugin. 
 * Tested with Table Rates Shipping Plugin 3.0.1
 * Converts the cart total to base currency, before the Table Rates plugin uses
 * it to find the matching shipping pricing rules. 
 *
 * @param array $args An array of arguments used by the Table Rates plugin to
 * find the matching the shipping pricing rules.
 * @return array The array of arguments, with the cart price converted to base 
 * currency.
 * @author Aelia <support@aelia.co>
 * @link https://aelia.freshdesk.com/solution/articles/new?folder_id=3000000891
 */
add_filter('woocommerce_table_rate_query_rates_args', function($args) {
  // $args['price'] contains the cart total, which is in the active currency
    $args['price'] = apply_filters('wc_aelia_cs_convert',
                                   $args['price'],
                                   get_woocommerce_currency(),
                                   get_option('woocommerce_currency'));
  return $args;
}, 99, 1);