Home Documentation Playground Pricing API Status Blog About FAQ Support

Best Exchange Rate API for PHP and Laravel (2026)

Reviewed by Madhushan, Fintech Developer — May 2026
Programming code on computer screen

PHP powers over 75% of the web, and Laravel is the most popular PHP framework by a wide margin. If your Laravel application handles multi-currency pricing, international payments, invoicing, or financial reporting, you need a currency API that integrates cleanly with the PHP and Laravel ecosystem.

The problem: most currency APIs treat PHP as an afterthought. They offer no Composer package, no Laravel service provider, and force you to write boilerplate Guzzle code for every call. Some have community-maintained wrappers that break when the API changes or the maintainer moves on. Others cap their free tier so aggressively that you burn through your quota during local development.

This article compares the 5 most popular exchange rate APIs for PHP and Laravel in 2026 and shows you exactly how to integrate each one — from Composer install to production-ready caching. Spoiler: AllRatesToday is the clear winner for PHP developers, with an official Packagist package, a Laravel service provider, real-time mid-market rates, and a free tier that does not require a credit card.

Side-by-Side Comparison

Here is an honest look at how the top 5 exchange rate APIs stack up for PHP and Laravel developers:

API PHP SDK Composer Package Free Tier Laravel Integration Update Speed
AllRatesToday Official allratestoday/allratestoday-php Free, no CC Service provider 60 seconds
Open Exchange Rates Community only Community packages 1,000 req/mo Manual setup Hourly
Fixer.io No None 100 req/mo Manual setup Daily
CurrencyAPI Official currencyapi/currencyapi-php 300 req/mo Manual setup Daily
ExchangeRate-API No None 1,500 req/mo Manual setup Daily

Key takeaway: AllRatesToday is the only API on this list that offers an official Composer package with a dedicated Laravel service provider, real-time rates updated every 60 seconds, historical data on the free tier, and no credit card requirement.

1. AllRatesToday — Best Overall for PHP and Laravel

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 ships with a Laravel service provider that handles configuration, dependency injection, and caching out of the box.

Install via Composer

composer require allratestoday/allratestoday-php

Basic PHP usage (no framework)

<?php

require 'vendor/autoload.php';

use AllRatesToday\AllRatesToday;

$client = new AllRatesToday('YOUR_API_KEY');

// Fetch real-time USD to EUR rate
$rate = $client->getRate('USD', 'EUR');
echo "1 USD = {$rate} EUR\n";

Convert an amount

<?php

$result = $client->convert('USD', 'EUR', 1000);

echo "\$1,000 = €{$result['result']}\n";
echo "Rate used: {$result['rate']}\n";
echo "Timestamp: {$result['time']}\n";

Fetch historical rates

<?php

$history = $client->getHistoricalRates('USD', 'EUR', '30d');

foreach ($history['rates'] as $point) {
    echo "{$point['time']}: {$point['rate']}\n";
}

Using Guzzle directly (no SDK)

If you prefer raw HTTP calls, here is how to use Guzzle:

<?php

require 'vendor/autoload.php';

use GuzzleHttp\Client;

$http = new Client([
    'base_uri' => 'https://allratestoday.com/api/v1/',
    'headers' => [
        'Authorization' => 'Bearer YOUR_API_KEY',
        'Accept' => 'application/json',
    ],
]);

$response = $http->get('rates', [
    'query' => [
        'source' => 'USD',
        'target' => 'EUR',
    ],
]);

$data = json_decode($response->getBody(), true);
echo "1 USD = {$data['rate']} EUR\n";
echo "Updated: {$data['time']}\n";

Laravel service provider setup

The AllRatesToday PHP SDK includes a Laravel service provider that auto-registers. After installing via Composer, publish the config file:

php artisan vendor:publish --tag=allratestoday-config

Add your API key to .env:

ALLRATESTODAY_API_KEY=your_api_key_here

The published config file (config/allratestoday.php):

<?php

return [
    'api_key' => env('ALLRATESTODAY_API_KEY'),
    'base_url' => env('ALLRATESTODAY_BASE_URL', 'https://allratestoday.com/api/v1'),
    'timeout' => env('ALLRATESTODAY_TIMEOUT', 10),
    'cache' => [
        'enabled' => env('ALLRATESTODAY_CACHE_ENABLED', true),
        'ttl' => env('ALLRATESTODAY_CACHE_TTL', 300), // 5 minutes
    ],
];

Using dependency injection in Laravel

<?php

namespace App\Http\Controllers;

use AllRatesToday\AllRatesToday;
use Illuminate\Http\JsonResponse;

class CurrencyController extends Controller
{
    public function __construct(
        private AllRatesToday $rates
    ) {}

    public function convert(string $from, string $to, float $amount): JsonResponse
    {
        $result = $this->rates->convert($from, $to, $amount);

        return response()->json([
            'from' => $from,
            'to' => $to,
            'amount' => $amount,
            'converted' => $result['result'],
            'rate' => $result['rate'],
            'timestamp' => $result['time'],
        ]);
    }

