elegantly/laravel-forex
| Install | |
|---|---|
composer require elegantly/laravel-forex |
|
| Latest Version: | v4.3.2 |
| PHP: | ^8.3 |
| Laravel: | 13 |
| Older releases: | 10 · 11 · 12 |
| License: | MIT |
| Last Updated: | Sep 29, 2026 |
| Links: | GitHub · Packagist |
Laravel Forex
Laravel Forex is a simple and flexible package for retrieving the latest and historical foreign exchange rates in your Laravel application.
By default, it uses the free tier from exchangerate-api.com, but you can easily configure it to use any other Forex provider.
Contents
- Features
- Requirements
- Installation
- Configuration
- Usage
- Providers
- Caching & Rate Limiting
- Testing
- Changelog
- Contributing
- Security
- Credits
- License
Features
- Retrieve latest exchange rates for any base currency.
- Retrieve historical exchange rates for a specific date.
- Convert
Moneyinstances between currencies with high precision usingbrick/money. - Validate money amounts with optional currency-aware minimum and maximum bounds.
- Built-in caching and optional rate limiting to keep API usage under control.
- Swap the default provider with a custom implementation via a simple interface.
Requirements
- PHP
^8.3 - Laravel
^13.0
Installation
Install the package via Composer:
composer require elegantly/laravel-forex
Publish the configuration file:
php artisan vendor:publish --tag="forex-config"
Configuration
The published configuration file lives at config/forex.php:
use Brick\Math\RoundingMode;
use Elegantly\Forex\Integrations\ExchangeRateApiFree\ExchangeRateApiFreeConnector;
return [
/**
* Rounding mode used when converting money.
*/
'rounding_mode' => RoundingMode::HalfUp,
'cache' => [
'enabled' => true,
'driver' => env('FOREX_CACHE_DRIVER', env('CACHE_STORE', env('CACHE_DRIVER', 'file'))),
'expiry_seconds' => 86_400, // 1 day
],
'rate_limit' => [
'enabled' => false,
'driver' => env('FOREX_RATE_LIMIT_DRIVER', env('CACHE_STORE', env('CACHE_DRIVER', 'file'))),
'every_seconds' => 3_600, // 1 hour
],
'client' => ExchangeRateApiFreeConnector::class,
'clients' => [
'exchange-rate-api' => [
'token' => env('EXCHANGE_RATE_API_TOKEN'),
],
],
];
Environment Variables
| Variable | Description |
|---|---|
EXCHANGE_RATE_API_TOKEN |
Your API token when using the paid exchangerate-api.com connector. |
FOREX_CACHE_DRIVER |
The cache store used for Forex responses. |
FOREX_RATE_LIMIT_DRIVER |
The cache store used for rate limiting. |
Usage
All public methods are available through the Forex facade:
use Elegantly\Forex\Facades\Forex;
Latest Rates
Fetch the latest rates for a given base currency:
$rates = Forex::latest('USD');
$usdToEur = $rates['EUR'];
Historical Rates
Fetch historical rates for a specific date:
use Carbon\Carbon;
$rates = Forex::rates(Carbon::create(2022, 4, 25), 'USD');
$usdToEur = $rates['EUR'];
Converting Money
Convert a Money instance from one currency to another:
use Brick\Math\RoundingMode;
use Brick\Money\Money;
use Elegantly\Forex\Facades\Forex;
$convertedMoney = Forex::convert(
money: Money::of(100, 'USD'),
currency: 'EUR',
);
$convertedMoney->__toString(); // (EUR) 88.84
You can also convert against historical rates and override the rounding mode:
use Carbon\Carbon;
$convertedMoney = Forex::convert(
money: Money::of(100, 'USD'),
currency: 'EUR',
roundingMode: RoundingMode::Down,
date: Carbon::create(2022, 4, 25),
);
Validating Money
Use ValidMoney in Laravel validation rules to parse a money value and optionally enforce minimum and maximum amounts:
use Brick\Money\Currency;
use Brick\Money\Money;
use Elegantly\Forex\Rules\ValidMoney;
$validated = $request->validate([
'amount' => [
'required',
new ValidMoney(
currency: Currency::of('USD'),
min: Money::of(10, 'EUR'),
max: Money::of(100, 'EUR'),
),
],
]);
The value is parsed using the selected currency. If currency is omitted, the default currency from elegantly/laravel-money is used. To read the currency from another field in the validation data, pass its attribute name instead:
$validated = $request->validate([
'currency' => ['required', 'string'],
'amount' => ['required', new ValidMoney(currency: 'currency')],
]);
When min or max uses a different currency, the parsed amount is converted using the latest Forex rates before comparison. Bounds are inclusive; validation fails when the amount is below min or above max.
Refreshing Rates
By default, rates are cached according to your configuration. To bypass the cache and fetch fresh data:
// Refresh latest rates
Forex::refreshLatest('USD');
// Refresh historical rates
Forex::refreshRates(Carbon::create(2022, 4, 25), 'USD');
Providers
ExchangeRate-Api.com
The package ships with two ready-to-use connectors for exchangerate-api.com:
ExchangeRateApiFreeConnector— uses the free public endpoint. Rates are updated once a day and historical data is not supported.ExchangeRateApiConnector— uses the authenticated v6 API. Requires a token and supports historical rates.
To use the paid connector, update your config:
use Elegantly\Forex\Integrations\ExchangeRateApi\ExchangeRateApiConnector;
'client' => ExchangeRateApiConnector::class,
And add your token to .env:
EXCHANGE_RATE_API_TOKEN=your-api-token
Custom Client
Want to use a different provider? Implement the ForexClient interface:
use Carbon\CarbonInterface;
use Elegantly\Forex\ForexClient;
class MyCustomForexClient implements ForexClient
{
public function latest(string $currency): array
{
// Return an associative array of currency code => rate
}
public function rates(CarbonInterface $date, string $currency): array
{
// Return historical rates for the given date
}
}
Then set it as the active client:
'client' => \App\Services\MyCustomForexClient::class,
Caching & Rate Limiting
The package uses Saloon's cache and rate-limit plugins to reduce API calls and avoid hitting provider limits.
- Caching is enabled by default and stores responses for the configured
expiry_seconds. - Rate limiting is disabled by default. Enable it to throttle requests to one per
every_secondsinterval.
Both features use the cache store configured in forex.php.
Testing
Run the test suite with:
composer test
Run the static analysis suite with:
composer analyse
Format the code with:
composer format
Changelog
See the CHANGELOG for details on recent updates.
Contributing
Contributions are welcome! Please read the CONTRIBUTING guide for details.
Security
If you discover any security-related issues, please refer to our security policy.
Credits
License
This package is open-source software licensed under the MIT license.
Related Packages
Version History
| Version | Released | PHP | Laravel | License |
|---|---|---|---|---|
| v4.3.2 | ^8.3 | ^13.0 | MIT | |
| v4.3.1 | ^8.3 | ^13.0 | MIT | |
| v4.3.0 | ^8.3 | ^13.0 | MIT | |
| v4.2.1 | ^8.3 | ^13.0 | MIT | |
| v4.2.0 | ^8.3 | ^13.0 | MIT | |
| v4.1.0 | ^8.3 | ^13.0 | MIT | |
| v4.0.3 | ^8.3 | ^13.0 | MIT | |
| v4.0.2 | ^8.3 | ^13.0 | MIT | |
| v4.0.1 | ^8.3 | ^13.0 | MIT | |
| v4.0.0 | ^8.1 | ^11.0| | MIT | |
| v3.0.0 | ^8.1 | ^11.0| | MIT | |
| v2.5.1 | ^8.1 | ^11.0| | MIT | |
| v2.5.0 | ^8.1 | ^11.0| | MIT | |
| v2.4.0 | ^8.1 | ^10.0| | MIT | |
| v2.3.0 | ^8.1 | ^10.0| | MIT | |
| v2.2.0 | ^8.1 | ^10.0| | MIT | |
| v2.1.3 | ^8.1 | ^10.0| | MIT | |
| v2.1.2 | ^8.1 | ^10.0| | MIT | |
| v2.1.1 | ^8.1 | ^10.0| | MIT | |
| v2.1.0 | ^8.1 | ^10.0| | MIT | |
| v2.0.1 | ^8.1 | ^10.0| | MIT | |
| v2.0.0 | ^8.1 | ^10.0| | MIT | |
| v1.2.0 | ^8.1 | ^10.0| | MIT | |
| v1.1.2 | ^8.1 | ^10.0| | MIT | |
| v1.1.1 | ^8.1 | ^10.0| | MIT | |
| v1.1.0 | ^8.1 | ^10.0| | MIT | |
| v1.0.6 | ^8.1 | ^10.0| | MIT | |
| v1.0.5 | ^8.1 | ^10.0 | MIT | |
| v1.0.4 | ^8.1 | ^10.0 | MIT | |
| v1.0.3 | ^8.1 | ^10.0 | MIT |
Showing the latest 30 of 33. See every release on Packagist