Weave 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

Laravel Swap Laravel Package

florianv/laravel-swap

Laravel Swap lets you convert currencies and fetch exchange rates in Laravel apps. It wraps the Swap PHP library, supporting multiple rate providers, caching, and simple configuration for reliable currency conversion.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. florianv/laravel-swap remains a thin Laravel integration layer over the mature florianv/swap currency-exchange library. It contributes three things: an auto-discovered service provider (container bindings), a facade (Swap::), and a publishable config file. That is a good architectural fit for Laravel applications that need point-in-time currency conversion — pricing display, invoicing, reporting, multi-currency checkout — without building their own provider abstraction. It is explicitly not an FX treasury, rate-ledger, or historical time-series store; those concerns remain application-owned. 2.5.0 does not change this positioning, but it does tighten the framework floor (Laravel 11+) and harden configuration validation, which reinforces the "convenience binding, not platform dependency" framing. Assess it as a convenience binding with a now-narrower supported platform window.

Integration feasibility. High for Laravel 11/12/13 estates; blocked for anyone still on Laravel 10 or Lumen. One composer require, zero manual provider registration (Laravel auto-discovery), php artisan vendor:publish for config, and provider credentials via .env. Time-to-first-conversion is measured in minutes. 2.5.0 materially improves the failure surface here: non-name values for swap.cache, swap.http_client, and swap.request_factory now throw a clear InvalidArgumentException instead of failing obscurely, and the provider config option names are corrected (api_key rather than access_key for the APILayer services). The real integration work remains policy, not plumbing: rounding rules, base-currency convention, and cache TTLs all live in your code, not the package.

Technical risk. Moderate, with the balance shifting:

  • Platform floor (new, highest-impact). Laravel 10 support is dropped and Lumen is no longer tested. Any service on Laravel 10 must either defer this upgrade or couple the dependency bump to a framework upgrade. Treat this as a gating question, not a routine patch.
  • Config key rename (new). Applications with a previously published config/swap.php will carry the stale access_key names for APILayer-backed providers. Upgrades will not fix existing published config — re-publish or patch it deliberately, and verify auth succeeds per provider post-upgrade.
  • Removed php-cache fallback (new). The unused fallback is gone and cache values must now be names, not instances. Anyone who passed a cache object or relied on implicit binding gets a hard failure at boot — which is the right trade (explicit > silent) but is a real break for existing code.
  • Provider dependency. Multi-provider fallback is the package's core value, but every provider brings its own API key, quota, rate-limit behavior, and deprecation history. 2.5.0 adds UniRateAPI and National Bank of Denmark and inherits Exchanger 2.11 provider fixes, which is net-positive, but provider churn remains the dominant upstream risk.
  • Rate quality and staleness. The package returns whatever the provider returns; accuracy, latency, and settlement-grade guarantees are contractual with the provider, not the package. Note the documented caveats: exchange_rates_api free plan is EUR-based, and coin_layer transmits the key over plain HTTP unless paid is true — the latter is a security-review item if we ever enable it.
  • Bus-factor. MIT-licensed, single-primary-maintainer project. Unchanged in substance, but 2.5.0 is a genuinely strong hygiene release (hardened CI, Psalm 7 with no baseline, Shepherd type coverage, CONTRIBUTING.md including an AI-assisted contributions policy, docs-sync test against Exchanger). That raises confidence in the maintainer's process without changing the structural single-maintainer risk. Still requires an internal owner and version pinning.
  • Versioning. The earlier concern about a forward-dated release is resolved — 2.5.0 is a coherent, well-scoped minor with an inspectable changelog. Pin the exact version anyway; the Laravel-version drop shows this package will follow framework EOL cadence.
  • Rounding is yours. Unchanged. No monetary policy is enforced — a rounding bug here becomes a financial-correctness bug downstream.

