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

Exchanger Laravel Package

florianv/exchanger

PHP exchange-rate provider layer with 31 services behind one ExchangeRateService interface. Supports historical rates, PSR-16 caching, and chainable fallback across providers (commercial APIs, ECB, national banks, exchangerate.host) for fine-grained control.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Provider Abstraction: Fits seamlessly into Laravel’s service-oriented architecture by abstracting 31+ exchange rate providers behind a unified ExchangeRateService interface. Aligns with Laravel’s dependency injection and service container patterns.
  • PSR Compliance: Leverages PSR-16 (caching), PSR-18 (HTTP clients), and PSR-17 (request factories), ensuring compatibility with Laravel’s ecosystem (e.g., Symfony’s HTTP client, Laravel Cache).
  • Fallback Chain: The Chain service enables graceful degradation—critical for financial applications where provider failures must not disrupt core functionality.
  • Historical Data: Supports time-series queries, useful for audit trails, reporting, or compliance (e.g., FX rate validation over periods).

Integration Feasibility

  • Laravel-Specific Synergy:
    • Service Container: Register the Exchanger as a singleton binding (ExchangeRateService) with configurable providers (e.g., fastforex, european_central_bank).
    • Configuration: Use Laravel’s config/exchanger.php to define:
      'providers' => [
          'primary' => Exchanger\Service\FastForex::class,
          'fallback' => [
              Exchanger\Service\EuropeanCentralBank::class,
              Exchanger\Service\Chain::class, // For nested fallbacks
          ],
      ],
      'cache' => 'array', // PSR-16 cache (e.g., 'redis', 'file')
      'api_keys' => [
          'fastforex' => env('FASTFOREX_API_KEY'),
      ],
      
    • Facade: Create a ExchangeRate facade for fluent access (e.g., ExchangeRate::convert(100, 'EUR', 'USD')).
  • HTTP Client: Laravel’s Http client (PSR-18) is auto-discoverable via php-http/discovery, reducing boilerplate.
  • Caching: Integrate with Laravel’s cache drivers (Redis, database, etc.) via PSR-16 adapters (e.g., php-cache/simple-cache-bridge).

Technical Risk

  • Provider Dependency: Commercial providers (e.g., fastforex) may introduce:
    • Rate Limits: Requires middleware to handle throttling (e.g., Laravel’s throttle or custom retry logic).
    • Cost: Free tiers may have usage caps; monitor API calls in production.
    • Downtime: Fallback chain must be tested rigorously (e.g., simulate provider failures in staging).
  • PHP 8.2+ Requirement: Laravel 10+ (PHP 8.1+) may need minor adjustments for PHP 8.2 features (e.g., typed properties).
  • Caching Complexity: PSR-16 cache keys must be designed to avoid stale data (e.g., cache invalidation on rate updates).
  • Historical Data Gaps: Some providers (e.g., webservicex) lack historical support; validate coverage for use cases.

Key Questions

  1. Provider Strategy:
    • Should the primary provider be fastforex (paid) or a free alternative (e.g., european_central_bank)?
    • How will API keys be managed (env vars, Vault, Laravel’s config)?
  2. Fallback Logic:
    • What’s the acceptable latency for fallback chains? (e.g., 200ms vs. 1s).
    • Should failed providers be logged/alerted (e.g., Sentry)?
  3. Caching:
    • What’s the optimal TTL for rates (e.g., 5m for volatile currencies, 1h for stable ones)?
    • How will cache invalidation be triggered (e.g., cron job to refresh rates)?
  4. Error Handling:
    • Should ChainException be caught globally (e.g., in Laravel’s App\Exceptions\Handler)?
    • How will missing rates be handled (e.g., throw, return null, or use a default rate)?
  5. Testing:
    • How will provider failures be mocked in tests (e.g., Laravel’s Mockery or Vcr for HTTP recordings)?
    • Are there edge cases (e.g., invalid currency pairs, rate limits) to validate?

Integration Approach

