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 Magento Stock Laravel Package

justbetter/laravel-magento-stock

A Laravel package for integrating Magento stock data into your application. It provides convenient tools to retrieve and validate product inventory and availability, helping you display accurate stock status and support reliable checkout, ordering, and catalog decisions.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire up the client first. This package is a thin stock-lookup layer on top of justbetter/laravel-magento-client; it cannot talk to Magento on its own.

composer require justbetter/laravel-magento-stock:^2.4
php artisan vendor:publish --provider="JustBetter\MagentoStock\ServiceProvider"

Then configure the underlying Magento connection (base URL + integration token) in config/magento-client.php / .env, and the stock-specific options (source code, cache TTL, cache store) in config/magento-stock.php. Confirm connectivity before writing feature code:

php artisan tinker
>>> JustBetter\MagentoStock\Facades\MagentoStock::getStock('SKU-123');

Where to look first

  • config/magento-stock.php – source code (default vs a specific MSI source), cache store and TTL, placeholder behaviour for unknown SKUs.
  • The MagentoStock facade – the public surface you will actually call from controllers, models and jobs.
  • The published/migrated tables (if you enable the local storage driver) – this is where the package persists fetched quantities so you can query stock locally instead of hitting Magento on every page view.

Canonical first use case: a single SKU on a product detail page. Resolve the SKU from your Product model, call the facade, and render the salable quantity / in-stock boolean. Once that works end-to-end, you have validated credentials, source code and caching in one go, and everything else is scale.

Implementation Patterns

Model accessor over raw facade calls. Wrap lookups behind your own domain object so controllers never know about Magento:

class Product extends Model
{
    public function getStockAttribute(): StockData
    {
        return MagentoStock::getStock($this->sku);
    }
}

This is the seam that lets you swap in a local DB cache, a Redis store, or a fake in tests without touching views.

Batch for listings and search results. Never loop over a collection calling the facade per item — that is N synchronous HTTP round-trips and will dominate your page load. Collect the SKUs and request them in one call (the package supports multi-SKU retrieval), then hydrate a sku => stock map:

$skus = $products->pluck('sku')->all();
$stock = MagentoStock::getStockForSkus($skus); // hydrate once

Map into the collection via ->map() rather than letting each model lazy-load Magento.

Cache aggressively, invalidate deliberately. Stock is read-mostly but must not be so stale you oversell. Two-tier pattern that works well:

  1. Package-level cache (short TTL, e.g. 1–5 minutes) to absorb traffic spikes.
  2. Your own persisted snapshot table refreshed by a queued job on a schedule and after order placement — used for catalogue filtering and sorting (where stock > 0) where you cannot afford remote calls at all.

Queue the writes, not the reads. Anything that follows an order (reservation, decrement, re-check) belongs in a job with a retry/backoff policy, because Magento MSI calls are the part most likely to fail transiently. Reads can be synchronous with cache in front; mutations should not block the checkout response.

Gate the feature. Put stock lookups behind a config flag and a null-object implementation so local/staging environments without Magento credentials boot cleanly instead of throwing connection errors on every request.

Testing seam. Bind a fake implementation of the stock contract in your test suite and assert on your own accessors/mappers. Do not point tests at a real Magento instance — flaky and slow.

Gotchas and Tips

Salable quantity is not quantity. With MSI enabled, a SKU can have physical quantity in a source yet zero salable quantity due to reservations. Decide explicitly which number your UI shows; "in stock" driven by raw quantity will be wrong on any store with pending orders. Also confirm the configured source code actually exists in Magento — a mistyped source silently yields empty/zero results rather than an error.

SKU mismatches are the #1 support ticket. SKUs are case- and whitespace-sensitive between Laravel and Magento. Normalise on ingest and log the offending SKU when a lookup returns nothing, otherwise you get "all products out of stock" with no clue why.

Unknown SKUs are normal, not exceptional. Products deleted in Magento, or created in Laravel but not yet pushed, will miss. Configure the placeholder behaviour and make your code tolerate a null/zero result instead of a thrown exception on a product page.

Watch for retry/loop behaviour against the Magento API. Version 2.4.4 fixes a loop in the request path; if you are on 2.4.3 or earlier and see repeated or runaway calls to Magento (visible as duplicated entries in the client's log or a spike in request count per page load), upgrading to ^2.4.4 is the fix. It is a patch release with no API or config changes — a drop-in replacement, but re-run your test suite and watch request counts in staging for a day since the changed code is on the hot read path.

Cache TTL is a business decision. A long TTL reduces Magento load but increases the window in which you sell something you no longer have; a short TTL pushes you toward rate limits. Set it per environment (tight in production checkout paths, loose for catalogue browsing) and remember the cache key must include the source code if you query multiple sources.

Rate limits and latency. Magento's REST API is slow compared to a local DB — a 100 ms average is optimistic. Time-box calls in the request cycle, set client timeouts, and fall back to your last persisted snapshot on timeout rather than failing the page.

Extension points worth knowing: the published config (cache store/TTL, source code, placeholder value), the bound contracts behind the facade (swap for your own implementation or a decorator that adds logging/metrics), and the underlying Magento client (swap for a mocked transport in tests). When debugging, enable the Magento client's HTTP logging first — most "the package is broken" reports are auth token expiry or a 404 on the SKU, both visible in the raw response.

Version pinning. Stay on ^2.4 and read each patch's changelog: this package sits on the read path of product pages, so a subtle regression is immediately customer-visible.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle