elegantly / laravel-forex
Forex for Laravel
Fund package maintenance!
Requires
- php: ^8.3
- brick/money: ^0.13.0||^0.14.0
- illuminate/contracts: ^13.0
- saloonphp/cache-plugin: ^3.0
- saloonphp/laravel-plugin: ^3.0||^4.0
- saloonphp/rate-limit-plugin: ^2.0
- saloonphp/saloon: ^3.0||^4.0
- spatie/laravel-package-tools: ^1.14.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
README
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. - 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), );
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.