xint0/banxico-php
PHP client for Banxico's SIE REST API to fetch USD-MXN exchange rates (SF43718 determination and SF60653 liquidation series), with methods for latest, specific-date, or date-range queries and any SIE series by name.
Architecture fit. xint0/banxico-php is a deliberately narrow, framework-agnostic client: a single SieClient class that wraps the Banxico SIE REST API, typed helpers for the two canonical MXN/USD series (SF43718 determination/Fix and SF60653 liquidation), and a generic fetchSeries($seriesCode, $from, $to) escape hatch for any other SIE series. It depends only on PSR-18 (psr/http-client) and PSR-17 (psr/http-factory) contracts, discovered at runtime via php-http/discovery. That is exactly the shape a TPM wants in a utility dependency: no container bindings, no service provider, no global state, no opinion about how your application is layered. It slots cleanly behind a repository or adapter in a Laravel service layer and stays out of your domain model.
Integration feasibility. Composer-only install (composer require xint0/banxico-php), PHP 8.2+ floor, and PSR-18 discovery means a standard Laravel app (which ships Guzzle as guzzlehttp/guzzle, a valid PSR-18 implementation) will resolve an HTTP client without additional wiring. The only external prerequisite is a Banxico SIE access token, obtained from the Banxico developer portal — a procurement/registration task, not an engineering one, but it is the real gating item. Return-value semantics are pragmatic: a single string for a single date, a date => rate array for a range, and a series-code-keyed array for multi-series calls, with ClienteBanxicoException thrown on client errors. That is a small, learnable contract.
Technical risk. The dominant risk is not technical, it is vendor/community risk. The package has 5 GitHub stars, 0 dependents, a single maintainer (Rogelio Jacinto), Spanish-only documentation, and an MIT license. There is no evidence of downstream production usage to learn from, so the "does this work in the wild?" signal is essentially absent. Secondary risks: (1) the library performs no caching, retry, backoff, or rate-limit handling — those are entirely the integrator's responsibility against a public central-bank API; (2) token lifecycle (rotation, revocation, quota) is unmanaged; (3) date handling and timezone semantics for Banxico publication windows (the Fix rate publishes on business days, liquidation may differ) are left to the caller; (4) the release timeline (3.0.0 targeting PHP 8.5, release dated 2026-09-22) suggests a maintainer keeping pace with PHP, which is reassuring for maintenance intent but also signals a small project tracking a fast-moving language target.
Key questions.
Stack fit. Laravel 10/11/12 (all PHP 8.2+) and the package's PHP 8.2+ floor align. Laravel's default Guzzle client satisfies psr/http-client-implementation, and php-http/discovery will find it, so no explicit client injection is strictly required — but a TPM should insist on explicitly injecting a PSR-18 client (via a small service provider binding) rather than relying on discovery, because discovery is implicit magic that fails silently in unusual runtime setups and is hard to diagnose in production. Treat SieClient as an infrastructure detail: wrap it in a BanxicoExchangeRateRepository interface so domain code never imports Xint0\BanxicoPHP\SieClient. This preserves the option to swap implementations (in-house client, different package, cached HTTP layer) without touching call sites.
Migration path. Greenfield is trivial. Brownfield: if the app currently calls Banxico directly via Http::get(...) or a custom Guzzle wrapper, introduce the package behind the same repository interface so the cutover is a one-line binding change with identical return types. Do not migrate call sites one at a time; migrate the boundary.
Compatibility. Watch three areas: (1) PSR-18/PSR-17 discovery conflicts if multiple HTTP clients are installed — pin the implementation; (2) PHP minor upgrades, since the package targets 8.2 through 8.5 across its release line, so run it through CI on the same PHP matrix you deploy; (3) response shapes are string-typed currency values (e.g. '19.7930'), so downstream consumers must handle decimal-as-string precisely (use bcmath/brick/math, not floats) — a small but easy-to-miss correctness risk.
Sequencing.
composer.lock review step.BanxicoClient service provider entry.SieClient in a repository interface with typed DTOs for rate + date + series code.Maintenance. The surface area is tiny (one client class, a handful of methods, thin exception type), so maintenance cost is low provided we own the version pin. The churn history is mostly tooling (PHPUnit, PHPStan, phive) and metadata, with one real breaking change at 1.0.0 (Cliente → SieClient) and a PHP-floor bump at 2.0.0. That is a healthy cadence for a utility. The MIT license is the operational safety valve: if the maintainer stops releasing, we can vendor/fork the class with negligible effort.
Support. This is the weakest dimension. One maintainer, Spanish-language docs, 5 stars, 0 dependents — there is no community to escalate to, no Stack Overflow corpus, and no third-party tutorials. Internal support must therefore be first-party: an owner on our side who understands the Banxico SIE API contract (not just this wrapper), a runbook for token issues, and a document explaining the two rate types to non-finance engineers. Budget a small amount of time for a Spanish-reading engineer to onboard the rest of the team.
Scaling. The package itself does not scale concerns — it is stateless and synchronous. Scaling is about the upstream API: Banxico publishes on business-day cadence, applies its own quota/policy, and will not tolerate per-request hammering from a high-traffic app. Mandatory companions: a cache layer (Redis or database) keyed by series + date, a scheduled warm-up job shortly after Banxico's publication window, and a queue for any batch backfill (e.g., historical ranges). Because the library returns arrays for ranges, backfills are straightforward but must be chunked to respect upstream limits.
Failure modes. Expect and design for: token expired/revoked (401 → alert + rotate); Banxico API downtime or timeout (→ serve last known cached rate, do not block the request path); HTTP client discovery failure (→ explicit binding avoids this); malformed/empty series response (→ validate non-empty before persisting); date-boundary errors from timezone assumptions (→ standardize on America/Mexico_City for "today's" rate decisions, store as DATE); decimal-as-string mishandling downstream (→ strict typing at the DTO boundary); and silent stale data if caching TTLs outlive the publication cadence (→ freshness metadata on every cached entry). None of these are exotic, but each needs an explicit decision because the package correctly does none of them for you.
Ramp-up. Low for any PHP developer: install, instantiate with a token, call one of three or four methods. The real ramp-up is domain ramp-up — understanding what the Fix rate is, why liquidation vs. determination matters, and which business process consumes which. That knowledge lives outside the package and should be captured in the repository adapter's docblocks rather than left implicit. Net recommendation: adopt, but only behind a repository boundary, with an explicit PSR-18 binding, a cache, and a named internal owner — treat the package as a replaceable ~150-line dependency, not a strategic one.
How can I help you explore Laravel packages today?