laravel-currency maintained by fomvasss
Laravel Currency
Support
If this package is useful to you, consider supporting its development:
USDT TRC20 address:
THLgp6DxiAtbNHvgnKV56vk1L38UuUagKf
A Laravel package for currency conversion and exchange rate management with multiple rate providers.
Features
- Currency conversion with buy / sell / average rates
- Multiple built-in rate providers (Monobank, PrivatBank, NBU, jsDelivr, ExchangeRatesAPI, CurrencyAPI, Fixer)
- Automatic caching of exchange rates with configurable TTL and fallback cache
- Dynamic base currency override with automatic rate recalculation
- Currency formatting with symbols, precision and locale separators
- Helper functions and Blade directives for use in views
- Custom provider support via a simple interface
Requirements
- PHP 8.1+
- Laravel 9.x, 10.x, 11.x, 12.x, or 13.x
Installation
composer require fomvasss/laravel-currency
Publish the configuration file:
php artisan vendor:publish --tag=currency-config
Configuration
The published config file is located at config/currency.php.
Available options
return [
// Default base currency
'default' => 'UAH',
// Default rate provider alias (see 'providers' array)
'default_provider' => env('CURRENCY_DEFAULT_PROVIDER', 'monobank'),
// Available providers
'providers' => [
'nbu' => \Fomvasss\Currency\RateProviders\NbuRateProvider::class,
'monobank' => \Fomvasss\Currency\RateProviders\MonobankRateProvider::class,
'privatbank' => \Fomvasss\Currency\RateProviders\PrivatbankRateProvider::class,
'jsdelivr' => \Fomvasss\Currency\RateProviders\JsDelivrProvider::class,
'exchangeratesapi' => \Fomvasss\Currency\RateProviders\ExchangeRatesApiProvider::class,
'currencyapi' => \Fomvasss\Currency\RateProviders\CurrencyApiProvider::class,
'fixer' => \Fomvasss\Currency\RateProviders\FixerProvider::class,
],
// Primary rate cache TTL in seconds (default: 1 hour)
'cache_ttl' => env('CURRENCY_CACHE_TTL', 3600),
// Fallback cache TTL in seconds — used when primary API is unavailable (default: 1 day)
'cache_ttl_fallback' => env('CURRENCY_CACHE_TTL_FALLBACK', 86400),
// Default rate type: 'buy', 'sell', or 'average'
'default_rate_type' => env('CURRENCY_DEFAULT_RATE_TYPE', 'average'),
// Default decimal precision (can be overridden per currency)
'default_precision' => env('CURRENCY_DEFAULT_PRECISION', 2),
// API keys for paid/key-required providers
'exchange_rates_api_key' => env('EXCHANGE_RATES_API_KEY', null),
'currencyapi_key' => env('CURRENCYAPI_KEY', null),
'fixer_api_key' => env('FIXER_API_KEY', null),
// Active currencies with formatting options
'currencies' => [
'USD' => [
'code' => 'USD',
'title' => 'US Dollar',
'symbol' => '$',
'precision' => 2,
'thousandSeparator' => ',',
'decimalSeparator' => '.',
'symbolPlacement' => 'before',
],
// ... other currencies
],
];
Environment Variables
CURRENCY_DEFAULT_PROVIDER=monobank
CURRENCY_DEFAULT_RATE_TYPE=average
CURRENCY_CACHE_TTL=3600
CURRENCY_CACHE_TTL_FALLBACK=86400
CURRENCY_DEFAULT_PRECISION=2
# For paid providers (optional)
EXCHANGE_RATES_API_KEY=your_key
CURRENCYAPI_KEY=your_key
FIXER_API_KEY=your_key
Rate Providers
| Alias | Class | Currencies | API Key | Notes |
|---|---|---|---|---|
nbu |
NbuRateProvider |
30+ | No | National Bank of Ukraine |
monobank |
MonobankRateProvider |
Multiple | No | Monobank API |
privatbank |
PrivatbankRateProvider |
EUR, USD only | No | PrivatBank API limitation |
jsdelivr |
JsDelivrProvider |
150+ | No | Free CDN, updated daily |
exchangeratesapi |
ExchangeRatesApiProvider |
Multiple | Yes | https://exchangeratesapi.io |
currencyapi |
CurrencyApiProvider |
Multiple | Yes | https://currencyapi.com (300 req/month free) |
fixer |
FixerProvider |
Multiple | Yes | https://fixer.io (100 req/month free) |
Basic Usage
use Fomvasss\Currency\Facades\Currency;
// Convert currencies
$euros = Currency::convert(100, 'USD', 'EUR');
// Get exchange rate
$usdRate = Currency::getRate('USD'); // average by default
$buyRate = Currency::getRate('USD', 'buy');
$sellRate = Currency::getRate('USD', 'sell');
// Get all rates
$allRates = Currency::getRates(); // average
$allRates = Currency::getRates('all'); // ['USD' => ['buy' => ..., 'sell' => ...], ...]
// Format currency
$formatted = Currency::format(1234.56, 'USD'); // $ 1,234.56
$noSymbol = Currency::format(1234.56, 'USD', false); // 1,234.56
Switching Rate Providers
// Switch by alias (recommended)
Currency::useProvider('nbu');
Currency::useProvider('monobank');
Currency::useProvider('jsdelivr');
// Switch via setRateProvider — accepts alias, class name, or instance
Currency::setRateProvider('nbu');
Currency::setRateProvider(\Fomvasss\Currency\RateProviders\NbuRateProvider::class);
Currency::setRateProvider(new NbuRateProvider());
$rate = Currency::getRate('USD');
Base Currency
// Get current base currency
$base = Currency::getBaseCurrency(); // 'UAH' (from config)
// Override base currency at runtime
// All rates returned by getRate() and getRates() are automatically recalculated
Currency::setBaseCurrency('USD');
$rates = Currency::getRates();
// Now returns rates relative to USD: ['EUR' => 0.92, 'UAH' => 41.5, ...]
// USD itself is NOT in the array (it is the base, rate = 1.0)
// Convert after changing base
$amount = Currency::convert(100, 'EUR', 'GBP');
Checking Provider Capabilities
$currencies = Currency::getSupportedCurrencies(); // ['USD', 'EUR', ...]
$count = Currency::getSupportedCurrenciesCount(); // e.g. 150 for jsdelivr
if (Currency::isSupported('JPY')) {
$rate = Currency::getRate('JPY');
}
Active Currencies (from config)
$currencies = Currency::getActiveCurrencies(); // full config array
$codes = Currency::getActiveCurrencyCodes(); // ['UAH', 'USD', 'EUR', ...]
$allConfig = Currency::getAllCurrencies(); // alias for getActiveCurrencies()
$usdConfig = Currency::getCurrencyConfig('USD'); // ['symbol' => '$', 'precision' => 2, ...]
$precision = Currency::getPrecision('USD'); // 2
Cache Management
// Clear cached rates for the current provider
Currency::clearCache();
Fallback cache stores the last successful rates and is used automatically when the primary API is unavailable. Configure its TTL via cache_ttl_fallback or the CURRENCY_CACHE_TTL_FALLBACK env variable.
Helper Functions
Global PHP helpers are available without importing any class:
// Convert amount
$result = currency_convert(100, 'USD', 'EUR');
$result = currency_convert(100, 'USD', 'EUR', 'sell');
// Format with symbol
$output = currency_format(1234.56, 'USD'); // $ 1,234.56
$output = currency_format(1234.56, 'USD', false); // 1,234.56
// Get rate
$rate = currency_rate('USD'); // average
$rate = currency_rate('USD', 'buy');
// Get symbol
$symbol = currency_symbol('USD'); // '$'
Blade Directives
{{-- Convert and output --}}
@currency(100, 'USD', 'EUR')
{{-- Format with symbol --}}
@currencyFormat(1234.56, 'USD')
{{-- Output exchange rate --}}
@currencyRate('USD')
{{-- Output symbol --}}
@currencySymbol('USD')
Event Handling
The package dispatches a CurrencyRateFetchFailed event when an API call fails.
// app/Listeners/HandleCurrencyRateFailure.php
namespace App\Listeners;
use Fomvasss\Currency\Events\CurrencyRateFetchFailed;
use Illuminate\Support\Facades\Log;
class HandleCurrencyRateFailure
{
public function handle(CurrencyRateFetchFailed $event): void
{
Log::error('Currency API failed', [
'provider' => $event->providerClass,
'error' => $event->errorMessage,
'using_fallback' => $event->usingFallback,
]);
}
}
Register in EventServiceProvider:
use Fomvasss\Currency\Events\CurrencyRateFetchFailed;
use App\Listeners\HandleCurrencyRateFailure;
protected $listen = [
CurrencyRateFetchFailed::class => [
HandleCurrencyRateFailure::class,
],
];
Event properties:
| Property | Type | Description |
|---|---|---|
$providerClass |
string | Class name of the failed provider |
$errorMessage |
string | Error description |
$usingFallback |
bool | Whether fallback cache is being used |
$fallbackRates |
array | Fallback rates (if available) |
Fallback Strategy
Use jsdelivr as a free fallback when primary APIs are unavailable:
try {
Currency::useProvider('monobank');
$rate = Currency::getRate('USD');
} catch (\Exception $e) {
Currency::useProvider('jsdelivr'); // free, 150+ currencies, no rate limits
$rate = Currency::getRate('USD');
}
Custom Providers
You can implement your own rate provider by creating a class that extends AbstractRateProvider or implements the RateProvider contract directly.
See the full guide with examples (API keys, multi-source fallback, mock for tests): CUSTOM_PROVIDERS.md.
License
MIT License. See LICENSE for details.