torann/currency
Laravel package for currency formatting, parsing, and conversion. Format and parse monetary values and convert between currencies using pluggable exchange rate providers, with caching and a simple Currency facade for everyday use.
Scoping "localized prices" as a story, not an epic. The package's real job is turning a stored amount into a correctly formatted string — right symbol, right decimal count, right separators — and optionally an indicative converted figure. A PM can pull "show prices in the customer's local format" out of a sprawling i18n programme and ship it as a bounded slice with testable acceptance criteria, while the harder localization work (translated copy, local payment methods, tax display) stays separate.
Build vs. buy on commodity money logic. Symbol maps, separator conventions, zero-decimal currencies (JPY), three-decimal currencies (KWD) and the long tail of formatting edge cases are commodity rules nobody differentiates on. The default PM posture should be to integrate, and spend engineering budget on pricing strategy, tax treatment and checkout rules instead. This package is the "buy" candidate in that comparison — cheaply evaluated, cheaply reversed.
Naming the indicative-vs-transactional boundary before engineering has to. Because conversion runs through configurable rate drivers, it fits display use cases ("approx. €42") and nothing else. It is not a payments or FX system with rate locks, spreads and settlement. The PM decision this supports is writing that line into the spec explicitly: display-layer conversion is in scope; charging a foreign customer at a guaranteed rate is a separate capability with a separate vendor and contract.
Owning the rate source and freshness policy. Pluggable drivers mean two customer-visible questions land squarely on product: whose rates (which provider, what terms and SLA) and how stale is acceptable (cache TTL, refresh cadence, fallback behaviour when the provider is down). A visibly stale converted price is a support ticket; in some markets it's a compliance concern. The package deliberately leaves that seam open — someone has to fill it.
Rounding and display-vs-charge as an explicit product rule. Decimals and separators are configurable, so a human must decide the rule per market — and specifically whether the displayed price is guaranteed to match the charged price. If they can diverge, state the tolerance up front rather than discovering it in a customer complaint.
Base-currency standardization, early and cheaply. A configurable default currency is an architectural decision with product consequences: every stored amount carries an implicit currency, and retrofitting that after data volume accumulates is expensive. Locking it now is one of the highest-leverage decisions this evaluation surfaces.
Cheap experiment enablement. If "do EUR/GBP-localized prices lift conversion in those markets?" is a roadmap hypothesis, this package makes the test small enough to actually run. Caveat to design in: instrument price display and price billing separately so the result isn't misread.
Deferring the commitment without blocking the roadmap. Nothing here forces a decision today. A PM can record the package as the assumed implementation for display-layer work, log the open questions (rate provider, maintenance posture, numeric representation), and revisit at checkout-localization time.
Consider it when:
Look elsewhere, or run a full evaluation first, when:
Diligence items before any revenue-path use: internal representation (float vs. minor units); where and how conversion rounds; licence terms and whether an internal fork is permitted; maintenance model and responsiveness; whether conversion makes a network call per request and how it caches; behaviour on provider failure or stale rates; whether fixed/historical rates can be injected for tests and replay; whether formatting is genuinely locale-aware or English-centric; and a CI matrix across supported Laravel and PHP versions.
One line for executives: It lets the product show prices correctly — and show approximately converted prices — in each market's own currency, using standard Laravel plumbing instead of a bespoke build. It is a display tool, not a payments or FX engine; charging customers in foreign currency remains a separate, larger decision.
For engineering leadership: A small, framework-native Laravel package providing currency formatting (configurable symbols, decimals, separators) and conversion via pluggable exchange-rate drivers, wired in through service provider, facade and config. It takes commodity work off the backlog, which is the point. Three things to scope deliberately rather than inherit:
Also worth surfacing: the build-vs-buy comparison. Formatting is small; conversion is a provider integration plus a cache plus a snapshot table — plausibly a few weeks of work that removes the dependency entirely. That comparison, not the release note, is the real decision.
Suggested handling: adopt for display-layer formatting and indicative conversion in a single low-traffic service first; wrap the calls; document the rate-freshness policy and the display-vs-charge rounding rule; then expand. Keep it off the checkout critical path until a proper evaluation clears it.
Caveat to state plainly: the available documentation describes what the package can do, not evidence of how well it does it — there is no meaningful adoption base or support-matrix evidence in what we have. That justifies a scoped pilot on a low-stakes display concern. It does not justify putting it on a revenue-critical path, nor treating multi-currency billing as solved because this dependency exists.
How can I help you explore Laravel packages today?