ブログに戻る

Currency API for PHP Integration Guide

V
Vlado Grigirov
April 05, 2026

PHP powers over 75% of websites with a known server-side language, making it the most common backend for applications that need currency conversion. Whether you are building a Laravel application, a WordPress plugin, or a custom PHP project, integrating a currency API correctly matters for performance and reliability. This guide covers everything from basic cURL requests to production-ready implementations with Guzzle, caching, and error handling.

Why Use a Currency API in PHP?

PHP applications frequently need exchange rate data for e-commerce pricing, invoice generation, financial reporting, and multi-currency checkout flows. Hardcoding rates is impractical since currencies fluctuate constantly. A dedicated currency API like Finexly provides real-time and historical rates for 170+ currencies with sub-50ms response times.

Getting Started

First, sign up for a free API key at Finexly. The free tier includes 1,000 requests per month with no credit card required.

Method 1: PHP cURL (No Dependencies)

The simplest approach uses PHP's built-in cURL extension:

<?php

function getExchangeRates(string $base = 'USD', array $symbols = []): array
{
    $apiKey = 'YOUR_API_KEY';
    $url = 'https://api.finexly.com/v1/latest?base=' . $base;

    if (!empty($symbols)) {
        $url .= '&symbols=' . implode(',', $symbols);
    }

    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . $apiKey,
            'Accept: application/json',
        ],
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode !== 200) {
        throw new RuntimeException("API request failed with status $httpCode");
    }

    return json_decode($response, true);
}

// Usage
$rates = getExchangeRates('USD', ['EUR', 'GBP', 'JPY']);
echo "1 USD = {$rates['rates']['EUR']} EUR\n";

Method 2: Guzzle HTTP Client

For production applications, Guzzle provides a cleaner interface with automatic retries and connection pooling:

<?php

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

class CurrencyApiClient
{
    private Client $client;

    public function __construct(string $apiKey)
    {
        $this->client = new Client([
            'base_uri' => 'https://api.finexly.com/v1/',
            'timeout' => 10,
            'headers' => [
                'Authorization' => 'Bearer ' . $apiKey,
                'Accept' => 'application/json',
            ],
        ]);
    }

    public function getLatestRates(string $base = 'USD', array $symbols = []): array
    {
        $query = ['base' => $base];
        if (!empty($symbols)) {
            $query['symbols'] = implode(',', $symbols);
        }

        try {
            $response = $this->client->get('latest', ['query' => $query]);
            return json_decode($response->getBody()->getContents(), true);
        } catch (RequestException $e) {
            throw new RuntimeException(
                'Currency API error: ' . $e->getMessage(),
                $e->getCode()
            );
        }
    }

    public function convert(string $from, string $to, float $amount): float
    {
        $response = $this->client->get('convert', [
            'query' => compact('from', 'to', 'amount'),
        ]);

        $data = json_decode($response->getBody()->getContents(), true);
        return $data['result'];
    }

    public function getHistoricalRates(string $date, string $base = 'USD'): array
    {
        $response = $this->client->get('historical', [
            'query' => compact('date', 'base'),
        ]);

        return json_decode($response->getBody()->getContents(), true);
    }
}

Install Guzzle via Composer:

composer require guzzlehttp/guzzle

Laravel Integration

If you are using Laravel, you can create a service class that integrates with the framework's caching and configuration:

<?php

namespace App\Services;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;

class CurrencyService
{
    private string $apiKey;
    private string $baseUrl = 'https://api.finexly.com/v1';

    public function __construct()
    {
        $this->apiKey = config('services.finexly.api_key');
    }

    public function getRate(string $from, string $to): float
    {
        $cacheKey = "exchange_rate:{$from}:{$to}";

        return Cache::remember($cacheKey, now()->addMinutes(5), function () use ($from, $to) {
            $response = Http::withToken($this->apiKey)
                ->get("{$this->baseUrl}/latest", [
                    'base' => $from,
                    'symbols' => $to,
                ]);

            $response->throw();

            return $response->json("rates.{$to}");
        });
    }

    public function convert(string $from, string $to, float $amount): float
    {
        $rate = $this->getRate($from, $to);
        return round($amount * $rate, 2);
    }
}

Register it in your config/services.php:

'finexly' => [
    'api_key' => env('FINEXLY_API_KEY'),
],

Then add your key to .env:

FINEXLY_API_KEY=your_api_key_here

Caching Strategies

Exchange rates do not change every millisecond. Caching responses reduces API calls and improves performance:

// File-based cache (no dependencies)
function getCachedRates(string $base, int $ttl = 300): array
{
    $cacheFile = sys_get_temp_dir() . "/rates_{$base}.json";

    if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $ttl) {
        return json_decode(file_get_contents($cacheFile), true);
    }

    $rates = getExchangeRates($base);
    file_put_contents($cacheFile, json_encode($rates));

    return $rates;
}

For Laravel, the Cache::remember() approach shown above handles this automatically with your configured cache driver (Redis, Memcached, or file).

Error Handling and Rate Limits

Production applications must handle API errors gracefully:

function safeGetRates(string $base): ?array
{
    try {
        $rates = getExchangeRates($base);

        if (!isset($rates['rates'])) {
            error_log('Unexpected API response format');
            return null;
        }

        return $rates;
    } catch (RuntimeException $e) {
        error_log('Currency API error: ' . $e->getMessage());

        // Fall back to cached data if available
        $cacheFile = sys_get_temp_dir() . "/rates_{$base}.json";
        if (file_exists($cacheFile)) {
            return json_decode(file_get_contents($cacheFile), true);
        }

        return null;
    }
}

The Finexly API returns standard HTTP status codes and rate limit headers (X-RateLimit-Remaining, X-RateLimit-Reset) so your application can handle limits proactively. Check the API documentation for the full error code reference.

Building a Simple Currency Converter

Here is a complete working example that ties everything together:

<?php
require 'vendor/autoload.php';

$client = new CurrencyApiClient('YOUR_API_KEY');

// Convert 500 EUR to USD
$result = $client->convert('EUR', 'USD', 500);
echo "500 EUR = $result USD\n";

// Get all rates for GBP
$rates = $client->getLatestRates('GBP');
foreach ($rates['rates'] as $currency => $rate) {
    echo "GBP/$currency: $rate\n";
}

// Historical rate from last month
$historical = $client->getHistoricalRates('2026-03-01', 'USD');
echo "USD/EUR on March 1: {$historical['rates']['EUR']}\n";

Next Steps

Now that you have currency conversion working in PHP, explore these related guides:

Ready to start? Get your free API key and integrate exchange rates into your PHP application in minutes.

Vlado Grigirov

Senior Currency Markets Analyst & Financial Strategist

Vlado Grigirov is a senior currency markets analyst and financial strategist with over 14 years of experience in foreign exchange markets, cross-border finance, and currency risk management. He has wo...

View full profile →

この記事を共有する