FOX - WooCommerce Currency Switcher Professional

WooCommerce Currency Switcher Exchange Rates Not Updating: Fixes

When the WooCommerce currency switcher's exchange rates are not updating, the symptom is one of three: a rate field shows no data for ... or 0 after Update all rates, the rates never change on their own, or they change but do not match what Google shows. Each has a different cause, and FOX itself rarely invents a number: it asks a rate provider, stores what comes back and multiplies your prices by it. This guide explains how that works, how to fix each symptom, and how to take control of the rates when the automatic ones are not what you want.

How FOX updates exchange rates

The rate source is the Currency aggregator in the Options tab of the FOX settings (WooCommerce → Settings → Currency), with its key in Aggregator API key if the provider needs one. For every currency except the base one, FOX sends one request to that aggregator, asking how many units of the currency one unit of your base currency buys. A USD shop with an EUR rate of 0.92 shows a 100 USD product at 92 EUR.

There are two ways rates get updated, and they treat failures differently:

  • Update all rates in the Currencies tab, and the refresh button next to each rate, fill the rate fields with the answers. Nothing is stored until you press Save. A currency the aggregator cannot price gets the error text in its field, and saving that field stores 0.
  • The scheduled update set by Rate auto update stores only rates greater than zero. A currency whose request fails keeps its previous rate, silently.

So a 0 almost always comes from a manual update that was saved, and a frozen rate from a scheduled update that either does not run or keeps failing for that currency.

"No data for" or a rate of 0

Press the refresh button next to the currency and read the text that appears in the rate field. It names the cause more often than not:

  • The aggregator has no data for the pair. No provider covers every currency. Yahoo has gaps for many exotic pairs (the message reads There is no data for these currencies: USD/XXX). The European Central Bank source publishes about thirty major currencies and calculates other base currencies from its euro rates. CryptoCompare covers crypto currencies and not every fiat one, and Pulse Verity handles crypto only, with USD as the base currency. Switch the aggregator and test again.
  • The currency code is not a real code. EURO, CAD$ or a code with an invisible character pasted from a web page returns nothing from any aggregator. Delete the code, type the three letters of the ISO 4217 code by hand and save. A currency that really has no ISO code needs a manual rate; see custom currency codes.
  • The API key is missing or wrong. Currencyapi, Open exchange rates, Currencylayer and Fixer need a key from the provider's site in Aggregator API key. Messages starting with Aggregator Error: come from the provider and say what it refused.
  • The free plan does not allow your base currency. Several providers answer free keys for one base currency only, for example USD at Open exchange rates and Currencylayer and EUR at Fixer. A shop with another base currency gets an error such as Changing the API base currency is available for ... plan clients. Use a plan that allows it or another aggregator.
  • The request quota is used up. FOX makes one request per currency on every update. Eight currencies besides the base one, updated every hour, make about 5,800 requests a month, which exceeds many free quotas; when the quota runs out, the provider stops answering. Choose a longer interval in Rate auto update so the monthly total fits.
  • The server cannot reach the provider. A local development install, a firewall that blocks outgoing HTTPS, or a broken cURL or SSL setup stops every request. FOX writes these failures to the PHP error log as lines starting with [WOOCS] wp_remote_get error:.

The fix path is the same in every case: correct the code, choose an aggregator that covers all your currencies for your base currency, paste its key, press Update all rates, check that every field holds a number, and only then press Save.

Never leave a rate at 0

A rate of 0 multiplies every price, fee and shipping cost in that currency to zero, so products can be ordered for nothing, and calculations that divide by the rate can stop the page with a Division by zero fatal error. If one currency cannot be priced automatically, give it a manual rate (below) or remove it. To guard against a provider returning a wild value, set Rate floor/ceiling for the currency in the Currencies tab: a fetched rate below the Minimum possible rate or above the Maximum possible rate is replaced by that limit. Pages showing prices of 0 for other reasons are covered in currency recounts wrong: double, zero and others.

Rates do not update automatically

Choose an interval in Rate auto update, from special: each minute to monthly, and press Save. The schedule starts from that moment. Below the option FOX shows the scheduler state: Last run, Next run and the interval, or no schedule stored yet if the option was never saved.

The schedule is FOX's own, not WP-Cron, and it runs on the first request that loads WordPress after the due time: a page view, an admin page, an AJAX or REST request. That has three consequences:

  • The exact time cannot be set in the settings, and an update can run late on a quiet site. Next run then shows overdue by ..., waiting for the next request that loads WordPress.
  • Pages served by a full page cache or a CDN do not load WordPress. A site whose visitors only ever get cached pages may go a long time without an update.
  • DISABLE_WP_CRON in wp-config.php does not affect it.

