mgcodeur/laravel-currency-converter
A Laravel package for converting currencies and fetching live exchange rates. It offers a simple API, supports multiple exchange rate providers, and integrates seamlessly with your Laravel app for pricing, payments, and multi-currency features.
Architecture fit
CurrencyRateProvider interface from day one so the vendor package is a swappable detail.brick/money or moneyphp/money for arithmetic if amounts are transactional; do not rely on the package's float handling for anything that lands on an invoice.Integration feasibility
composer require + php artisan vendor:publish + one config file. Realistically a half-day spike for a mid-level engineer, not a sprint item.Technical risk
bcmath/string arithmetic, and whether the rounding mode is configurable. Float drift shows up as cent-level mismatches in aggregates and is expensive to unwind.Key questions for the maintainer / spike
post-install/post-update Composer scripts, and what network calls happen in the service provider boot?Stack fit
Migration path
App\Contracts\CurrencyRateProvider with a single method returning a rate DTO (pair, rate, as_of timestamp, source).PackageCurrencyRateProvider wrapping this package. Any future swap — paid API, ECB feed, internal treasury service — is a one-class change plus a container binding.rate, rate_source, and rate_captured_at on every transaction row from the first release. This is cheap now and non-negotiable later; retrofitting it means backfilling history you cannot reconstruct.Compatibility
composer.json constraints against your PHP and Laravel versions before committing; a 2026 release may already have dropped older Laravel lines.Currency is a silent-wrong-answer bug.brick/money or moneyphp/money for arithmetic and formatting. Do not let one library do both jobs by accident.Sequencing
Maintenance
composer update side effects.Support
Scaling
currency_rates table; all request-path conversions read from the database. This converts a runtime third-party dependency into a cron dependency, which is a categorically smaller blast radius.Failure modes
| Failure | Symptom | Mitigation |
|---|---|---|
| Upstream endpoint unavailable | Exceptions or hard failures on conversion | Local rate table + last-known-good fallback |
| Silent stale rates | Prices subtly wrong, no alert fires | rate_captured_at persisted; staleness threshold with alerting |
| Upstream throttling by egress IP | Intermittent, hard-to-reproduce failures | Scheduled refresh from a single egress; retry with backoff |
| Unsupported currency pair | Exception in a user-facing path | Validate pair at the boundary; graceful degradation to base currency |
| Float rounding drift | Cent-level mismatches in aggregates and invoices | Integer minor units via a money library; configurable rounding |
| Network call in request path | Latency spikes, timeouts | Never call out synchronously in web requests; short timeouts if unavoidable |
| Upstream ToS change or shutdown | Rates freeze or package breaks | Fork trigger + provider interface makes the swap a one-class change |
| Unattributable rate in an audit | Finance/compliance finding | Persist rate, source, and timestamp on every applied conversion |
| Maintainer abandonment | No security patches | Version pinning, vendored fork readiness, SCA scanning |
Ramp-up
How can I help you explore Laravel packages today?