    public function latest(string $source = 'USD'): JsonResponse
    {
        $rate = $this->rates->getRate($source, request('target', 'EUR'));

        return response()->json([
            'source' => $source,
            'target' => request('target', 'EUR'),
            'rate' => $rate,
        ]);
    }
}

Caching with Laravel's Cache facade

Caching exchange rates reduces API calls and improves response times. Here is a production-ready service class that wraps AllRatesToday with Laravel's Cache facade:

<?php

namespace App\Services;

use AllRatesToday\AllRatesToday;
use Illuminate\Support\Facades\Cache;

class ExchangeRateService
{
    public function __construct(
        private AllRatesToday $client
    ) {}

    /**
     * Get exchange rate with caching.
     * Default TTL: 5 minutes (300 seconds).
     */
    public function getRate(string $source, string $target, int $ttl = 300): float
    {
        $cacheKey = "fx_rate_{$source}_{$target}";

        return Cache::remember($cacheKey, $ttl, function () use ($source, $target) {
            return $this->client->getRate($source, $target);
        });
    }

    /**
     * Convert amount with cached rate.
     */
    public function convert(string $source, string $target, float $amount): array
    {
        $rate = $this->getRate($source, $target);

        return [
            'source' => $source,
            'target' => $target,
            'amount' => $amount,
            'result' => round($amount * $rate, 2),
            'rate' => $rate,
        ];
    }

    /**
     * Get historical rate (cached for 24 hours since historical data doesn't change).
     */
    public function getHistoricalRate(string $source, string $target, string $date): float
    {
        $cacheKey = "fx_historical_{$source}_{$target}_{$date}";

        return Cache::remember($cacheKey, 86400, function () use ($source, $target, $date) {
            $data = $this->client->getHistoricalRates($source, $target, $date);
            return $data['rate'];
        });
    }

    /**
     * Flush all cached exchange rates.
     */
    public function clearCache(): void
    {
        Cache::flush(); // Or use tagged cache for more precision
    }
}

Register it in your AppServiceProvider:

<?php

// app/Providers/AppServiceProvider.php

use App\Services\ExchangeRateService;
use AllRatesToday\AllRatesToday;

public function register(): void
{
    $this->app->singleton(ExchangeRateService::class, function ($app) {
        return new ExchangeRateService($app->make(AllRatesToday::class));
    });
}

Laravel Artisan command for rate updates

<?php

namespace App\Console\Commands;

use App\Services\ExchangeRateService;
use Illuminate\Console\Command;

class UpdateExchangeRates extends Command
{
    protected $signature = 'rates:update {--source=USD} {--targets=EUR,GBP,JPY,CAD,AUD}';
    protected $description = 'Fetch and cache the latest exchange rates';

    public function handle(ExchangeRateService $service): int
    {
        $source = $this->option('source');
        $targets = explode(',', $this->option('targets'));

        $this->info("Updating rates for {$source}...");

        foreach ($targets as $target) {
            $rate = $service->getRate($source, trim($target), 600);
            $this->line("  {$source}/{$target}: {$rate}");
        }

        $this->info('Rates updated and cached.');
        return Command::SUCCESS;
    }
}

Schedule it in routes/console.php or app/Console/Kernel.php:

// routes/console.php (Laravel 11+)
Schedule::command('rates:update')->everyFiveMinutes();

Packagist: allratestoday/allratestoday-phpView on GitHub

2. Open Exchange Rates

Open Exchange Rates has been around since 2012 but has no official PHP SDK. You need to use Guzzle or file_get_contents directly. There are community-maintained Composer packages, but they are not officially supported and may break without warning.

<?php

use GuzzleHttp\Client;

$http = new Client();
$appId = 'YOUR_APP_ID';

$response = $http->get("https://openexchangerates.org/api/latest.json", [
    'query' => [
        'app_id' => $appId,
        'base' => 'USD', // Free tier: USD only
    ],
]);

$data = json_decode($response->getBody(), true);
$eurRate = $data['rates']['EUR'];
echo "1 USD = {$eurRate} EUR\n";

3. Fixer.io

Fixer was popular years ago but has stagnated since its acquisition by APILayer. There is no PHP SDK, no Composer package, and the free tier is nearly unusable at 100 requests per month with EUR-only base currency and HTTP-only access (no HTTPS).

<?php

$apiKey = 'YOUR_API_KEY';

// Note: free tier is HTTP only, not HTTPS
$url = "http://data.fixer.io/api/latest?"
    . http_build_query([
        'access_key' => $apiKey,
        'base' => 'EUR',  // Free tier: EUR base only
        'symbols' => 'USD,GBP,JPY',
    ]);

$response = file_get_contents($url);
$data = json_decode($response, true);

foreach ($data['rates'] as $currency => $rate) {
    echo "EUR/{$currency}: {$rate}\n";
}