Stack Fit

  • Laravel Ecosystem:
    • Service Container: Bind Exchanger as a singleton with provider configurations.
    • Facades: Expose a clean API (e.g., ExchangeRate::getRate('EUR/USD')).
    • Cache: Use Laravel’s cache drivers (Redis, database) via PSR-16 adapters.
    • HTTP: Leverage Laravel’s Http client or Guzzle (PSR-18 compliant).
    • Events: Emit events for rate updates (e.g., ExchangeRateUpdated) for observability.
  • Database:
    • Store historical rates in a exchange_rates table for compliance/audit:
      Schema::create('exchange_rates', function (Blueprint $table) {
          $table->id();
          $table->string('base_currency');
          $table->string('target_currency');
          $table->decimal('rate', 15, 6);
          $table->dateTime('effective_at');
          $table->string('provider')->nullable();
          $table->timestamps();
      });
      
  • Queue Jobs:
    • Offload rate fetching to background jobs (e.g., FetchExchangeRates) to avoid blocking requests.

Migration Path

  1. Phase 1: Proof of Concept (1–2 weeks)
    • Install florianv/exchanger and symfony/http-client (or Laravel’s Http).
    • Implement a basic ExchangeRateService binding in AppServiceProvider:
      $this->app->singleton(ExchangeRateService::class, function ($app) {
          $service = new Chain([
              new FastForex(null, null, ['api_key' => env('FASTFOREX_API_KEY')]),
              new EuropeanCentralBank(),
          ]);
          return new Exchanger($service, $app->make(SimpleCacheInterface::class));
      });
      
    • Test with a facade:
      ExchangeRate::getRate('EUR/USD')->getValue();
      
  2. Phase 2: Integration (2–3 weeks)
    • Replace hardcoded rates in the codebase with Exchanger calls.
    • Add caching (e.g., Redis) and configure TTLs per currency pair.
    • Implement fallback logging (e.g., Laravel Log or Sentry).
  3. Phase 3: Optimization (1–2 weeks)
    • Add queue jobs for bulk rate fetching (e.g., daily cron).
    • Implement database storage for historical rates.
    • Add monitoring (e.g., Grafana dashboard for rate freshness).

Compatibility

  • Laravel Versions:
    • Compatible with Laravel 10+ (PHP 8.2+). For Laravel 9, pin to PHP 8.1 and adjust dependencies.
  • Dependencies:
    • symfony/http-client (or Laravel’s Http) for PSR-18.
    • php-cache/simple-cache-bridge to adapt Laravel’s cache to PSR-16.
    • nyholm/psr7 (included via symfony/http-client).
  • Third-Party Packages:
    • Conflict risk: None identified. florianv/exchanger has no Laravel-specific dependencies.

Sequencing

  1. Prerequisites:
    • Upgrade to Laravel 10+ (PHP 8.2) if not already.
    • Set up a free fastforex API key or alternative provider.
  2. Core Integration:
    • Register Exchanger in the service container.
    • Implement a facade or repository pattern for rate access.
  3. Enhancements:
    • Add caching, fallback logging, and database storage.
    • Implement background jobs for rate updates.
  4. Testing:
    • Unit tests for ExchangeRateService (mock providers).
    • Integration tests for caching and fallback chains.
    • End-to-end tests for critical paths (e.g., checkout with FX conversion).

Operational Impact

Maintenance

  • Provider Updates:
    • Monitor florianv/exchanger for breaking changes (e.g., provider API deprecations).
    • Update dependencies via composer update and test fallbacks.
  • API Key Rotation:
    • Automate key renewal (e.g., Laravel Forge or Envoyer).
    • Store keys in Laravel’s .env or a secrets manager (e.g., AWS Secrets Manager).
  • Caching:
    • Implement a cron job to refresh cached rates (e.g., every 6 hours).
    • Monitor cache hit/miss ratios (e.g., via Laravel Debugbar).

Support

  • Troubleshooting:
    • Log provider failures with context (e.g., currency pair, timestamp).
    • Use Laravel’s App\Exceptions\Handler to catch ChainException and notify support.
  • Documentation:
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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai