yassine-as / laravel-multi-currency
Laravel package for multi-currency support with automatic conversion
Requires
- php: ^8.0
- guzzlehttp/guzzle: ^7.0
- laravel/framework: ^9.0|^10.0|^11.0
README
A comprehensive Laravel package for multi-currency support with automatic conversion, IP-based currency detection, caching, and seamless integration.
โจ Features
- ๐ Automatic Currency Detection - Detects user's currency based on IP geolocation
- ๐ฑ Real-time Exchange Rates - Fetches rates from multiple providers (ExchangeRate-API, CurrencyAPI)
- โก Smart Caching - Database + memory caching to optimize performance
- ๐๏ธ Manual Currency Switching - User-friendly dropdown with AJAX support
- ๐ช Session & Cookie Support - Remembers user preferences
- ๐จ Blade Directives - Easy integration with
@currency()
and@currencySymbol
- ๐ก๏ธ Middleware Support - Automatic currency detection per request
- ๐ง Artisan Commands - Update exchange rates via command line
- ๐ฑ Responsive UI - Ready-to-use currency switcher component
๐ Installation
Install the package via Composer:
composer require yassine-as/laravel-multi-currency
Publish Configuration & Migrations
# Publish config file php artisan vendor:publish --provider="YassineAs\MultiCurrency\MultiCurrencyServiceProvider" --tag="config" # Publish migrations php artisan vendor:publish --provider="YassineAs\MultiCurrency\MultiCurrencyServiceProvider" --tag="migrations" # Publish views (optional) php artisan vendor:publish --provider="YassineAs\MultiCurrency\MultiCurrencyServiceProvider" --tag="views"
Run Migrations
php artisan migrate
โ๏ธ Configuration
Add these variables to your .env
file:
# Base currency for your products DEFAULT_CURRENCY=USD # Exchange rate provider (exchangerate-api or currencyapi) EXCHANGE_RATE_PROVIDER=exchangerate-api # API Keys (get free keys from providers) EXCHANGE_RATE_API_KEY=your_exchangerate_api_key CURRENCY_API_KEY=your_currency_api_key # Auto-detect currency based on user's IP AUTO_DETECT_CURRENCY=true # Cache duration in seconds (3600 = 1 hour) CURRENCY_CACHE_DURATION=3600
Get Free API Keys
ExchangeRate-API (Recommended):
- Visit exchangerate-api.com
- Sign up for free (1,500 requests/month)
- Copy your API key to
EXCHANGE_RATE_API_KEY
CurrencyAPI (Alternative):
- Visit currencyapi.com
- Sign up for free (300 requests/month)
- Copy your API key to
CURRENCY_API_KEY
๐ Usage
1. In Blade Templates
{{-- Display price with current currency --}} <p>Price: @currency($product->price)</p> {{-- Display just the currency symbol --}} <span>@currencySymbol</span> {{-- Include the currency switcher dropdown --}} @include('multi-currency::currency-switcher') {{-- Convert specific amount --}} <p>Converted: @currency(100, 'EUR')</p>
2. In Controllers
<?php use YassineAs\MultiCurrency\Facades\Currency; class ProductController extends Controller { public function show(Product $product) { // Get current currency $currentCurrency = Currency::getCurrentCurrency(); // e.g., 'EUR' // Get currency symbol $symbol = Currency::getCurrentSymbol(); // e.g., 'โฌ' // Convert price $convertedPrice = Currency::convert($product->price, 'USD', 'EUR'); // Format price with current currency $formattedPrice = Currency::format($product->price); // Set user's currency Currency::setCurrency('SAR'); // Get all supported currencies $currencies = Currency::getSupportedCurrencies(); return view('products.show', compact('product', 'formattedPrice')); } }
3. In Models
Add these methods to your Product model:
<?php class Product extends Model { // Get price in specific currency public function getPriceInCurrency($currency = null) { return app('YassineAs\MultiCurrency\Services\CurrencyService') ->convert($this->price, config('multi-currency.default_currency'), $currency); } // Get formatted price with currency symbol public function getFormattedPrice($currency = null) { return app('YassineAs\MultiCurrency\Services\CurrencyService') ->format($this->price, $currency); } }
4. AJAX Currency Switching
The package includes a ready-to-use currency switcher:
{{-- Add to your layout --}} @include('multi-currency::currency-switcher') {{-- Or create custom switcher --}} <select id="currency-selector"> @foreach(Currency::getSupportedCurrencies() as $code => $currency) <option value="{{ $code }}" {{ Currency::getCurrentCurrency() === $code ? 'selected' : '' }}> {{ $currency['symbol'] }} {{ $currency['name'] }} </option> @endforeach </select> <script> document.getElementById('currency-selector').addEventListener('change', function() { fetch('/currency/switch', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }, body: JSON.stringify({ currency: this.value }) }).then(() => location.reload()); }); </script>
๐๏ธ Artisan Commands
Refresh Exchange Rates
# Update all exchange rates php artisan currency:refresh-rates # Update rates with specific base currency php artisan currency:refresh-rates --base=EUR
Schedule Automatic Updates
Add to your app/Console/Kernel.php
:
protected function schedule(Schedule $schedule) { // Update exchange rates every hour $schedule->command('currency:refresh-rates')->hourly(); }
๐ Supported Currencies
The package supports these currencies by default:
Code | Currency | Symbol |
---|---|---|
USD | US Dollar | $ |
EUR | Euro | โฌ |
GBP | British Pound | ยฃ |
SAR | Saudi Riyal | ุฑ.ุณ |
AED | UAE Dirham | ุฏ.ุฅ |
EGP | Egyptian Pound | ุฌ.ู |
Add More Currencies
Edit config/multi-currency.php
:
'supported_currencies' => [ 'USD' => ['symbol' => '$', 'name' => 'US Dollar'], 'EUR' => ['symbol' => 'โฌ', 'name' => 'Euro'], 'JPY' => ['symbol' => 'ยฅ', 'name' => 'Japanese Yen'], 'CAD' => ['symbol' => 'C$', 'name' => 'Canadian Dollar'], // Add more currencies... ],
๐ฃ๏ธ API Routes
The package provides these routes:
POST /currency/switch # Switch currency GET /currency/supported # Get supported currencies
๐ง Advanced Configuration
Custom Exchange Rate Provider
Create your own provider:
// In your ExchangeRateService protected function fetchFromCustomApi($fromCurrency, $toCurrency, $config) { // Implement your custom API logic $response = Http::get('https://your-api.com/rates', [ 'from' => $fromCurrency, 'to' => $toCurrency, 'key' => $config['api_key'] ]); return $response->json()['rate'] ?? null; }
Custom Geolocation Service
Override the default IP detection:
// In config/multi-currency.php 'custom_geolocation' => true, // Create your own GeolocationService class CustomGeolocationService extends GeolocationService { public function detectCurrency($ip = null) { // Your custom logic return 'USD'; } }
๐งช Testing
# Test currency conversion Currency::convert(100, 'USD', 'EUR'); # Test formatting Currency::format(100); // Returns: $100.00 # Test currency detection app('YassineAs\MultiCurrency\Services\GeolocationService')->detectCurrency();
๐จ Frontend Integration
<script> function currencySwitcher() { return { currency: 'USD', currencies: @json(Currency::getSupportedCurrencies()), async switchCurrency() { await fetch('/currency/switch', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }, body: JSON.stringify({ currency: this.currency }) }); location.reload(); } } } </script>
## ๐จ Troubleshooting
### Common Issues
**1. Exchange rates not updating:**
```bash
# Clear cache and refresh rates
php artisan cache:clear
php artisan currency:refresh-rates
2. Currency not detected:
- Check if
AUTO_DETECT_CURRENCY=true
in.env
- Verify IP detection is working (test with different IPs)
3. API rate limits exceeded:
- Use caching (increase
CURRENCY_CACHE_DURATION
) - Consider upgrading your API plan
- Switch to alternative provider
4. Blade directives not working:
- Clear view cache:
php artisan view:clear
- Ensure service provider is registered
๐ Changelog
v1.0.0
- Initial release
- Multi-currency support
- IP-based detection
- Exchange rate caching
- Blade directives
- AJAX currency switching
๐ค Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
๐ Credits
- Author: Yassine AS
- Exchange Rate APIs: ExchangeRate-API, CurrencyAPI
- IP Geolocation: ip-api.com