| 开发者 | maxhandmade |
|---|---|
| 更新时间 | 2026年9月7日 21:22 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 7.1 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
mhm-currency-switcher folder to the /wp-content/plugins/ directory, or install directly through the WordPress plugin screen.[mhmcs_currency_switcher] renders the currency dropdown. It accepts one
attribute, size, which may be small, medium or large; leave it out to
use the size saved in Display Options.
[mhmcs_currency_prices] renders the same product price in several currencies.
Its attributes are all optional:
currencies — comma-separated codes, e.g. currencies="USD,EUR". Without
it, the currencies chosen in Display Options are used. Codes you have not
configured as currencies are ignored.product_id — price a specific product instead of the one being viewed.price — price a specific amount instead of a product's.show_flags — true or false, overriding the saved Display Options
setting.As many as your shop needs — every currency WooCommerce offers can be enabled, and nothing is held back for a paid version. The REST API refuses a request carrying more than 500 currency rows; that is a guard against oversized payloads and is well above the number of codes WooCommerce itself offers, so the panel cannot reach it.
Exchange rates are fetched from ExchangeRate-API in real time, either on demand or on a schedule you configure (hourly, twice daily, or daily) so your rates stay current without manual intervention.
If that source cannot be reached, the plugin falls back to the European Central Bank's daily reference rate feed before giving up and leaving your existing rates in place. Both are named, with their terms, under "External services" below. If your network blocks the fallback, the mhmcs_fallback_rates_url filter can point it somewhere else.
Yes. MHM Currency Switcher fully supports WooCommerce High-Performance Order Storage (HPOS / Custom Order Tables).
No. A fixed price is stored per product and currency, not per price type, so the same amount is used for the regular price and the sale price. A product on sale in your base currency shows as not on sale in a currency you have given a fixed price to. If you need the sale to carry across, leave that currency to the exchange rate instead of fixing it.
Yes. When cache compatibility mode is on, prices on cached pages are converted through a public REST endpoint, and one address may call it 120 times a minute by default. Ordinary browsing is nowhere near that — a page makes one request. If your shop sits behind a reverse proxy or a CDN that makes every visitor look like the same address, raise or disable the limit with the mhmcs_convert_rate_limit filter. Note that the address is read from the proxy headers WooCommerce passes on, which it trusts unconditionally and which can be forged; the limit bounds accidental hammering rather than a determined attacker.
Some themes and plugins define WooCommerce's cart constant on every page, usually to show a cart total in the header. When that happens the plugin treats every page as a checkout — the customer's money is at stake — and converts prices on the server, which is exactly what cache compatibility mode exists to avoid. Nothing looks wrong on the site: prices are still correct for whoever loads the page first, and then a page cache can serve that person's currency to everyone else. Because there is no visible symptom, the plugin says so in the admin instead. The notice clears itself as soon as a front-end page renders normally again.
With cache compatibility on, the page is generated in your base currency and the browser converts the prices afterwards, so the machine-readable product data a crawler reads stays in the base currency. This is deliberate and is not corrected: pinning it the other way would leave the data disagreeing with the page in the one case where the two currently agree — with cache compatibility switched off, where the page and the structured data are both converted on the server.
Only when the request asks for a currency: ?currency=EUR on a wc/v3 product request converts price, regular_price and sale_price and adds a currency_code field. Without the parameter the response is pinned to your base currency, so the answer never depends on the cookies of whoever is calling. A per-product fixed price takes precedence over the exchange rate here, exactly as it does on the shop page.
One known limit: the price_html field is not pinned in the same way. It cannot be reached in that state by a normal wc/v3 client — only by code that dispatches an internal REST request during a page render — so no integration sees it, but it is not consistent with the three numeric fields and is recorded here rather than left unsaid.
WC_Geolocation::geolocate_ip() with the remote-API
fallback switched off, the same way WooCommerce core calls it on the
storefront. Before this, a store with no MaxMind database sent every new
visitor's IP address to a third-party geolocation service. Visitor IP
addresses no longer leave your server for this feature.mhm-cs-* to mhmcs-*.
Every class in the switcher's CSS and JS -- .mhm-cs-switcher,
.mhm-cs-dropdown, .mhm-cs-size--small, and the rest -- now uses the
mhmcs- prefix instead. If you have written custom CSS or JavaScript
that targets one of the old mhm-cs-* classes, it will stop matching
after you update: change your selectors to the new mhmcs- names. No
alias is kept for the old classes.mhmcs_fallback_rates_url filter's $source argument is
now always ecb. The exchange-rate fallback no longer has two stages
(currency-api then frankfurter); it is now a single request to the
European Central Bank's daily reference feed. Code that checked for
$source === 'currency-api' or 'frankfurter' will no longer see those
values.currency-api.pages.dev then
Frankfurter chain added in 2.0.0. Coverage is unchanged -- the same
roughly thirty currencies -- because that was already the final stage of
the old chain; the extra intermediate stage is removed as no longer
useful.activate_plugins (the capability to
act on it -- you install a plugin), and the two cache-compatibility
notices need manage_woocommerce.mhm-cs- / mhm_cs_ / mhm_currency_switcher_
legacy naming token still in the plugin -- across CSS, JavaScript, the
admin panel source and its compiled build, tests and documentation -- has
been renamed to the current mhmcs prefix. This is the last of the
prefix cleanup that started with the 2.0.0 shortcode and option rename.GET /rates REST endpoint was
removed. It duplicated information already visible in the page itself;
the authenticated /rates/sync and /rates/preview endpoints used by
the admin panel are unaffected.languages/ is no longer included in the release ZIP --
WordPress.org compiles translations from the .pot file, which is still
kept in the plugin's repository.[mhm_currency_switcher]
is now [mhmcs_currency_switcher], and [mhm_currency_prices] is now
[mhmcs_currency_prices]. The old tags are gone; a page still holding one
will show the raw text instead of the switcher, so update any page, post or
template that uses them. WordPress.org's prefix check splits a prefix at the
first underscore, which read the old tags as "mhm" -- three letters, under
the four-letter minimum -- and a plugin cannot be reviewed under a name the
review tool cannot attribute to it. Stored data is untouched: option names,
order meta and per-product fixed prices all keep the names they had.latest.currency-api.pages.dev instead of the
jsDelivr CDN. Same upstream project, same payload; only the host changed.
WordPress.org's review tool keeps a fixed list of public CDN domains and
treats a shipped source naming one as an error, whatever the URL fetches.
If your store restricts outbound requests to an allow-list, permit the new
host -- or redirect it with the filter below.mhmcs_fallback_rates_url, which receives the URL, the base
currency code and which source is being filtered (currency-api or
frankfurter), so a store can move one source without moving the others.intl extension is required.?currency=, while
every other field in the response, and the currency a client reads it under,
stayed in the base currency. Feeds, stock syncs and marketplace integrations
took that price as fact.GET /settings returned the whole stored option, including keys whose
controls were removed in an earlier release. One of them, provider_api_key,
is a credential you supplied. Saving settings has always dropped those keys,
but a shop that had not pressed Save since then still held the value, and the
read route handed it to anyone with the "manage WooCommerce" capability —
which includes shop managers, who are not administrators. The read route now
filters the same list the save route and the uninstaller do.[mhm_currency_switcher] and [mhm_currency_prices]
shortcodes and their attributes, which this file advertised but never named.wc/v3 REST reads now return the base currency unless the request
asks for one, so the response no longer depends on the caller's cookies.POST mhmcs/v1/convert, rate limited to 120
requests a minute per address (mhmcs_convert_rate_limit filter).mhmcs prefix. Settings from earlier
development builds are not carried over.