PHPackages                             enea/laravel-cashier - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. enea/laravel-cashier

AbandonedArchivedLibrary

enea/laravel-cashier
====================

Simple package for product management

V4.0.0(3y ago)5194MITPHPPHP ^8.1

Since May 31Pushed 2y ago1 watchersCompare

[ Source](https://github.com/vaened/laravel-cashier)[ Packagist](https://packagist.org/packages/enea/laravel-cashier)[ RSS](/packages/enea-laravel-cashier/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (3)Dependencies (3)Versions (30)Used By (0)

Deprecated - Laravel Cashier Package
====================================

[](#deprecated---laravel-cashier-package)

[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)

**This repository is marked as deprecated and has been replaced by a better and more comprehensive version.**

**Reason**: We have released [Swift Cart](https://github.com/vaened/swift-cart), which offers enhanced functionalities, a more user-friendly experience, and improved performance. As a result, this repository will no longer receive updates.

**Deprecation Date**: August 4st, 2023.

This package provides a functionality to manage the sale of products and abstracts all the calculations you need for a sale.

```
// create a shopping cart
$document = Invoice::create()->using([Taxes::IVA]);
$shoppingCart = ShoppingManager::initialize($client, $document);

// add a global discount
$discount = Discount::percentage(15)->setCode('PROMOTIONAL');
$shoppingCart->addDiscount($discount);

// add products
$keyboard = $shoppingCart->push(Product::find(1), 5);
$keyboard->addDiscount(Discount::percentage(8)->setCode('ONLY-TODAY'));

$backpack = $shoppingCart->push(Product::find(2));
$backpack->setQuantity(10);

// get totals
$shoppingCart->getSubtotal();
$shoppingCart->getTotalDiscounts();
$shoppingCart->getTotalTaxes();
$shoppingCart->getTotal();
```

Installation
------------

[](#installation)

Laravel Cashier requires PHP 7.4. This version supports Laravel 7

To get the latest version, simply require the project using Composer:

```
$ composer require enea/laravel-cashier
```

And publish the configuration file.

```
$ php artisan vendor:publish --provider='Enea\Cashier\CashierServiceProvider'
```

Class reference
---------------

[](#class-reference)

This table defines the implementation of the models necessary for the operation of the package, there are some models that come to help such as: `$discount` and `$document`, however it is recommended to replace these models with your own.

**Concrete****Abstract****Description**`$client`[`Enea\Cashier\Contracts\BuyerContract`](/src/Contracts/BuyerContract.php)person who makes the purchase`$document`[`Enea\Cashier\Contracts\DocumentContract`](/src/Contracts/DocumentContract.php)type of sale document`$product`[`Enea\Cashier\Contracts\ProductContract`](/src/Contracts/ProductContract.php)product being sold`$quote`[`Enea\Cashier\Contracts\QuoteContract`](/src/Contracts/QuoteContract.php)quote available for sale`$quotedProduct`[`Enea\Cashier\Contracts\QuotedProductContract`](/src/Contracts/QuotedProductContract.php)quoted product to sell`$discount`[`Enea\Cashier\Modifiers\DiscountContract`](/src/Modifiers/DiscountContract.php)representation of a discount`$tax`[`Enea\Cashier\Modifiers\TaxContract`](/src/Modifiers/TaxContract.php)representation of a taxUsage
-----

[](#usage)

To start a purchase you must use the `ShoppingManager::initialize($client, $document)`.

```
use App\Client;
use Enea\Cashier\Documents\Invoice;
use Enea\Cashier\Facades\ShoppingManager;

$document = Invoice::create()->using([Taxes::IVA]); // or use your own model
$shoppingCart = ShoppingManager::initialize(Client::find(10), $document);
```

When you initialize a shopping cart, a token is generated so that it can be searched from `ShoppingManager::find($token)`. This function gets the shopping cart from session.

```
$token = $shoppingCart->getGeneratedToken();
$shoppingCart = ShoppingManager::find($token); // returns the shopping cart that matches the token
```

It is also possible that you want to invoice a quote, and to do so you must call the `attach` function of the `$shoppingCart`. Doing this creates a [`QuoteManager`](/src/QuoteManager.php) instance inside the Shopping Cart, which can be accessed from the `$shoppingCart->getQuoteManager()` function.

```
$shoppingCart->attach($quote);
```

Now you just have to add products to the shopping cart using `$shoppingCart->push($product, $quantity)`.

```
$keyboard = Product::query()->where('description', 'Keyboard K530-rgb')->firstOrFail();
$productCartItem = $shoppingCart->push($keyboard, 4);
```

Or you can also pull products from the quote using `$shoppingCart->pull($productID)`.

```
$productCartItem = $shoppingCart->pull($productID);
```

The `push` and `pull` methods returns an instance of [`ProductCartItem`](/src/Items/ProductCartItem.php), which provides a lot of useful method.

```
// set product quantity
$productCartItem->setQuantity(10);

// configure custom properties
$productCartItem->setProperty(['key' => 'value']);
$productCartItem->putProperty('key', 'value');
$productCartItem->removeProperty('key');

// manage discounts
$productCartItem->addDiscounts($discounts);
$productCartItem->addDiscount($discount);
$productCartItem->getDiscount($discountCode);
$productCartItem->removeDiscount($discountCode);

// get the totals
$cashier = $productCartItem->getCashier();
$cashier->getUnitPrice();
$cashier->getGrossUnitPrice();
$cashier->getNetUnitPrice();
$cashier->getQuantity();
$cashier->getSubtotal();
$cashier->getTotalDiscounts();
$cashier->getTotalTaxes();
$cashier->getTotal();
```

### Example

[](#example)

For this example, we are going to simulate a simple purchase. We need a `$client` and we will use a `$invoice` with `IVA` as a sales document.

```
class ShoppingCartController extends Controller
{
  public function start(Client $client): JsonResponse
  {
    $shoppingCart = ShoppingManager::initialize($client);
    $shoppingCart->setDocument(Invoice::create()->using([Taxes::IGV]));

    return response()->json([
      'token' => $shoppingCart->getGeneratedToken(),
      'shoppingCart' => $shoppingCart->toArray()
    ]);
  }

  public function addGlobalDiscount(Discount $discount, Request $request): JsonResponse
  {
    $shoppingCart = ShoppingManager::find($request->header('CART-TOKEN'));
    $shoppingCart->addDiscount($discount);

    return response()->json(compact('shoppingCart'));
  }

  public function removeGlobalDiscount(Discount $discount, Request $request): JsonResponse
  {
    $shoppingCart = ShoppingManager::find($request->header('CART-TOKEN'));
    $shoppingCart->removeDiscount($discount->getDiscountCode());

    return response()->json(compact('shoppingCart'));
  }
}
```

Now we add a controller to manage shopping cart products.

```
class ProductManagerController extends Controller
{
  public function addProduct(Product $product, Request $request): JsonResponse
  {
    $shoppingCart = ShoppingManager::find($request->header('CART-TOKEN'));
    $added = $shoppingCart->push($product, $request->get('quantity'));

    return response()->json(compact('shoppingCart', 'added'));
  }

  public function removeProduct(string $productID, Request $request): JsonResponse
  {
    $shoppingCart = ShoppingManager::find($request->header('CART-TOKEN'));
    $shoppingCart->remove($productID);

    return response()->json(compact('shoppingCart'));
  }

  public function updateProductQuantity(string $productID, Request $request): JsonResponse
  {
    $shoppingCart = ShoppingManager::find($request->header('CART-TOKEN'));
    $product = $shoppingCart->find($productID);
    $product->setQuantity($request->get('quantity'));

    return response()->json(compact('shoppingCart', 'product'));
  }

  public function addDiscountToProduct(string $productID, Discount $discount, Request $request): JsonResponse
  {
    $shoppingCart = ShoppingManager::find($request->header('CART-TOKEN'));
    $product = $shoppingCart->find($productID);
    $product->addDiscount($discount);

    return response()->json(compact('shoppingCart'));
  }

  public function removeDiscountToProduct(string $productID, Discount $discount, Request $request): JsonResponse
  {
    $shoppingCart = ShoppingManager::find($request->header('CART-TOKEN'));
    $product = $shoppingCart->find($productID);
    $product->removeDiscount($discount);

    return response()->json(compact('shoppingCart'));
  }
}
```

And to finish we save the document in the database.

```
class PurchaseController extends Controller
{
  public function store(Request $request): JsonResponse
  {
    $shoppingCart = ShoppingManager::find($request->header('CART-TOKEN'));
    $products = $shoppingCart->collection()->map($this->toOrderProduct());

    $order = DB::Transaction($this->createOrder($shoppingCart, $products));
    $dropped = $this->destroyShoppingCart($shoppingCart->getGeneratedToken());

    return response()->json(compact('order', 'dropped'));
  }

  private function createOrder(ShoppingCart $cart, Collection $products): Closure
  {
    return function() use ($cart, $products): Order {
      $order = Order::create([
        // complete the structure of your model
        'subtotal' => $cart->getSubtotal(),
        'total' => $cart->getTotal(),
        'document_id'd => $cart->getDocument()->getUniqueIdentificationKey(),
      ]);
      $order->detail()->saveMany($products);
      return $order;
    };
  }

  private function toOrderProduct(): Closure
  {
    return fn(ProductCartItem $product) => new OrderProduct([
      'product_id' => $product->getUniqueIdentificationKey(),
      'quantity' => $product->getQuantity(),
      'unit_price' => $product->getCashier()->getUnitPrice(),
      'discount' => $product->getCashier()->getTotalDiscounts(),
      'iva_pct' =>  $product->getTax('IVA')->getPercentage(),
    ]);
  }

  private function destroyShoppingCart(string $token): bool
  {
    ShoppingManager::drop($token);
    return !ShoppingManager::has($token);
  }
}
```

Cashier
-------

[](#cashier)

It is responsible for centralizing the calculations to get taxes, discounts and totals for each product. you can find it in [**Enea\\Cashier\\Calculations\\Cashier**](/src/Calculations/Cashier.php).

**Method****Description****Return****`getUnitPrice()`**unit sales pricefloat`getGrossUnitPrice()`gross price (price without tax)float`getNetUnitPrice()`net price (price + taxes)float`getSubtotal()`subtotalfloat`getTotalDiscounts()`total discountsfloat`getTotalTaxes()`total taxesfloat`getTotal()`final total with discounts and taxesfloat`getTaxes()`all taxes grouped by name[**Taxed\[\]**](/src/Calculations/Taxed.php)`getTax(string $name)`tax by name[**Taxed**](/src/Calculations/Taxed.php)`getDiscounts()`all discounts grouped by code[**Discounted\[\]**](/src/Calculations/Discounted.php)`getDiscount(string $code)`discount by code[**Discounted**](/src/Calculations/Discounted.php)### Pricing

[](#pricing)

Cashier separates the prices into 3, `getGrossUnitPrice()`, `getNetUnitPrice()` and `getUnitPrice()`, where the latter is the unit price after evaluating taxes, both **included** and **excluded**. `$cashier->getUnitPrice()` is the function used for all calculations. You can see an example in code from [`Enea\Tests\Calculations\PriceTest`](/tests/Calculations/PriceTest.php)

**Method**getGrossUnitPrice()getNetUnitPrice()getUnitPrice()**Base**100.00 $USD100.00 $USD100.00 $USD**Included Taxes**IVA(12%), AnotherTax(11%)IVA(12%), AnotherTax(11%)IVA(12%), AnotherTax(11%)**Tax to use**IVA(12%)IVA(12%)IVA(12%)**Applied**-IVA and AnotherTaxIVA**Total**81.30 $USD100 $USD90.24 $USDConfiguration
-------------

[](#configuration)

There are a few things you need to know to set up taxes and discounts correctly.

- [**Enea\\Cashier\\Modifiers\\DiscountContract**](/src/Modifiers/DiscountContract.php)

    Represents an applicable discount. There is quite a functional helper implementation in [`Enea\Cashier\Modifiers\Discount`](src/Modifiers/Discount.php) so it is not totally necessary to assign your own model, unless you want full control over the discount codes.

    ```
    namespace Enea\Cashier\Modifiers;

    use Enea\Cashier\Calculations\Percentager;
    use Enea\Cashier\Modifiers\DiscountContract;

    class Discount implements DiscountContract
    {
        public function getDiscountCode(): string
        {
            return $this->code;
        }

        public function getDescription(): string
        {
            return $this->description;
        }

        public function extract(float $total): float
        {
            if (! $this->percentage) {
                return $this->discount;
            }
    				// logic to calculate a percentage discount
            return Percentager::excluded($total, $this->discount)->calculate();
        }
    }
    ```
- [**Enea\\Cashier\\Contracts\\DocumentContract**](/src/Contracts/DocumentContract.php)

    Represents the type of document with which the sale will be made and also defines the taxes that will be applied to the products.

    ```
    namespace App\Models;

    use Enea\Cashier\Taxes;
    use Enea\Cashier\Contracts\DocumentContract;
    use Illuminate\Database\Eloquent\Model;

    class Document extends Model implements DocumentContract
    {
        public function taxesToUse(): array
        {
          	// some logic
            return [
              Taxes::IGV, // tax name
            ];
        }
    }
    ```
- [**Enea\\Cashier\\Modifiers\\TaxContract**](/src/Modifiers/TaxContract.php)

    Represents the tax on the `product`, the package has a help implementation which can be found in [`Enea\Cashier\Modifiers\Tax`](/src/Modifiers/Tax.php)

    ```
    namespace App\Models;

    use Enea\Cashier\Contracts\ProductContract;
    use Enea\Cashier\Modifiers\Tax;
    use Enea\Cashier\Taxes;

    class Product extends Model implements ProductContract
    {
        public function getUnitPrice(): float
        {
            return $this->sale_price;
        }

        public function getShortDescription(): string
        {
            return $this->short_description;
        }

        public function getTaxes(): array
        {
            return [
                Tax::included(Taxes::IGV, $this->igv_pct),
            ];
        }
    }
    ```

    To use taxes it is necessary to understand that they can be configured in 2 ways, **included** and **excluded**

    **Type****INCLUDED****EXCLUDED****Unit Price**100.00 $USD100.00 $USD**Tax %**10%10%**Total Tax**9.09 $USD10.00 $USD**Net Price**100.00 $USD110.00 $USD

More documentation
------------------

[](#more-documentation)

You can find a lot of comments within the source code as well as the tests located in the `tests` directory.

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity83

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~84 days

Recently: every ~435 days

Total

23

Last Release

1402d ago

Major Versions

0.1.4 → 1.0.02017-06-17

1.1.5 → 2.0.02017-10-04

2.0.1 → 3.0.02020-09-05

v3.1.0 → V4.0.02022-07-11

PHP version history (5 changes)0.0.1PHP &gt;=7.1

1.1.0PHP &gt;=5.6

3.0.0PHP &gt;=7.4

v3.1.0PHP ^7.4||^8.0

V4.0.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/ebfa2dc9bcd9f9f7cea1f5473811d3c3904f60716e5605ab0d7208a9a6b81f09?d=identicon)[vaened](/maintainers/vaened)

---

Top Contributors

[![vaened](https://avatars.githubusercontent.com/u/15077850?v=4)](https://github.com/vaened "vaened (176 commits)")

---

Tags

cashierlaravel-cashiershopping-cartmanagercartshoppingcashiersales

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/enea-laravel-cashier/health.svg)

```
[![Health](https://phpackages.com/badges/enea-laravel-cashier/health.svg)](https://phpackages.com/packages/enea-laravel-cashier)
```

###  Alternatives

[grumpydictator/firefly-iii

Firefly III: a personal finances manager.

22.8k69.3k](/packages/grumpydictator-firefly-iii)[lukepolo/laracart

A simple cart for Laravel

583135.4k1](/packages/lukepolo-laracart)[sylius/sylius-standard

Starting point for projects powered by Sylius eCommerce.

271291.3k](/packages/sylius-sylius-standard)[jackiedo/cart

A package used to create and manage carts (such as shopping, recently viewed, compared items...) in Laravel application.

20852.7k](/packages/jackiedo-cart)[firefly-iii/data-importer

Firefly III Data Import Tool.

7545.8k](/packages/firefly-iii-data-importer)[amsgames/laravel-shop

Package set to provide shop or e-commerce functionality (such as CART, ORDERS, TRANSACTIONS and ITEMS) to Laravel for customizable builds.

4845.9k](/packages/amsgames-laravel-shop)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