Key questions for the team.

  • Which of our services are on Laravel 10 or Lumen, and what is their upgrade path/timeline? This gates adoption of 2.5.0.
  • Which providers do we already hold contracts/keys for, and what are their rate limits and SLAs? Are any APILayer-backed, and is our published config using the corrected api_key names?
  • Do we pass cache/HTTP-client values by name or by instance? If by instance, 2.5.0 is a breaking change for us.
  • Is enabling coin_layer ever in scope? If so, does the paid => true requirement satisfy security review?
  • Do we need historical/lookback rates, or only "current" conversion? (Determines whether we need our own rate-persistence layer.)
  • What is our rounding and presentation policy, and where will it be enforced?
  • Must rates be persisted for audit/reconciliation, and for how long?
  • Single base currency or multi-tenant per-currency configuration?
  • Does a single-maintainer dependency meet our supply-chain and support bar, or do we need an internal fork/wrapper? (2.5.0's tooling investment makes "wrap, don't fork" the more defensible answer.)

Integration Approach

Stack fit. Assumes a conventional Laravel 11/12/13 application (service provider + facade idiom) on a supported PHP version. It is framework-idiomatic and payment-processor-agnostic — it composes cleanly with any checkout, billing, or catalog system. If the codebase is not Laravel, or is still on Laravel 10/Lumen, this package adds no value over using florianv/swap directly — and on Laravel 10 the new version won't install at all.

Migration path. Do not call the facade directly from domain code. Introduce a narrow internal interface (e.g. CurrencyConverter) with a SwapCurrencyConverter implementation bound in a service provider. This:

  • keeps the vendor surface isolated to one adapter,
  • makes the eventual provider or library swap a one-file change,
  • gives a single choke point for rounding, caching, and telemetry,
  • and — relevant now — absorbs config-shape changes (cache names, key renames) without touching domain code.

Legacy hardcoded-rate call sites can then be migrated incrementally behind that interface rather than in a big-bang rewrite.

Compatibility checks before committing.

  • Laravel 11 / 12 / 13 only. Map every consuming service against this floor; Laravel 10 services need a framework upgrade first or must stay pinned to 2.4.x (and accept that they are now on an unsupported line).
  • PHP version constraints vs. our runtime matrix.
  • florianv/swap ^4.6 / Exchanger 2.11 — confirm this resolves against our existing lockfile and doesn't force transitive bumps (Guzzle/HTTP client, psr/simple-cache).
  • Published config drift. Diff our config/swap.php against the 2.5.0 stub; specifically reconcile access_key → api_key for APILayer providers and confirm no removed keys are still referenced.
  • Cache/HTTP-client/request-factory values are names. Verify our config passes store names, not instances, or we will hit the new InvalidArgumentException at boot.
  • php-cache fallback removal — confirm nothing depended on the implicit binding.
  • Facade alias collisions; config key namespacing.

Sequencing.

  1. Framework floor triage. Confirm which services can take 2.5.0 today and which are pinned to Laravel 10. Decide explicitly whether 2.4.x remains an allowed transient state (recommend: no — set an expiry date).
  2. Upgrade spike (non-prod). Bump the constraint, boot, diff-publish config, fix provider key names, validate returned rates against an independent reference on a sample of pairs with two providers plus fallback.
  3. Abstraction + policy. Land the CurrencyConverter interface, rounding rules, and base-currency convention before any business feature uses it (do this concurrently if it isn't already in place — it is the reason this upgrade is low-risk).
  4. Caching + quota design. Set TTLs per pair, choose cache backend by name, estimate call volume against provider quotas.
  5. Audit trail (if required). Persist rate snapshots with timestamp, provider, and pair for reconciliation.
  6. Wire into business flows — pricing display first (low blast radius), then checkout/invoicing once confidence is established.
  7. Observability and failover drills. Instrument cache hit rate, provider error rate, and fallback frequency; rehearse provider-outage behavior.
  8. Production rollout behind a feature flag with a kill switch to static rates.

Operational Impact

Maintenance. Small dependency surface and low churn expected from the Laravel wrapper itself. 2.5.0 raises the baseline hygiene bar considerably — php-cs-fixer, hardened CI, Psalm 7 without a baseline, Shepherd type coverage, and a test that keeps provider docs in sync with Exchanger — which lowers our review cost per upgrade. But the maintenance burden still sits with (a) the upstream swap library, (b) provider API changes, and (c) our own config and cache tuning. The Laravel-version drop is a signal: this package tracks framework EOL, so our framework upgrade cadence now dictates our ability to take security and provider fixes. Pin exact versions, subscribe to advisory feeds, schedule a quarterly dependency review, and add "framework floor moved" to the standing agenda. Budget a named internal owner.

Support. No commercial support tier; community/MIT only. Support model must be internal: a runbook covering provider outage, key rotation, rate anomaly response, and fallback verification. Two new runbook entries from 2.5.0: (i) config validation failures at boot (InvalidArgumentException on cache/HTTP-client/request-factory) and (ii) provider auth failures traced to stale access_key config post-upgrade. On-call should know that "wrong price displayed" is a first-class incident class, not a cosmetic bug.

Scaling. The package is stateless from our perspective — scaling is almost entirely a caching and quota problem. Rate calls are external network I/O; without aggressive caching, throughput is bounded by provider quotas, not by our infrastructure. Design for cache-first reads, per-pair cache keys, and a pre-warm strategy for high-traffic pairs. Redis sizing and eviction policy matter more than application replicas. 2.5.0's requirement that cache be named rather than injected is mildly helpful here: it makes the cache topology explicit and reviewable rather than an incidental object graph.

Failure modes to design for.

  • Framework floor mismatch (new): a dependency resolver or CI image on Laravel 10 fails to install 2.5.0 mid-build. Pin per-service and treat the lockfile as the record of which line each service is on.
  • Config drift / stale key names (new): an upgraded package with an un-republished config silently fails provider auth. Detect with a post-deploy smoke conversion per configured provider.
  • Boot-time config validation (new): a cache/HTTP-client value passed as an instance rather than a name now hard-fails the application at boot. Good failure mode, but it means a config error becomes an outage — enforce via a config test, not just production discovery.
  • Provider outage or rate-limit (429): fallback chain engages; if all providers fail, behavior must degrade to last-known-good cache and then to an explicit, visible error — never to a silently wrong rate.
  • Silent staleness: cache serves stale rates beyond business tolerance. Requires TTL enforcement and staleness alerts.
  • Rate anomaly: provider returns a nonsensical value (fat-finger or bad feed). Needs plausibility bounds and a circuit breaker. Note the documented exchange_rates_api EUR-base behavior when writing those bounds.
  • Key rotation / expired credentials: surfaces as a hard failure; alert on auth errors distinctly from quota errors.
  • Unsupported currency pair: should be an explicit, typed failure, not a zero or a null.
  • Rounding regressions: caught only by tests — mandate unit tests on conversion and rounding at the adapter boundary.

Ramp-up. A Laravel developer can be productive in under an hour. A responsible integration — abstraction, caching, rounding tests, observability, audit persistence, and failover drills — is roughly one to two sprints for a small team. The 2.5.0 upgrade itself is a small, well-documented piece of work (config diff plus a boot check); the cost sits in the framework-floor triage for Laravel 10 services, and the learning curve remains in the FX domain policy the package deliberately does not own.

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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox