PHPackages                             blesta/pricing - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. blesta/pricing

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

blesta/pricing
==============

A library for handling pricing and pricing modifiers

3.4.0(2y ago)14964↓33.3%5[2 issues](https://github.com/blesta/pricing/issues)MITPHPPHP &gt;=5.4.0CI failing

Since Apr 29Pushed 2y ago6 watchersCompare

[ Source](https://github.com/blesta/pricing)[ Packagist](https://packagist.org/packages/blesta/pricing)[ Docs](http://github.com/blesta/pricing)[ RSS](/packages/blesta-pricing/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (6)Dependencies (3)Versions (23)Used By (0)

blesta/pricing
==============

[](#blestapricing)

[![Build Status](https://camo.githubusercontent.com/5887a55245038dacc06a54bed4e06682838f7627d6268364c785b3a03da00ee5/68747470733a2f2f7472617669732d63692e6f72672f626c657374612f70726963696e672e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/blesta/pricing) [![Coverage Status](https://camo.githubusercontent.com/94a4e379d727c09fec24ab4d09af2f885f17ab129bbae6bab41a24cedf204437/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f626c657374612f70726963696e672f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/blesta/pricing?branch=master)

A library for handling pricing. Supports:

- Unit Prices
- Item Prices
    - Unit Price that may include discounts and taxes
- Discounts
    - Percentages
    - Fixed amounts
- Taxes (inclusive\_calculated, inclusive, exclusive)
    - Inclusive and Exclusive
    - Applied in sequence or compounded
    - Inclusive calculated is meant to be subtracted from the item price
- Item Collection
    - Iterate over Item Prices
    - Aggregate totals over Item Prices

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

[](#installation)

Install via composer:

```
composer require blesta/pricing
```

Basic Usage
-----------

[](#basic-usage)

### UnitPrice

[](#unitprice)

```
use Blesta\Pricing\Type\UnitPrice;

$price = new UnitPrice(5.00, 2, "id");
$price->setDescription("2 X 5.00");
$unit_price = $price->price(); // 5.00
$qty = $price->qty(); // 2
$total = $price->total(); // 10.00
$key = $price->key(); // id

// Update the unit price, quantity, and key
$price->setPrice(10.00);
$price->setQty(3);
$price->setKey('id2');
```

### DiscountPrice

[](#discountprice)

```
use Blesta\Pricing\Modifier\DiscountPrice;

$discount = new DiscountPrice(25.00, "percent");
$discount->setDescription("25% off");
$price_after_discount = $discount->off(100.00); // 75.00
$discount_price = $discount->on(100.00); // 25.00
```

### TaxPrice

[](#taxprice)

Exclusive tax (price does not include tax):

```
use Blesta\Pricing\Modifier\TaxPrice;

$tax = new TaxPrice(10.00, TaxPrice::EXCLUSIVE);
$tax->setDescription("10 % tax");
$tax->on(100.00); // 10.00
$tax->off(100.00); // 100.00 (price on exclusive tax doesn't include tax, so nothing to take off)
$tax->including(100.00); // 110.00
```

Inclusive tax (price already includes tax):

```
use Blesta\Pricing\Modifier\TaxPrice;

$tax = new TaxPrice(25.00, TaxPrice::INCLUSIVE);
$tax->setDescription("25 % tax");
$tax->on(100.00); // 25.00
$tax->off(100.00); // 75.00
$tax->including(100.00); // 100.00
```

Inclusive tax (price already includes tax) calculated based on the price minus tax:

```
use Blesta\Pricing\Modifier\TaxPrice;

$tax = new TaxPrice(25.00, TaxPrice::INCLUSIVE_CALCULATED);
$tax->setDescription("25 % tax");
$tax->on(100.00); // 20.00
$tax->off(100.00); // 80.00
$tax->including(100.00); // 100.00
```

Cascading tax (tax on a tax):

```
use Blesta\Pricing\Modifier\TaxPrice;
use Blesta\Pricing\Type\UnitPrice;

$price = new UnitPrice(10.00);
$tax1 = new TaxPrice(10.00, TaxPrice::EXCLUSIVE);
$tax2 = new TaxPrice(5.00, TaxPrice::EXCLUSIVE);
$tax2->on(
    $tax1->on(
        $price->total()
    )
    + $price->total()
); // 0.55 = [((10.00 * 0.10) + 10.00) * 0.05]
```

### ItemPrice

[](#itemprice)

```
use Blesta\Pricing\Type\ItemPrice;

$item_price = new ItemPrice(10.00, 3);
$item_price->total(); // 30.00
```

With discount applied:

```
use Blesta\Pricing\Modifier\DiscountPrice;

$discount = new DiscountPrice(5.00, "percent");

// call setDiscount() as many times as needed to apply discounts
$item_price->setDiscount($discount);
$item_price->totalAfterDiscount(); // 28.50
```

Amount applied for a specific discount:

```
use Blesta\Pricing\Modifier\DiscountPrice;

$item_price = new ItemPrice(10.00, 3);

$discount1 = new DiscountPrice(5.00, "percent");
$discount2 = new DiscountPrice(25.00, "percent");

// NOTE: Order matters here
$item_price->setDiscount($discount1);
$item_price->setDiscount($discount2);

$item_price->discountAmount($discount1); // 1.50
$item_price->discountAmount($discount2); // 7.125 ((30.00 - 1.50) * 0.25)
```

With tax applied:

```
use Blesta\Pricing\Modifier\TaxPrice;

$tax = new TaxPrice(10.00, TaxPrice::EXCLUSIVE);

// call setTax() as many times as needed to apply multiple levels of taxes
$item_price->setTax($tax);
// pass as many TaxPrice objects to setTax as you want to compound tax
// ex. $item_price->setTax($tax1, $tax2, ...);
$item_price->totalAfterTax(); // 32.1375 = (subtotal + ([subtotal - discounts] * taxes)) = (30 + [30 - (1.50 + 7.125)] * 0.10)
```

With tax and discount:

```
$item_price->total(); // 23.5125 = (subtotal - discounts + ([subtotal - discounts] * taxes)) = (30 - (1.50 + 7.125) + [30 - (1.50 + 7.125)] * 0.10)
```

With tax and discount where the discount does *not* apply to the taxes:

```
$item_price->setDiscountTaxes(false);
$item_price->total(); // 24.375 = (subtotal - discounts + ([subtotal] * taxes)) = (30 - (1.50 + 7.125) + ([30] * 0.10))
```

Without taxes of the 'exclusive' type:

```
$item_price->setDiscountTaxes(true);
$item_price->excludeTax(TaxPrice::EXCLUSIVE)->totalAfterTax(); // 30.00 = (30 + [30 - (1.50 + 7.125)] * 0)
$item_price->total(); // 21.375 = (30 - (1.50 + 7.125) + [30 - (1.50 + 7.125)] * 0)

// Be sure to reset the excluded taxes before attempting to fetch totals that should include them again!
$item_price->resetTaxes();
$item_price->total(); // 23.5125 = (subtotal - discounts + ([subtotal - discounts] * taxes)) = (30 - (1.50 + 7.125) + [30 - (1.50 + 7.125)] * 0.10)
$item_price->excludeTax(TaxPrice::EXCLUSIVE)->total(); // 21.375 = (30 - (1.50 + 7.125) + [30 - (1.50 + 7.125)] * 0)
$item_price->resetTaxes();
```

Amount applied for a specific tax:

```
use Blesta\Pricing\Modifier\TaxPrice;

$tax1 = new TaxPrice(10.00, TaxPrice::EXCLUSIVE);
$tax2 = new TaxPrice(5.00, TaxPrice::INCLUSIVE);

// NOTE: order *DOES NOT* matter
$item_price->setTax($tax1);
$item_price->setTax($tax2);

$item_price->taxAmount($tax1); // 2.1375 = ([subtotal - discounts] * taxes) = ([30 - (1.50 + 7.125)] * 0.10)
$item_price->taxAmount($tax2); // 1.06875 = ([subtotal - discounts] * taxes) = ([30 - (1.50 + 7.125)] * 0.05)
```

Without taxes of the 'exclusive' type:

```
$item_price->excludeTax(TaxPrice::EXCLUSIVE)->totalAfterTax(); // 31.06875 = (subtotal + ([subtotal - discounts] * taxes)) = (30 + [30 - (1.50 + 7.125)] * 0.05)
$item_price->resetTaxes();
```

Cascading tax:

```
use Blesta\Pricing\Modifier\TaxPrice;
use Blesta\Pricing\Type\ItemPrice;

$item_price = new ItemPrice(10.00, 3);

$tax1 = new TaxPrice(10.00, TaxPrice::EXCLUSIVE);
$tax2 = new TaxPrice(5.00, TaxPrice::INCLUSIVE);
$tax3 = new TaxPrice(2.50, TaxPrice::EXCLUSIVE);

$item_price->setTax($tax1, $tax2, $tax3);
$item_price->taxAmount($tax1); // 3.00 = ([subtotal - discounts] * taxes) = ([30 - 0] * 0.10)
$item_price->taxAmount($tax2); // 1.65 = ([subtotal - discounts + previous-taxes] * 0.05) = ([30.00 - 0 + 3.00] * 0.05)
$item_price->taxAmount($tax3); // 0.86625 = ([subtotal - discounts + previous-taxes] * 0.025) = ([30.00 - 0 + 3.00 + 1.65] * 0.025)
$item_price->taxAmount(); // 5.51625

// Exclude taxes of the 'inclusive' type
$item_price->excludeTax(TaxPrice::INCLUSIVE);
$item_price->taxAmount($tax1); // 3.00 = ([subtotal - discounts] * taxes) = ([30 - 0] * 0.10)
$item_price->taxAmount($tax2); // 0 = ([subtotal - discounts + previous-taxes] * 0) = ([30.00 - 0 + 3.00] * 0)
$item_price->taxAmount($tax3); // 0.86625 = ([subtotal - discounts + previous-taxes] * 0.025) = ([30.00 - 0 + 3.00 + 1.65] * 0.025)
$item_price->taxAmount(); // 3.86625
$item_price->resetTaxes();
```

### ItemPriceCollection

[](#itempricecollection)

```
use Blesta\Pricing\Collection\ItemPriceCollection;
use Blesta\Pricing\Type\ItemPrice;

$item_collection = new ItemPriceCollection();

$item1 = new ItemPrice(10.00, 3);
$item2 = new ItemPrice(25.00, 2);
$item_collection->append($item1)->append($item2);

$item_collection->total(); // 80.00

foreach ($item_collection as $item) {
    $item->total(); // 30.00, 50.00
}
```

### PricingFactory

[](#pricingfactory)

Using the PricingFactory can streamline usage. Assume you have the following:

```
$products = array(
    array('desc' => 'Apples', 'amount' => 0.5, 'qty' => 3),
    array('desc' => 'Oranges', 'amount' => 0.75, 'qty' => 10)
);
```

So we initialize our PricingFactory, and let it create our DiscountPrice and TaxPrice objects for use.

```
use Blesta\Pricing\PricingFactory;

$pricing_factory = new PricingFactory();

// Some coupon
$discount = $pricing_factory->discountPrice(50.00, "percent");
$discount->setDescription('Super-Saver Coupon');

// Typical local sales tax
$tax = $pricing_factory->taxPrice(10.00, TaxPrice::EXCLUSIVE);
$tax->setDescription("Sales tax");
```

Then we let the PricingFactory initialize our ItemPriceCollection, and each ItemPrice over our data set.

```
$item_collection = $pricing_factory->itemPriceCollection();

foreach ($products as $product) {
    $item = $pricing_factory->itemPrice($product['amount'], $product['qty']);
    $item->setDescription($product['desc']);
    $item->setTax($tax);

    if ('Apples' === $product['desc']) {
        $item->setDiscount($discount);
    }
    $item_collection->append($item);
}

$item_collection->discountAmount($discount); // 0.75
$item_collection->taxAmount($tax); // 0.825
$item_collection->subtotal(); // 9.00
$item_collection->totalAfterTax(); // 9.825
$item_collection->totalAfterDiscount(); // 8.25
$item_collection->total(); // 9.075
```

You may also exclude specific taxes by their type when calculating totals:

```
$item_collection->excludeTax(TaxPrice::EXCLUSIVE)->taxAmount($tax); // 0.00
$item_collection->excludeTax(TaxPrice::EXCLUSIVE)->totalAfterTax(); // 9.00
$item_collection->excludeTax(TaxPrice::EXCLUSIVE)->total(); // 8.25
$item_collection->total(); // 9.075 (item tax exclusions in the collection are reset after each call to a ::total..., the ::taxAmount, or ::discountAmount)
```

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance17

Infrequent updates — may be unmaintained

Popularity27

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

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 ~173 days

Recently: every ~159 days

Total

18

Last Release

1087d ago

Major Versions

1.2.2 → 2.0.02016-05-27

2.0.1 → 3.0.02016-06-09

PHP version history (2 changes)1.0.0PHP &gt;=5.1.0

2.0.0PHP &gt;=5.4.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/7f87ae869d67f48673504d6cba1adcb8945a3ba8280798917e18b7c744009fc2?d=identicon)[clphillips](/maintainers/clphillips)

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

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

---

Top Contributors

[![clphillips](https://avatars.githubusercontent.com/u/682986?v=4)](https://github.com/clphillips "clphillips (45 commits)")[![tysonphillips](https://avatars.githubusercontent.com/u/8607630?v=4)](https://github.com/tysonphillips "tysonphillips (28 commits)")[![JReissmueller](https://avatars.githubusercontent.com/u/18198499?v=4)](https://github.com/JReissmueller "JReissmueller (13 commits)")[![abdyfranco](https://avatars.githubusercontent.com/u/23648083?v=4)](https://github.com/abdyfranco "abdyfranco (5 commits)")

---

Tags

taxpricingdiscounttotals

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/blesta-pricing/health.svg)

```
[![Health](https://phpackages.com/badges/blesta-pricing/health.svg)](https://phpackages.com/packages/blesta-pricing)
```

###  Alternatives

[mpociot/vat-calculator

EU VAT calculation, the way it should be.

1.3k3.9M18](/packages/mpociot-vat-calculator)[commerceguys/tax

Tax library with a flexible data model, predefined tax rates, powerful resolving logic.

286763.3k](/packages/commerceguys-tax)[frittenkeez/laravel-vouchers

Voucher system for Laravel 9+

5819.9k2](/packages/frittenkeez-laravel-vouchers)[serendipity_hq/bundle-features

Manage features and plans in your Symfony app.

1184.3k](/packages/serendipity-hq-bundle-features)[opengento/module-saleable

This extension allows to set if a product is saleable and can show its price by scope and customer group.

136.9k](/packages/opengento-module-saleable)[andychukse/laravel-pricing-plans

A package provide pricing plans for Laravel.

121.8k](/packages/andychukse-laravel-pricing-plans)

PHPackages © 2026

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