PHPackages                             hejunjie/promotion-engine - 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. hejunjie/promotion-engine

ActiveLibrary

hejunjie/promotion-engine
=========================

一个 灵活可扩展 的 PHP 促销策略引擎，让购物车的各种复杂促销逻辑（满减、打折、阶梯优惠、会员折扣…）实现更优雅、可维护 ｜ A flexible and scalable PHP promotional strategy engine that enables various complex promotional logics (money off, discounts, tiered offers, member discounts, etc.) in shopping carts to be implemented more elegantly and maintainably.

v2.2.0(5mo ago)1731MITPHPPHP &gt;=7.4

Since Jul 29Pushed 5mo agoCompare

[ Source](https://github.com/zxc7563598/php-promotion-engine)[ Packagist](https://packagist.org/packages/hejunjie/promotion-engine)[ RSS](/packages/hejunjie-promotion-engine/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)DependenciesVersions (6)Used By (0)

🛒 hejunjie/promotion-engine
===========================

[](#-hejunjiepromotion-engine)

 [English](./README.md)｜[简体中文](./README.zh-CN.md)---

A **flexible and scalable** PHP promotional strategy engine that enables various complex promotional logics (money off, discounts, tiered offers, member discounts, etc.) in shopping carts to be implemented more elegantly and maintainably.

**This project has been parsed by Zread. If you need a quick overview of the project, you can click here to view it：[Understand this project](https://zread.ai/zxc7563598/php-promotion-engine)**

---

📦 Installation method
---------------------

[](#-installation-method)

Install this library using Composer：

```
composer require hejunjie/promotion-engine
```

---

🚀 Usage
-------

[](#-usage)

```
use Hejunjie\PromotionEngine\Models\Cart;
use Hejunjie\PromotionEngine\Models\User;
use Hejunjie\PromotionEngine\PromotionEngine;
use Hejunjie\PromotionEngine\Rules;

// Create user (VIP)
$user = new User(vip: true);

// Create a shopping cart (with 10 items, and the total price can cover various rules)
$cart = new Cart();
$cart->addItem('商品A', 50, 1, ['snacks']);
$cart->addItem('商品B', 60, 1, ['clothes']);
$cart->addItem('商品C', 40, 1, ['clothes']);
$cart->addItem('商品D', 100, 1, ['promo']);
$cart->addItem('商品E', 30, 3, ['snacks']);
$cart->addItem('商品F', 200, 1, ['electronics']);

// Initialize the promotion engine
$engine = new PromotionEngine();
// Explanation of promotion calculation mode:
//
// independent (independent mode):
// Each rule calculates the discount amount separately based on the "original price of the product",
// Finally, the discounts will be consolidated, and the total price will not be affected by intermediate calculations from other rules.
//
// sequential (discount-on-discount mode):
// Each rule continues to calculate based on the "previously calculated price", resulting in a "discount on discount" effect.
// When a rule involves multiple products, the discount amount will be allocated based on the proportion of each product's original price in the total combined price,
// To ensure that the price of each item is updated correctly in subsequent calculations.
//
// lock (locked mode):
// Each item will only be discounted by one rule at most, and subsequent rules will not apply repeated discounts to items that have already been locked.
// Applicable to business scenarios where "a certain product can only enjoy one discount" (such as flash sales, exclusive coupons, etc.).
$engine->setMode('independent');

// Register all rules
$engine->addRule(new Rules\FullDiscountRule(200, 0.9));  // 10% off for purchases over 200
$engine->addRule(new Rules\FullQuantityReductionRule(3, 20));  // Buy 3 or more and get 20% off
$engine->addRule(new Rules\NthItemDiscountRule(3, 0.5));  // Third item is 50% off
$engine->addRule(new Rules\VipDiscountRule(0.95));  // 5% discount for VIP
$engine->addRule(new Rules\FullQuantityDiscountRule(5, 0.9));  // 10% off for purchases of 5 items or more
$engine->addRule(new Rules\FullReductionRule(100, 20));  // 20 off for purchases over 100
$engine->addRule(new Rules\VipReductionRule(5));  // VIP: 5 yuan off

// Perform calculation
$result = $engine->calculate($cart, $user);

// Print result (for manual verification)
echo "\n=== test result ===\n";
echo "original price: ¥{$result['original']}\n";
echo "discount: -¥{$result['discount']}\n";
echo "final: ¥{$result['final']}\n";
echo "Discount Details:\n";
foreach ($result['details'] as $detail) {
    echo "- {$detail}\n";
}

// 输出内容：
// === test result ===
// original price: ¥540
// discount: -¥200
// final: ¥340
// Discount Details:
// - 指定商品满200元打0.9折 (-¥54)
// - 指定商品满3件减20 (-¥20)
// - 指定商品第3件打5折 (-¥20)
// - VIP 0.95 折 (-¥27)
// - 指定商品满5件打9折 (-¥54)
// - 指定商品满100减20 (-¥20)
// - VIP 立减 5 元 (-¥5)
```

🛠️ Rule type (out-of-box)
-------------------------

[](#️-rule-type-out-of-box)

方法说明FullDiscountRuleFor purchases over X yuan, receive a Z% discount (Example: For purchases over 200 yuan, receive a 20% discount)FullQuantityReductionRuleBuy X items and get Y yuan off (Example: Buy 3 items and get 20 yuan off)NthItemDiscountRuleThe Nth item is discounted by Z (Example: the 3rd item is discounted by 50%)TieredDiscountRuleEnjoy a Z% discount when your purchase reaches X yuan (Example: 10% discount when your purchase reaches 100 yuan, 20% discount when your purchase reaches 200 yuan, 30% discount when your purchase reaches 500 yuan (whichever is the highest))VipDiscountRuleVIP users enjoy discounts (Example: 10% off for VIP)FullQuantityDiscountRuleBuy X items and get Z% off (Example: Buy 3 items and get 10% off)FullReductionRuleFor purchases over X yuan, get Y yuan off (Example: for purchases over 100 yuan, get 20 yuan off)"NthItemReductionRuleThe Nth item is on special offer (Example: the 3rd item is priced at 9.9 yuan)TieredReductionRuleStep discount: subtract Y yuan when the purchase reaches X yuan (Example: subtract 10 yuan when the purchase reaches 100 yuan, subtract 30 yuan when the purchase reaches 200 yuan, and subtract 80 yuan when the purchase reaches 500 yuan (whichever is the highest level))VipReductionRuleVIP users enjoy immediate discounts (Example: a discount of 5 yuan when ordering as a VIP)🎯 Purpose &amp; Original Intent
-------------------------------

[](#-purpose--original-intent)

> **Why write this package?**

In e-commerce, B2C, and retail systems, promotion logic is often scattered across Controller, Service, and if-else statements. Once there are numerous rules, maintenance becomes a nightmare.

✅ I hope to **solve this problem using a 'rule engine + extensible policy class'**:

- **Write each discount as a separate class** → clear, easy to test, reusable
- **Supports multiple calculation modes** → `original` (based on original price) / `stack` (discount on discount)
- **Easy to extend** → Adding new rules only requires `extends PromotionRule`

👉 In this way, for future integrations of **new activities / membership levels / specific product category discounts**, it will only be necessary to create a new `Rule`, without the need for major code modifications.

---

🤝 Welcome PR &amp; contributions
--------------------------------

[](#-welcome-pr--contributions)

📢 **All pull requests (PRs) are welcome:**

- New promotional rules (such as coupons, buy-one-get-one-free, flash sales, etc.)
- Optimize core logic (such as more flexible rule priorities, discount stacking strategies)
- Unit testing (PHPUnit) or performance optimization
-

👉 Fork this repository and submit a Pull Request, or create an issue to exchange ideas.

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance73

Regular maintenance activity

Popularity12

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75% 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 ~35 days

Total

5

Last Release

153d ago

Major Versions

v1.0.0 → v2.0.02025-08-01

PHP version history (2 changes)v1.0.0PHP &gt;=8.1

v2.2.0PHP &gt;=7.4

### Community

Maintainers

![](https://www.gravatar.com/avatar/5b65d4b40ae456172fb38f63f84bf737ac88031484b1f228b1cc8d71baa80adf?d=identicon)[苏青安](/maintainers/%E8%8B%8F%E9%9D%92%E5%AE%89)

---

Top Contributors

[![zxc7563598](https://avatars.githubusercontent.com/u/46590942?v=4)](https://github.com/zxc7563598 "zxc7563598 (3 commits)")[![mingzhanliao](https://avatars.githubusercontent.com/u/63911596?v=4)](https://github.com/mingzhanliao "mingzhanliao (1 commits)")

---

Tags

cart-discountcomposerecommercephp8promotion-enginestrategy-pattern

### Embed Badge

![Health badge](/badges/hejunjie-promotion-engine/health.svg)

```
[![Health](https://phpackages.com/badges/hejunjie-promotion-engine/health.svg)](https://phpackages.com/packages/hejunjie-promotion-engine)
```

PHPackages © 2026

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