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

Exchange Laravel Package

worksome/exchange

Currency exchange for Laravel: convert money between currencies through a clean, driver-based API. Swap exchange-rate providers, cache rates, and keep conversion logic testable and framework-friendly.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit worksome/exchange is a Laravel-oriented currency exchange package built around a driver abstraction (exchange-rate providers) and a Rates value object returned to the application. It slots in as an infrastructure dependency at the service layer: application code asks the package for a Rates instance and consumes base currency, rate map, and retrieval timestamp. This is a good fit for Laravel apps that need quoted FX rates without building provider adapters themselves; it is not an accounting/ledger library, so rounding, precision policy, and rate-source auditability remain our responsibility.

Integration feasibility Low-to-moderate. Installation is standard Composer + published config, and the driver model means we can select or swap providers via configuration. The main effort in v3.0.0 is mechanical but repo-wide: three deprecated accessors were removed and replaced by public properties on the Rates object. Any call site using method syntax will now fatal rather than warn, so the upgrade is gated on a complete call-site inventory.

Breaking changes in v3.0.0

Removed (v2.x) Replacement (v3.0.0) Risk
$rates->getBaseCurrency() $rates->baseCurrency Fatal error at runtime if missed
$rates->getRates() $rates->rates Fatal error at runtime if missed
$rates->getRetrievedAt() $rates->retrievedAt Fatal error at runtime if missed

Additional changes:

  • Frankfurter v2 API: the frankfurter driver now targets v2. Self-hosted Frankfurter deployments must expose v2 and update FRANKFURTER_BASE_URL from the /v1 to the /v2 endpoint — an environment/config change that will fail at runtime, not at install time.
  • New frankfurter_v2 driver: a parallel driver was introduced before the default driver was switched. This gives a transitional path but also means the codebase may temporarily carry two Frankfurter drivers — worth confirming which one we should standardize on.
  • Base currency cast to float: a type-affecting change. If we persist, cache, compare strictly, or serialize Rates payloads, the resulting JSON/type may differ from v2.x.
  • CI-only dependency bump (dependabot/fetch-metadata): no runtime impact.

Technical risk

  • High: uncached/untested call sites relying on removed getters — a silent gap in test coverage converts directly into a production fatal.
  • Medium: Frankfurter v2 response shape, currency coverage, and rate precision may differ from v1; the driver abstracts the mapping, but our cached or snapshotted values may not be comparable across the boundary.
  • Medium: self-hosted Frankfurter environments that we do not control (staging vs. production drift).
  • Low: the property-based DTO is more idiomatic and reduces future churn; this is a one-time migration cost.

Key questions

  1. Which drivers are actually active in each environment, and do we self-host Frankfurter anywhere?
  2. Are Rates objects cached, queued as serialized payloads, or persisted? If so, does the property/float change alter the serialized contract?
  3. Do we strict-compare or === rate values anywhere that a float cast could disturb?
  4. What are the supported PHP/Laravel version constraints for v3, and does that match our matrix?
  5. Does v2 of the Frankfurter API change currency coverage or precision in a way that affects downstream calculations?
  6. Do we standardize on frankfurter (v2) or frankfurter_v2, and is the latter intended as a temporary shim?

Integration Approach

Stack fit Standard Laravel package integration: Composer dependency, auto-discovered service provider, publishable config for driver and credentials, and an environment variable for the Frankfurter base URL. No new infrastructure is required unless we want a caching layer in front of the provider calls, which we should own.

Migration path

  1. Inventory all usages of the three deprecated getters across application, packages, and tests (grep plus static analysis — PHPStan/Larastan or a Rector rule gives a reliable, reviewable diff).
  2. Replace method calls with property access; keep the change mechanical and in its own PR so regressions are attributable.
  3. Audit any place Rates is serialized, cached, queued, or logged; confirm the property-based shape and float cast are acceptable, or add an explicit mapping/DTO at our boundary.
  4. Update FRANKFURTER_BASE_URL from /v1 to /v2 in every environment that points at a self-hosted instance, and verify the endpoint is reachable before deploying code.
  5. Bump to ^3.0, run the full suite, and do a rate-parity spot check against v2.x output for a handful of currency pairs.

Compatibility The getter removal is not shim-able from our side without wrapping the Rates object; if a staged rollout is required, introduce a thin internal adapter over Rates first (in v2.5.x) so that the v3 bump only touches the adapter. The Frankfurter base URL change is a deploy-order concern: code and configuration must move together, and a rollback must revert both.

Sequencing Pin 2.5.x as the known-good baseline → land the internal adapter / call-site migration while still on v2 → optionally trial the frankfurter_v2 driver in staging to de-risk the API change → coordinate the FRANKFURTER_BASE_URL cutover with the v3 deploy → validate rates and caching behavior in staging → release to production with a rollback plan that includes the config revert.

Operational Impact

Maintenance Low ongoing footprint, but this release is a forcing function: the maintainers are consolidating the public API surface, and the property-based Rates object is likely the stable contract going forward. The dependabot activity and small contributor base suggest active but lean maintenance — budget for periodic minor upgrades rather than assuming long-term API stability. The short-lived coexistence of frankfurter and frankfurter_v2 drivers should be treated as transitional; expect one to be deprecated.

Support Community-supported, no commercial SLA. Our exposure is an external FX provider dependency plus package-maintainer responsiveness. For anything rate-critical (invoicing, pricing, settlement), we should treat the package as a convenience adapter and retain our own fallback source and audit trail.

Scaling Rate retrieval is an outbound HTTP call per request unless we cache. At any meaningful traffic volume, we must cache Rates with a TTL that matches business tolerance for stale FX, and add a fallback driver or last-known-good cache for provider outages. The float cast on base currency is worth noting for high-precision or high-volume financial calculations — prefer decimal arithmetic downstream.

Failure modes

  • Fatal errors from any missed getter call site (no deprecation grace period in v3).
  • Runtime failures against self-hosted Frankfurter instances still on /v1, or where v2 is unreachable.
  • Silent value drift if v2 returns different precision or currency coverage than v1 — surfaces as wrong numbers, not exceptions.
  • Serialization/cache incompatibility if persisted Rates payloads were written under v2.x.
  • Upstream provider outage or rate limit; the package is an adapter, not a resilient client, so retry/circuit-breaking is ours.
  • Type-strictness breakage in tests or comparisons due to the base currency float cast.

Ramp-up Low for a developer familiar with Laravel: one package, one config file, one value object. The real ramp-up cost is organizational — ensuring every team that consumes exchange rates knows the getters are gone and that the Frankfurter base URL is an environment-level dependency requiring coordinated change. A short internal note plus a static-analysis rule blocking the deprecated getters is sufficient to prevent recurrence.

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.
ably/pubsub-server
mstfkhazaal/defender
mfonte/base62x
karnoweb/metapilot
tobya/bcsapiwrapper
swalker2/cpanel
vish4395/laravel-translation-manager
morningtrain/economic
teksite/systeminfo-laravel
atomcms/voting
run6/weather
siokas/laravelembeddirectives
adamlien/pkuuids
gilsonsouza/lara-doc-generator
manelgavalda/enrollment_mobile
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics