Integration guide
Add currency exchange rates and conversion to Laravel
Use the Laravel HTTP facade and cache to fetch current rates. Set cache expiration from nextUpdateAt and keep CXR_API_KEY in server configuration.
1. Get a free API key
Sign up at https://currencyexchangerate-api.com/auth/login, then create a key under API keys in the console. The free plan includes 3,000 requests per month with no credit card. Store the secret as CXR_API_KEY in server-side environment configuration; never expose it in browser code.
.env
shellCXR_API_KEY=cxr_your_secret_key2. Create a reusable client and cache rates
Use the standard HTTP client. Cache every /latest response until nextUpdateAt: rates change at most once by then, and reusing the response saves quota. The helper also exposes /convert.
app/Services/Rates.php
PHP<?php namespace App\Services; use Illuminate\Support\Carbon;use Illuminate\Support\Facades\Cache;use Illuminate\Support\Facades\Http; // config/services.php: 'cxr' => ['key' => env('CXR_API_KEY')],class Rates{ private string $base = 'https://api.currencyexchangerate-api.com/api/v1'; private function get(string $path): array { return Http::withToken(config('services.cxr.key')) ->acceptJson() ->get($this->base . $path) ->throw() ->json(); } public function latest(string $base = 'USD', string $symbols = 'EUR,GBP'): array { $key = "rates:$base:$symbols"; if (Cache::has($key)) { return Cache::get($key); } $query = http_build_query(compact('base', 'symbols')); $data = $this->get('/latest?' . $query); Cache::put($key, $data, Carbon::parse($data['nextUpdateAt'])); return $data; } public function convert(string $from, string $to, float $amount): array { $query = http_build_query(compact('from', 'to', 'amount')); return $this->get('/convert?' . $query); }}3. Use it in Laravel
Call the helper from a server route, controller, view, command, or script. Format converted values for the user’s locale.
app/Http/Controllers/ConversionController.php
PHP$data = $rates->convert('EUR', 'GBP', 100);$formatter = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);$data['formatted'] = $formatter->formatCurrency($data['result'], $data['to']); return response()->json($data);4. Handle API errors
A 401 means the key is invalid. A 429 can mean a rate limit or quota limit; read Retry-After in seconds before retrying. Other errors use application/problem+json.
app/Http/Controllers/ConversionController.php
PHPuse Illuminate\Http\Client\RequestException; try { $data = $rates->convert('EUR', 'GBP', 100);} catch (RequestException $e) { $status = $e->response->status(); if ($status === 401) { abort(500, 'Check CXR_API_KEY'); } return response() ->json($e->response->json(), $status === 429 ? 429 : 502) ->header('Retry-After', (string) $e->response->header('Retry-After'));}5. Format the amount for display
Use locale-aware currency formatting instead of adding a symbol manually.
format.php
PHP$formatter = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);echo $formatter->formatCurrency(85.249105, 'EUR');