Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Currency Laravel Package

sylius/currency

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sylius/currency
    

    Add the service to your Laravel container (e.g., in config/app.php or a service provider):

    $this->app->bind(CurrencyConverterInterface::class, function ($app) {
        return new CurrencyConverter();
    });
    
  2. Define Currencies: Register supported currencies in your config (e.g., config/currencies.php):

    'currencies' => [
        'USD' => ['code' => 'USD', 'name' => 'US Dollar', 'symbol' => '$'],
        'EUR' => ['code' => 'EUR', 'name' => 'Euro', 'symbol' => '€'],
    ],
    
  3. First Use Case: Convert a value from one currency to another:

    $converter = app(CurrencyConverterInterface::class);
    $amount = $converter->convert(100, 'USD', 'EUR'); // Returns ~82.61 (using default exchange rates)
    

Where to Look First

  • Documentation for API details.
  • src/CurrencyConverter.php for core logic.
  • src/Exception/ for error handling (e.g., UnsupportedCurrencyException).

Implementation Patterns

Core Workflows

  1. Currency Conversion:

    // Convert a fixed amount (e.g., for pricing)
    $priceInEur = $converter->convert(100, 'USD', 'EUR');
    
    // Convert with precision control (e.g., for financial calculations)
    $converter->convert(100, 'USD', 'EUR', 4); // Round to 4 decimal places
    
  2. Dynamic Exchange Rates: Extend CurrencyConverter to fetch real-time rates from an API (e.g., ExchangeRate-API):

    class ApiCurrencyConverter extends CurrencyConverter
    {
        public function getRate(string $from, string $to): float
        {
            $response = Http::get("https://api.exchangerate-api.com/v4/latest/{$from}");
            return $response['rates'][$to];
        }
    }
    
  3. Context-Aware Conversion: Attach conversion logic to domain objects (e.g., Order, Product):

    class Order
    {
        public function getTotalInCurrency(string $currency): float
        {
            return app(CurrencyConverterInterface::class)
                ->convert($this->total, $this->currency, $currency);
        }
    }
    
  4. Fallback Rates: Define fallback rates in config for unsupported pairs:

    'fallback_rates' => [
        'USD' => ['EUR' => 0.8261, 'GBP' => 0.7346],
    ],
    

Integration Tips

  • Laravel Cashier/Stripe: Use the package to normalize subscription prices across regions.
  • Multi-Tenant Apps: Store tenant-specific exchange rates in a database table and hydrate the converter dynamically.
  • API Responses: Standardize currency fields in JSON responses:
    return response()->json([
        'price' => [
            'amount' => $product->price,
            'currency' => $product->currency,
        ],
    ]);
    

Gotchas and Tips

Pitfalls

  1. Precision Loss: Floating-point arithmetic can cause rounding errors. Always specify precision:

    $converter->convert(100, 'USD', 'EUR', 6); // Avoids 0.0001 discrepancies
    
  2. Unsupported Currencies: The package throws UnsupportedCurrencyException if a currency isn’t registered. Validate input early:

    if (!$converter->supports('XYZ')) {
        throw new InvalidArgumentException('Unsupported currency: XYZ');
    }
    
  3. Circular Dependencies: Avoid recursive conversions (e.g., USD → EUR → USD). Cache rates or use a directed graph to detect cycles.

  4. Static Exchange Rates: The default implementation uses hardcoded rates. For production, always override getRate() to fetch live data.

Debugging

  • Rate Calculation: Override getRate() to log intermediate values:

    public function getRate(string $from, string $to): float
    {
        $rate = parent::getRate($from, $to);
        \Log::debug("Rate {$from}→{$to}: {$rate}");
        return $rate;
    }
    
  • Precision Issues: Use PHP’s bcmath or gmp extensions for high-precision calculations:

    $converter->convert(100, 'USD', 'EUR', 10, 'bcmath');
    

Extension Points

  1. Custom Rate Providers: Implement RateProviderInterface for external APIs or databases:

    class DatabaseRateProvider implements RateProviderInterface
    {
        public function getRate(string $from, string $to): float
        {
            return DB::table('exchange_rates')
                ->where('from', $from)
                ->where('to', $to)
                ->value('rate');
        }
    }
    
  2. Currency Formatting: Extend CurrencyConverter to add locale-aware formatting:

    class LocalizedCurrencyConverter extends CurrencyConverter
    {
        public function format(float $amount, string $currency, string $locale = 'en_US'): string
        {
            $formatter = NumberFormatter::create($locale, NumberFormatter::CURRENCY);
            return $formatter->formatCurrency($amount, $currency);
        }
    }
    
  3. Event-Driven Updates: Dispatch events when rates change (e.g., CurrencyRateUpdated):

    event(new CurrencyRateUpdated($from, $to, $newRate));
    

Config Quirks

  • Case Sensitivity: Currency codes (e.g., USD, eur) are case-sensitive by default. Normalize them in your config:
    'currencies' => [
        strtoupper('usd') => [...],
    ],
    
  • Default Currency: The package doesn’t enforce a default. Set one in your config to avoid null issues:
    'default_currency' => 'USD',
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky