Best Currency API for WooCommerce and WordPress (2026)
WooCommerce powers over 25% of all online stores worldwide. If you sell internationally, your customers expect to see prices in their local currency — not a vague "prices shown in USD" disclaimer. Multi-currency pricing is no longer optional; it directly impacts conversion rates and cart abandonment.
The challenge: most currency APIs were not designed for the WordPress ecosystem. They ship JavaScript or Python SDKs but ignore PHP entirely. They lack the WordPress-native hooks you need to integrate with WooCommerce filters like woocommerce_product_get_price. And the free tiers are so restrictive that a store with 50 daily visitors burns through the monthly quota in a week.
This article compares the 5 best currency APIs for WooCommerce and WordPress in 2026, with real PHP code examples using wp_remote_get and Composer packages. Spoiler: AllRatesToday is the clear winner for WooCommerce stores, with an official PHP SDK, real-time mid-market rates, and a free tier that handles real store traffic without a credit card.
Side-by-Side Comparison
Here is how the top 5 currency APIs stack up for WooCommerce and WordPress developers:
| API | WooCommerce Plugin | PHP SDK | Free Tier | Real-Time | Multi-Currency |
|---|---|---|---|---|---|
| AllRatesToday | Yes (official) | Official (Packagist) | Free tier, no CC | Yes (60s) | 160+ currencies |
| Open Exchange Rates | Third-party only | Community only | 1,000 req/mo | Hourly | 170+ currencies |
| CurrencyAPI | No | Official | 300 req/mo | No (daily) | 150+ currencies |
| Fixer.io | Third-party only | No | 100 req/mo | No (daily) | 170+ currencies |
| ExchangeRate-API | No | No | 1,500 req/mo | No (daily) | 160+ currencies |
Key takeaway: AllRatesToday is the only API on this list that offers an official PHP SDK on Packagist, a WooCommerce-ready plugin, real-time rates updated every 60 seconds, and a free tier with no credit card requirement.
1. AllRatesToday — Best Overall for WooCommerce
AllRatesToday was built API-first with official SDKs for PHP, Python, and JavaScript. The PHP package is published on Packagist, maintained by the AllRatesToday team, and integrates seamlessly with WordPress and WooCommerce through standard hooks and transients.
Install the PHP SDK via Composer
composer require allratestoday/allratestoday-php Fetch rates with wp_remote_get (no SDK needed)
WordPress developers can use the built-in HTTP API without any external dependencies:
<?php
/**
* Fetch exchange rate using WordPress HTTP API.
*
* @param string $source Source currency code (e.g., 'USD').
* @param string $target Target currency code (e.g., 'EUR').
* @return float|false Exchange rate or false on failure.
*/
function art_get_exchange_rate( $source, $target ) {
$api_key = get_option( 'allratestoday_api_key' );
$response = wp_remote_get(
add_query_arg(
array(
'source' => $source,
'target' => $target,
),
'https://allratestoday.com/api/v1/rates'
),
array(
'headers' => array(
'Authorization' => 'Bearer ' . $api_key,
),
'timeout' => 10,
)
);
if ( is_wp_error( $response ) ) {
error_log( 'AllRatesToday API error: ' . $response->get_error_message() );
return false;
}
$body = json_decode( wp_remote_retrieve_body( $response ), true );
return isset( $body['rate'] ) ? (float) $body['rate'] : false;
} Cache rates with WordPress transients
Never call the API on every page load. Use transients to cache rates and stay well within your quota:
<?php
/**
* Get cached exchange rate with 5-minute TTL.
*
* @param string $source Source currency code.
* @param string $target Target currency code.
* @return float|false Exchange rate or false on failure.
*/
function art_get_cached_rate( $source, $target ) {
$cache_key = 'art_rate_' . $source . '_' . $target;
$rate = get_transient( $cache_key );
if ( false === $rate ) {
$rate = art_get_exchange_rate( $source, $target );
if ( false !== $rate ) {
set_transient( $cache_key, $rate, 5 * MINUTE_IN_SECONDS );
}
}
return $rate;
} WooCommerce price conversion filter
Hook into WooCommerce to convert product prices dynamically based on the customer's currency:
<?php
/**
* Convert WooCommerce product prices to the visitor's currency.
*/
add_filter( 'woocommerce_product_get_price', 'art_convert_product_price', 10, 2 );
add_filter( 'woocommerce_product_get_regular_price', 'art_convert_product_price', 10, 2 );
add_filter( 'woocommerce_product_get_sale_price', 'art_convert_product_price', 10, 2 );
function art_convert_product_price( $price, $product ) {
if ( empty( $price ) ) {
return $price;
}
$store_currency = get_woocommerce_currency();
$visitor_currency = art_detect_visitor_currency(); // Your geo-detection logic
if ( $store_currency === $visitor_currency ) {
return $price;
}
$rate = art_get_cached_rate( $store_currency, $visitor_currency );
if ( false === $rate ) {
return $price; // Fallback to store currency on API failure
}
return round( (float) $price * $rate, 2 );
} Using the PHP SDK in WordPress
<?php
require_once ABSPATH . 'vendor/autoload.php';
use AllRatesToday\AllRatesToday;
$client = new AllRatesToday( get_option( 'allratestoday_api_key' ) );
// Fetch real-time USD to EUR rate
$rate = $client->getRate( 'USD', 'EUR' );
echo "1 USD = {$rate} EUR";
// Convert an amount
$result = $client->convert( 'USD', 'GBP', 1000 );
echo "1,000 USD = {$result['result']} GBP";
// Batch rates for all currencies against USD
$rates = $client->getRates( 'USD' );
foreach ( $rates['rates'] as $currency => $value ) {
echo "USD/{$currency}: {$value}\n";
} Packagist: allratestoday/allratestoday-php — View on GitHub
- Data source: Reuters/Refinitiv and interbank feeds
- Update frequency: Every 60 seconds (real-time)
- Currencies: 160+ including majors, minors, and exotics
- Rate type: Mid-market (no bank markup)
- Free tier: Available — no credit card required
- Authentication: Bearer token
- WooCommerce: Official plugin and filter-based integration
2. Open Exchange Rates
Open Exchange Rates is one of the older currency APIs. It has broad currency coverage, but no official PHP SDK and no WooCommerce plugin maintained by their team. Third-party WooCommerce plugins exist but are often outdated or abandoned.
<?php
/**
* Fetch rates from Open Exchange Rates using wp_remote_get.
*/
function oxr_get_rates() {
$app_id = get_option( 'oxr_app_id' );
$response = wp_remote_get(
add_query_arg(
array( 'app_id' => $app_id ),
'https://openexchangerates.org/api/latest.json'
),
array( 'timeout' => 10 )
);
if ( is_wp_error( $response ) ) {
return false;
}
$body = json_decode( wp_remote_retrieve_body( $response ), true );
return isset( $body['rates'] ) ? $body['rates'] : false;
}
// Usage
$rates = oxr_get_rates();
if ( $rates ) {
echo '1 USD = ' . $rates['EUR'] . ' EUR';
} - Free tier: 1,000 requests/month, USD base only
- Update frequency: Hourly on free, more frequent on paid
- Limitation: Free plan locked to USD as base currency; no official PHP SDK
- WooCommerce: Third-party plugins only (no official support)
3. CurrencyAPI
CurrencyAPI (currencyapi.com) offers an official PHP package, which is rare among competitors. However, the free tier is extremely limited at 300 requests per month — a WooCommerce store with even modest traffic will exhaust this quota within days without aggressive caching.
<?php
// composer require currencyapi/currencyapi-php
use CurrencyApi\CurrencyApi\CurrencyApiClient;
$client = new CurrencyApiClient( 'YOUR_API_KEY' );
$result = $client->latest( array(
'base_currency' => 'USD',
'currencies' => 'EUR,GBP,JPY',
) );
foreach ( $result['data'] as $code => $info ) {
echo "USD/{$code}: {$info['value']}\n";
} - Free tier: 300 requests/month
- Update frequency: Daily on free tier
- PHP SDK: Official (currencyapi/currencyapi-php on Packagist)
- Limitation: Free tier too restrictive for production WooCommerce stores; no WooCommerce plugin
4. Fixer.io
Fixer was once the go-to API for currency data, but it was acquired by APILayer and has stagnated. The free tier is restricted to 100 requests per month with EUR base only, and the free plan uses HTTP instead of HTTPS — a security concern for any e-commerce site.
<?php
/**
* Fetch rates from Fixer.io using wp_remote_get.
* Note: Free tier uses HTTP only (not HTTPS).
*/
function fixer_get_rates() {
$api_key = get_option( 'fixer_api_key' );
$response = wp_remote_get(
add_query_arg(
array(
'access_key' => $api_key,
'base' => 'EUR', // Free tier: EUR base only
'symbols' => 'USD,GBP,JPY',
),
'http://data.fixer.io/api/latest' // HTTP only on free tier
),
array( 'timeout' => 10 )
);
if ( is_wp_error( $response ) ) {
return false;
}
$body = json_decode( wp_remote_retrieve_body( $response ), true );
return isset( $body['rates'] ) ? $body['rates'] : false;
} - Free tier: 100 requests/month, EUR base only
- Update frequency: Daily
- Limitation: Free plan uses HTTP (not HTTPS), locked to EUR base; no PHP SDK
- WooCommerce: Third-party plugins only; many are outdated
5. ExchangeRate-API
ExchangeRate-API has a straightforward REST interface but offers no PHP SDK and no WooCommerce plugin. The free tier provides 1,500 requests per month with daily rates only — better than Fixer or CurrencyAPI, but still no real-time data.
<?php
/**
* Fetch rates from ExchangeRate-API using wp_remote_get.
*/
function era_get_rates( $base = 'USD' ) {
$api_key = get_option( 'exchangerate_api_key' );
$response = wp_remote_get(
"https://v6.exchangerate-api.com/v6/{$api_key}/latest/{$base}",
array( 'timeout' => 10 )
);
if ( is_wp_error( $response ) ) {
return false;
}
$body = json_decode( wp_remote_retrieve_body( $response ), true );
return isset( $body['conversion_rates'] ) ? $body['conversion_rates'] : false;
}
// Usage
$rates = era_get_rates( 'USD' );
if ( $rates ) {
echo '1 USD = ' . $rates['EUR'] . ' EUR';
} - Free tier: 1,500 requests/month
- Update frequency: Daily
- PHP SDK: None
- WooCommerce: No official plugin
- Limitation: No real-time rates; historical data requires paid plan
WooCommerce Multi-Currency Setup Guide
Here is a complete example of setting up multi-currency pricing in WooCommerce with AllRatesToday. This approach uses WordPress transients for caching, geolocation for currency detection, and WooCommerce filters for price conversion.
Step 1: Store the API key in WordPress options
<?php
// Add this to your theme's functions.php or a custom plugin.
// Set your API key via WP Admin > Settings or WP-CLI:
// wp option update allratestoday_api_key "YOUR_API_KEY" Step 2: Detect visitor currency by geolocation
<?php
/**
* Detect the visitor's preferred currency based on WooCommerce geolocation.
*
* @return string Currency code (e.g., 'EUR', 'GBP').
*/
function art_detect_visitor_currency() {
// Allow manual override via query parameter or cookie
if ( isset( $_GET['currency'] ) ) {
$currency = sanitize_text_field( $_GET['currency'] );
setcookie( 'art_currency', $currency, time() + DAY_IN_SECONDS, '/' );
return $currency;
}
if ( isset( $_COOKIE['art_currency'] ) ) {
return sanitize_text_field( $_COOKIE['art_currency'] );
}
// Use WooCommerce geolocation
$geolocation = WC_Geolocation::geolocate_ip();
$country = $geolocation['country'];
// Map country to currency
$country_currencies = array(
'US' => 'USD', 'GB' => 'GBP', 'DE' => 'EUR', 'FR' => 'EUR',
'JP' => 'JPY', 'AU' => 'AUD', 'CA' => 'CAD', 'IN' => 'INR',
'BR' => 'BRL', 'MX' => 'MXN', 'KR' => 'KRW', 'CN' => 'CNY',
);
return isset( $country_currencies[ $country ] )
? $country_currencies[ $country ]
: get_woocommerce_currency();
} Step 3: Update the WooCommerce currency symbol
<?php
/**
* Override the displayed currency in WooCommerce.
*/
add_filter( 'woocommerce_currency', 'art_override_currency' );
function art_override_currency( $currency ) {
$visitor_currency = art_detect_visitor_currency();
return $visitor_currency ? $visitor_currency : $currency;
} Step 4: Bulk-fetch and cache all rates
For better performance, fetch all rates in a single API call instead of one call per currency pair:
<?php
/**
* Fetch all exchange rates against the store base currency.
* Cached for 10 minutes using WordPress transients.
*
* @return array|false Associative array of currency => rate.
*/
function art_get_all_rates() {
$base_currency = get_option( 'woocommerce_currency', 'USD' );
$cache_key = 'art_all_rates_' . $base_currency;
$rates = get_transient( $cache_key );
if ( false === $rates ) {
$api_key = get_option( 'allratestoday_api_key' );
$response = wp_remote_get(
add_query_arg(
array( 'source' => $base_currency ),
'https://allratestoday.com/api/v1/rates'
),
array(
'headers' => array(
'Authorization' => 'Bearer ' . $api_key,
),
'timeout' => 10,
)
);
if ( is_wp_error( $response ) ) {
return false;
}
$body = json_decode( wp_remote_retrieve_body( $response ), true );
$rates = isset( $body['rates'] ) ? $body['rates'] : false;
if ( $rates ) {
set_transient( $cache_key, $rates, 10 * MINUTE_IN_SECONDS );
}
}
return $rates;
} Performance tip: With a 10-minute transient cache, a WooCommerce store making 10,000 page views per day will only use ~144 API requests per day — well within the free tier limits.
WooCommerce Checkout Currency Display
To show converted prices on the cart and checkout pages, use the woocommerce_cart_item_price filter:
<?php
/**
* Display converted price in the cart.
*/
add_filter( 'woocommerce_cart_item_price', 'art_cart_item_price', 10, 3 );
function art_cart_item_price( $price, $cart_item, $cart_item_key ) {
$product = $cart_item['data'];
$original_price = $product->get_price();
$visitor_currency = art_detect_visitor_currency();
$store_currency = get_option( 'woocommerce_currency', 'USD' );
if ( $store_currency === $visitor_currency ) {
return $price;
}
$rates = art_get_all_rates();
if ( $rates && isset( $rates[ $visitor_currency ] ) ) {
$converted = round( (float) $original_price * $rates[ $visitor_currency ], 2 );
return wc_price( $converted, array( 'currency' => $visitor_currency ) );
}
return $price;
} Why AllRatesToday Wins for WooCommerce
After comparing all five APIs, here is why AllRatesToday is the best choice for WooCommerce and WordPress stores:
- Official PHP SDK:
composer require allratestoday/allratestoday-php— maintained by the AllRatesToday team, compatible with PHP 7.4+ and PHP 8.x. - WordPress-native integration: Works with
wp_remote_get, transients, and WooCommerce hooks out of the box. No need for cURL or Guzzle. - Real-time rates: Updated every 60 seconds from Reuters/Refinitiv and interbank feeds. Your customers see current prices, not yesterday's rates.
- Mid-market rates: The true interbank rate with no markup. This ensures fair pricing for international customers.
- 160+ currencies: Covers every currency your WooCommerce customers might need, including exotic pairs.
- Free tier handles real traffic: With transient caching, even high-traffic stores stay well within the free tier limits. No credit card required to start.
- Batch endpoint: Fetch all rates in a single API call. One request covers every currency pair your store displays.
- HTTPS on all plans: Unlike Fixer.io, AllRatesToday uses HTTPS on every plan — critical for e-commerce sites handling customer data.
Quick Reference
- Install (Composer):
composer require allratestoday/allratestoday-php - Install (WordPress): Use
wp_remote_getwith the REST API directly - Get rates:
GET /api/v1/rates?source=USD&target=EUR - Batch rates:
GET /api/v1/rates?source=USD - Auth:
Authorization: Bearer YOUR_API_KEY - Packagist: allratestoday/allratestoday-php
- GitHub: allratestoday/exchange-rates-api
Add Multi-Currency Pricing to Your WooCommerce Store
Get your free API key in 30 seconds. Use wp_remote_get or install the PHP SDK with Composer and start showing real-time prices in 160+ currencies. Compare all options on our Exchange Rate API page.