---
title: "The Shops facade — Shops for Laravel | Roundly"
description: "Shops::cart(), order() and inventory() handles plus coupons(), current() and addresses() — the whole shop API in one facade, every method listed."
url: https://roundly-consulting.com/open-source/docs/shops-for-laravel/facade
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Shops for Laravel](https://roundly-consulting.com/open-source/docs/shops-for-laravel.md)

# The Shops facade

RoundlyConsulting\\Shops\\Facades\\Shops is the whole API in one place. Each area is a scoped handle — one cart, one order, one variant’s stock — or a sub-accessor. The package also registers it as the global Shops alias:

```php
use RoundlyConsulting\Money\Money;
use RoundlyConsulting\Shops\Facades\Shops;
use RoundlyConsulting\Shops\Inventory\Enums\StockReason;
use RoundlyConsulting\Shops\Orders\DataTransferObjects\PlaceOrderData;
use RoundlyConsulting\Shops\Orders\Enums\Status;

// Cart — lines of another cart are refused (ForeignItemException)
Shops::cart($cart)->add($variant, 2);            // CartItem; the same variant merges into its line
Shops::cart($cart)->update($item, 3);            // ?CartItem — 0 removes the line
Shops::cart($cart)->remove($item);
Shops::cart($cart)->clear();                     // the "empty cart" button
Shops::cart($cart)->price('SUMMER');             // Price DTO, optionally with a coupon code
Shops::cart($cart)->subtotal();                  // Money
$order = Shops::cart($cart)->checkout(new PlaceOrderData(couponCode: 'SUMMER'));

// Order
Shops::order($order)->transition(Status::InProgress);
Shops::order($order)->charge();                  // PaymentResult — Paid on success; New/InProgress only
Shops::order($order)->fulfil();                  // reservation becomes a sale
Shops::order($order)->cancel();                  // reservation released, store credit returned
Shops::order($order)->refund();                  // an unfulfilled order's reservation released too
Shops::order($order)->quoteShipping($address);   // Money, through the bound ShippingMethod

// Inventory — every change is a StockAdjustment ledger row
Shops::inventory($variant)->receive(10, ref: $purchaseOrder, note: 'PO-17');
Shops::inventory($variant)->returned(1, $order); // the variant must be on that order
Shops::inventory($variant)->adjust(-2, StockReason::Manual, note: 'Damaged');
Shops::inventory($variant)->available();         // stock - reserved

// Coupons, tenancy, addresses
Shops::coupons()->preview('WELCOME10', Money::ofMinor(1000, 'EUR')); // DiscountResult, no redemption
Shops::current()->set($shop);                    // CurrentShop: set / get / id / forget / run
Shops::addresses()->defaults($customer);         // OrderAddresses (billing, shipping)
```

## Entry points

| Call | Returns | What it is |
| --- | --- | --- |
| `Shops::cart(Cart $cart)` | `Handles\CartHandle` | One cart: lines, price, checkout. |
| `Shops::order(Order $order)` | `Handles\OrderHandle` | One order: transitions, charge, shipping quote. |
| `Shops::inventory(ProductVariant $variant)` | `Handles\InventoryHandle` | One variant’s stock. |
| `Shops::coupons()` | `Handles\CouponsHandle` | Coupon previews, no redemption. |
| `Shops::current()` | `Shops\CurrentShop` | The bound tenant (see Shops & tenancy). |
| `Shops::addresses()` | `Orders\AddressBook` | A customer’s default order addresses. |
| `Shops::fake()` | `Testing\ShopsFake` | The recording manager (see Testing). |

## Handle methods

| Method | Returns | Does |
| --- | --- | --- |
| `cart($cart)->add(ProductVariant $variant, int $quantity = 1)` | `CartItem` | Snapshots the variant; the same variant merges into its line. |
| `cart($cart)->update(CartItem $item, int $quantity)` | `?CartItem` | Sets a line’s quantity; 0 removes it and returns null. |
| `cart($cart)->remove(CartItem $item)` | `void` | Removes a line. |
| `cart($cart)->clear()` | `Cart` | Removes every line; the cart stays. |
| `cart($cart)->price(?string $couponCode = null)` | `Price` | Prices the cart, with the stored or given coupon code. Never redeems. |
| `cart($cart)->subtotal()` | `Money` | Goods subtotal before any discount. |
| `cart($cart)->checkout(PlaceOrderData $data = new PlaceOrderData)` | `Order` | Places the order in one transaction, holding the cart’s row lock — a double submit places one order. |
| `order($order)->transition(Status $to)` | `Order` | Any allowed status move. |
| `order($order)->cancel() / refund() / fulfil()` | `Order` | Shortcuts for Canceled (store credit returned), Refunded and Fulfilled. |
| `order($order)->charge()` | `PaymentResult` | New or InProgress orders only, decided under the order’s row lock. Store credit first when enabled, the rest through the gateway; Paid on success. |
| `order($order)->quoteShipping(Address $to)` | `Money` | Quote through the bound ShippingMethod. |
| `inventory($variant)->receive(int $quantity, ?Model $ref = null, ?string $note = null)` | `StockAdjustment` | A delivery: on-hand stock goes up. |
| `inventory($variant)->returned(int $quantity, ?Model $ref = null, ?string $note = null)` | `StockAdjustment` | A customer return; with an Order ref the variant must be on it. |
| `inventory($variant)->adjust(int $delta, StockReason $reason = StockReason::Manual, ?Model $ref = null, ?string $note = null)` | `StockAdjustment` | Any signed adjustment; a manual correction by default. |
| `inventory($variant)->available()` | `int` | Stock minus reserved. |
| `inventory($variant)->inStock(int $quantity = 1)` | `bool` | Whether the quantity can be sold now. |
| `coupons()->preview(string $code, Money $goods)` | `DiscountResult` | What a code would take off, via the bound DiscountResolver. |
| `addresses()->defaults(Addressable $customer, ?bool $billingSameAsShipping = null)` | `OrderAddresses` | Primary billing and shipping addresses as order snapshots. |
| `addresses()->map(?AddressModel $address)` | `?Address` | One saved address as an order Address. |

- A line of another cart is refused with ForeignItemException before anything is written — scope carts to the current customer and let the handle guard the line ids that arrive in a request.
- returned() with an Order reference refuses a variant that was never on that order, also with ForeignItemException.
- Illegal status moves throw IllegalStatusTransitionException and change nothing; an oversell at checkout throws InsufficientStockException, and an empty cart or a line whose variant was removed throws CheckoutRefusedException — both write nothing.
- Shops::current() methods (set, get, id, forget, run) are listed under Shops & tenancy.

## Model shorthand

The model convenience methods go through the same manager, so they behave identically and Shops::fake() sees them:

```php
use RoundlyConsulting\Shops\Orders\Enums\Status;
use RoundlyConsulting\Shops\Shops\Shop;

$cart->add($variant, 2);            // Shops::cart($cart)->add($variant, 2)
$order->transitionTo(Status::Paid); // Shops::order($order)->transition(Status::Paid)
$order->markInProgress();           // → InProgress
$order->markPaid();                 // → Paid
$order->markFulfilled();            // → Fulfilled
$order->cancel();                   // Shops::order($order)->cancel()
$order->refund();                   // Shops::order($order)->refund()
Shop::current();                    // Shops::current()->get(), typed to the package's Shop model
```

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/shops-for-laravel.md)