4. CurrencyAPI

CurrencyAPI (currencyapi.com) does offer an official PHP package on Packagist, which puts it ahead of most competitors on developer experience. However, the free tier is limited to 300 requests per month with daily-only rates, and there is no dedicated Laravel service provider.

<?php

// composer require currencyapi/currencyapi-php
use CurrencyApi\CurrencyApi\CurrencyApiClient;

$client = new CurrencyApiClient('YOUR_API_KEY');

$result = $client->latest([
    'base_currency' => 'USD',
    'currencies' => 'EUR,GBP,JPY',
]);

foreach ($result['data'] as $code => $info) {
    echo "USD/{$code}: {$info['value']}\n";
}

5. ExchangeRate-API

ExchangeRate-API offers a simple REST interface with no PHP SDK and no Composer package. The free tier gives 1,500 requests per month with daily rates only.

<?php

$apiKey = 'YOUR_API_KEY';
$url = "https://v6.exchangerate-api.com/v6/{$apiKey}/latest/USD";

$response = file_get_contents($url);
$data = json_decode($response, true);

$eurRate = $data['conversion_rates']['EUR'];
echo "1 USD = {$eurRate} EUR\n";
echo "Last updated: {$data['time_last_update_utc']}\n";

Laravel E-Commerce: Multi-Currency Pricing

A common use case is displaying product prices in the visitor's local currency. Here is a complete implementation using AllRatesToday with Laravel:

Middleware for currency detection

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class DetectCurrency
{
    private array $currencyMap = [
        'US' => 'USD', 'GB' => 'GBP', 'DE' => 'EUR', 'FR' => 'EUR',
        'JP' => 'JPY', 'CA' => 'CAD', 'AU' => 'AUD', 'CH' => 'CHF',
        'IN' => 'INR', 'BR' => 'BRL', 'MX' => 'MXN', 'KR' => 'KRW',
    ];

    public function handle(Request $request, Closure $next)
    {
        $currency = $request->query('currency')
            ?? $request->cookie('currency')
            ?? $this->detectFromCountry($request);

        $request->merge(['display_currency' => $currency]);

        return $next($request);
    }

    private function detectFromCountry(Request $request): string
    {
        $country = $request->header('CF-IPCountry', 'US');
        return $this->currencyMap[$country] ?? 'USD';
    }
}

Blade helper for price display

<?php

// app/Helpers/CurrencyHelper.php

namespace App\Helpers;

use App\Services\ExchangeRateService;

class CurrencyHelper
{
    public static function formatPrice(
        float $amountUsd,
        string $targetCurrency
    ): string {
        if ($targetCurrency === 'USD') {
            return '$' . number_format($amountUsd, 2);
        }

        $service = app(ExchangeRateService::class);
        $converted = $service->convert('USD', $targetCurrency, $amountUsd);

        $symbols = [
            'EUR' => '€', 'GBP' => '£', 'JPY' => '¥',
            'CAD' => 'CA$', 'AUD' => 'A$', 'CHF' => 'CHF ',
            'INR' => '₹', 'BRL' => 'R$', 'MXN' => 'MX$',
        ];

        $symbol = $symbols[$targetCurrency] ?? $targetCurrency . ' ';
        return $symbol . number_format($converted['result'], 2);
    }
}

Use it in Blade templates:

{{-- resources/views/products/show.blade.php --}}

<div class="price">
    {{ CurrencyHelper::formatPrice($product->price_usd, request('display_currency', 'USD')) }}
</div>

Laravel API Routes

Add currency conversion endpoints to your Laravel API:

<?php

// routes/api.php

use App\Http\Controllers\CurrencyController;

Route::prefix('currency')->group(function () {
    Route::get('/rate/'/rate/{from}/{to}'#123;from'/rate/{from}/{to}'#125;/'/rate/{from}/{to}'#123;to'/rate/{from}/{to}'#125;', [CurrencyController::class, 'latest']);
    Route::get('/convert/'/convert/{from}/{to}/{amount}'#123;from'/convert/{from}/{to}/{amount}'#125;/'/convert/{from}/{to}/{amount}'#123;to'/convert/{from}/{to}/{amount}'#125;/'/convert/{from}/{to}/{amount}'#123;amount'/convert/{from}/{to}/{amount}'#125;', [CurrencyController::class, 'convert']);
});

Test it:

curl http://localhost:8000/api/currency/rate/USD/EUR
curl http://localhost:8000/api/currency/convert/USD/EUR/500

Why AllRatesToday Wins for PHP and Laravel

After comparing all five APIs, here is why AllRatesToday is the best choice for PHP and Laravel developers:

Quick Reference

Start Building with PHP, Laravel, and Real-Time Rates

Get your free API key in 30 seconds. Install the SDK with composer require allratestoday/allratestoday-php and fetch real-time mid-market rates for 160+ currencies. Compare all options on our Exchange Rate API page.

Get Your Free API Key