- How do I install florianv/exchanger in a Laravel application?
- Run composer require florianv/exchanger symfony/http-client nyholm/psr7; the library requires PHP 8.2 or newer. No hard HTTP client is bundled, so php-http/discovery (Psr18ClientDiscovery since 2.9.0) locates an installed PSR-18 client, and Laravel already ships Guzzle by default. Exchanger publishes no service provider, so you write a small provider (roughly 30 to 60 lines) that binds a configured Chain instance and reads provider credentials from config/services.php and .env.
- Is florianv/exchanger a Laravel package?
- No. Exchanger is a framework-agnostic PHP provider layer sitting at the bottom of the florianv stack (laravel-swap, symfony-swap, swap, exchanger) with no facade, config file or auto-discovery. Choosing it directly means you own the DI bindings, config surface, cache policy and chain composition. If you just need to convert an amount at today's rate, laravel-swap is the cheaper decision and pulls Exchanger in transitively.
- What PHP and Laravel versions does florianv/exchanger support?
- Exchanger requires PHP 8.2 or newer since version 2.9.0, and because it is framework-agnostic it runs in any modern Laravel release. Versioning discipline is decent but not semver-perfect: 2.9.0 raised the PHP floor and swapped the HTTP discovery class in a minor release, both of which can break a dependent app. Pin to a caret range and treat every minor upgrade as a change that needs a full test-suite run.
- How do I set up chain fallback between exchange rate providers in Exchanger?
- Exchanger ships a Chain service: you compose an ordered list of ExchangeRateService implementations and, when one errors, the next in the chain is tried. Build that chain in your own Laravel service provider, ordering providers by reliability and cost (for example a commercial API first, ECB or a national bank as backup). Caching results on top of the chain keeps you well inside free-tier rate limits and reduces exposure to any single provider outage.
- How do I use Laravel's cache with Exchanger's PSR-16 requirement?
- Laravel's cache repository implements PSR-16 only partially, so it cannot be passed to Exchanger directly. You have three options: symfony/cache adapters pointed at Redis or the filesystem, which duplicates your cache infrastructure; php-cache/simple-cache-bridge, which goes the wrong direction (PSR-6 to PSR-16); or a small adapter class implementing Psr\SimpleCache\CacheInterface over Illuminate\Contracts\Cache\Repository. The adapter is the right call because TTL, key prefixing and eviction stay under config/cache.php and your existing Redis and Horizon observability keeps working.
- Can I get historical exchange rates with florianv/exchanger?
- Yes, historical rates are a built-in feature: you build the request with ExchangeRateQueryBuilder and pass the date you want. Support varies by provider, since not all of the 30+ services expose history and free tiers often limit the range, so keep a chain rather than relying on a single source. Chain fallback and PSR-16 caching apply to historical lookups the same way they do for current rates.
- How do I fake exchange rates when testing Laravel code that uses Exchanger?
- Because the abstraction surface is tiny, you fake it rather than mock HTTP. Bind a stub ExchangeRateService or your own FxRateProvider wrapper in the container that returns fixed ExchangeRate value objects exposing getValue(), getDate(), getProviderName() and getCurrencyPair(). Nothing is hard-coupled to Guzzle or a specific cache backend, so tests run without network access and without a live provider key.
- How should I handle rounding and precision when converting currency with Exchanger?
- Exchanger returns a rate and nothing more: it does not convert, round or enforce precision, and getValue() returns a float by design. That is fine for display prices and catalog estimates, but it is not ledger-grade accounting. Do the multiplication and rounding at your own boundary with BCMath or brick/money and never let a float reach a persisted monetary column.
- What is the difference between exchanger, swap and laravel-swap?
- Exchanger is the provider layer with the 30+ service implementations; swap builds conversion and currency logic on top of it, and laravel-swap wires swap into Laravel with a facade, config and container bindings. Reach for Exchanger directly only if you need non-default chain ordering, per-currency-pair cache keys or TTLs, your own PSR-18 middleware for rate limiting, signing or tracing, or a shared FX surface other teams consume. Otherwise laravel-swap gives you the same providers with far less code you own.
- Is florianv/exchanger maintained and safe to use in production?
- It has been maintained since 2016 under the MIT license with a deliberately small security surface: outbound HTTP only, no PII handling, no deserialization, and API keys as the only secret to protect. The risks are operational rather than code quality: a single primary maintainer with a modest adoption footprint, plus structural provider churn such as 2.0.0 dropping Yahoo and Google and 2.9.0 patching National Bank of Romania endpoints that may stop at any time. Pin the version, keep a fallback chain, and hide the library behind your own FxRateProvider interface so replacing it costs days rather than weeks.