To make updates punctual, let a server cron job request any uncached URL of the site every few minutes, for example https://your-site.com/wp-cron.php; that loads WordPress and the overdue update runs. To update at a fixed time instead, set Rate auto update to no auto update and run the update action from the server's crontab with WP-CLI at the time you want:

# crontab: update FOX rates every day at 06:00 server time
0 6 * * * cd /path/to/wordpress && wp eval 'do_action("woocs_update_rates_wpcron");'

The action is documented as woocs_update_rates_wpcron. If the plugin is older than 2.5.3, update it first: in older versions the schedule could keep restarting on shops with steady REST API traffic and never run.

How to check that it works

An aggregator often returns the same rate it returned an hour ago, which looks like "not updating". To test, type an obviously wrong rate such as 7777 into one currency, save, and wait one interval: the scheduled update should replace it. Email notice about "Rate auto update" results in the Options tab sends the administrator a list of rates after every scheduled run. The list shows every currency with its current rate, including a currency whose request failed and kept its old value, and it is sent with PHP's mail(), so an SMTP plugin does not deliver it. When no e-mail arrives, the Last run line is the better witness.

Keep manual rates or use your own source

Automatic rates are optional. The ways to take control, from simplest to most flexible:

  • All rates by hand. Set Rate auto update to no auto update, type the rates and save. Nothing overwrites them.
  • One currency by hand, the rest automatic. The woocs_add_custom_rate filter answers for chosen currencies before the aggregator is asked, both in scheduled updates and on the update buttons. After adding it, press Update all rates and Save, or wait for the next scheduled run:
    /*
     * Fixed rate for one currency, automatic rates for the others.
     * Child theme functions.php or a code snippets plugin.
     */
    add_filter('woocs_add_custom_rate', function ($rate, $base_currency, $currency) {
        if ($currency === 'NGN') {
            return 1550; // 1 unit of the base currency = 1550 NGN
        }
        return $rate; // false: the aggregator decides
    }, 10, 3);
  • A margin on top of the rate. The interest field next to each rate in the Rate+% column adds a fixed amount (0.15) or a whole percentage (2%) to the stored rate, so updates keep your margin. More in how to adjust exchange rates manually.
  • Your own rate source. The filters woocs_announce_aggregator and woocs_add_aggregator_processor add an aggregator that reads your bank's API, an XML file or a CSV feed; the processor is called once per currency and returns the rate. How to add a custom rate aggregator has a working example. For the Narodowy Bank Polsky source, woocs_bank_polski_table switches from table A to another table.
  • Rates written by your code. The rates are stored in the woocs option, keyed by currency code. Read it with get_option(), not with $WOOCS->get_currencies(), which returns the rates with the interest already added:
    $currencies = get_option('woocs', array());
    if (isset($currencies['EUR'])) {
        $currencies['EUR']['rate'] = 0.9215;
        update_option('woocs', $currencies);
    }
    To react to every scheduled update, for example to log the rates or pass them to another system, use the woocs_sheduler_rates_updated action, which receives the updated currencies.

Why the rate differs from Google

FOX uses exactly the rate the selected aggregator returned at the last update. Google, XE and banking apps show rates from their own data providers, usually a live mid-market rate, so a difference does not mean an error. The usual reasons:

  • Different sources and timing. The Yahoo aggregator takes the opening value of the latest daily price bar, which can be hours old by the afternoon. The European Central Bank publishes its reference rates once each working day. Free plans of other providers are often refreshed hourly or daily. Rates that follow the market within minutes need a provider and plan that update that often, and an interval in Rate auto update to match.
  • Your own settings. An interest value in Rate+%, a Rate floor/ceiling limit, a woocs_add_custom_rate filter, rounding code or fixed prices per currency all move the shown price away from a plain conversion. Check the rounding code and the product's fixed prices before blaming the rate.
  • Prices that change while the rate does not. If prices move while the rate fields stay the same, something else is converting or changing prices: a second currency plugin, a dynamic pricing plugin, or a page cache serving an old page.

To align the rates, choose the aggregator whose numbers match the reference you trust, update more often within its quota, or set the rate by hand for the currencies where the difference matters.

Checklist

  • Every currency code is a plain three-letter ISO code, typed by hand.
  • The aggregator covers all your currencies for your base currency, and its key and plan allow that base currency.
  • Update all rates fills every field with a number before you press Save; no rate is 0.
  • Rate auto update saved, Last run recent, and requests per month within the provider's quota.
  • On a fully cached site, a server cron job requests an uncached URL.
  • Floor and ceiling set for currencies where a wrong rate would hurt.

If a currency still will not update with a correct code and a working aggregator, open a topic on the FOX support forum with the base currency, the aggregator, the text shown in the rate field and any [WOOCS] lines from the PHP error log, and we will look at it.