hejunjie / trade-splitter
一个灵活、可扩展的交易/利润分账组件,提供百分比、固定金额、阶梯与递归分账等内置策略,并支持注册自定义策略 | A flexible and scalable transaction/profit sharing component, offering built-in strategies such as percentage, fixed amount, tiered, and recursive sharing, and supporting the registration of custom strategies
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 7
Watchers: 0
Forks: 2
Open Issues: 0
pkg:composer/hejunjie/trade-splitter
Requires
- php: >=8.1
README
PHP Trade Splitter
English|简体中文A flexible and extensible trade/profit distribution component.
Built-in strategies include Percentage, Fixed Amount, Ladder, and Recursive, and you can easily register custom strategies.
Perfect for multi-level commissions, e-commerce settlements, platform fees, and agent profit sharing.
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
✨ Features
- 🔧 Multiple Strategies – 4 common built-in distribution modes
- 🧩 Extensible Design – easily register your own strategy
- ⚡ Simple to Use – one static method does it all
- 🧠 Clean Architecture – object-oriented with the Strategy pattern
📦 Installation
composer require hejunjie/trade-splitter
🚀 Quick Start
<?php require __DIR__ . '/vendor/autoload.php'; use Hejunjie\TradeSplitter\Splitter; // Percentage-based split (the sum of all rates must equal 1.0) $allocations = Splitter::split(1000, [ ['name' => 'Platform', 'rate' => 0.1], ['name' => 'Author', 'rate' => 0.9], ], 'percentage'); // Convert to array and print results $result = array_map(fn($a) => $a->toArray(), $allocations); print_r($result);
Example output:
Array ( [0] => Array ( [name] => Platform [amount] => 100 [ratio] => 0.1 ) [1] => Array ( [name] => Author [amount] => 900 [ratio] => 0.9 ) )
🧩 Core Concepts
| Concept | Description |
|---|---|
| Splitter | The main entry point — selects the strategy and performs the split |
| StrategyInterface | Contract every strategy must implement:split(SplitContext $context): array |
| SplitContext | Contains the split context (totalandparticipants) |
| Allocation | Represents a split result withname,amount, andratio; providestoArray() |
🧮 Built-in Strategies
Percentage Split percentage
Distributes amounts by percentage. The sum of all rate values must equal 1.0.
$result = Splitter::split(1000, [ ['name' => 'Platform', 'rate' => 0.1], ['name' => 'Author', 'rate' => 0.9], ], 'percentage'); echo json_encode(array_map(fn($r) => $r->toArray(), $result), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . PHP_EOL; // Output: // [ // { // "name": "Platform", // "amount": 100, // "ratio": 0.1 // }, // { // "name": "Author", // "amount": 900, // "ratio": 0.9 // } // ]
Fixed Amount Split fixed
Splits by fixed amounts. The total of all fixed values must not exceed the total amount.
$result = Splitter::split(3000, [ ['name' => 'Agent A', 'amount' => 200], ['name' => 'Agent B', 'amount' => 300], ], 'fixed'); echo json_encode(array_map(fn($r) => $r->toArray(), $result), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . PHP_EOL; // Output: // [ // { // "name": "Agent A", // "amount": 200, // "ratio": 0.0667 // }, // { // "name": "Agent B", // "amount": 300, // "ratio": 0.1 // } // ]
Ladder Split ladder
Applies different percentage rates based on amount tiers.
Use null for no upper limit.
$result = Splitter::split(5000, [ [ 'name' => 'Agent A', 'ladders' => [ ['max' => 1000, 'rate' => 0.05], ['max' => 5000, 'rate' => 0.10], ['max' => null, 'rate' => 0.15], ], ], [ 'name' => 'Platform', 'rate' => 0.05, ], ], 'ladder'); echo json_encode(array_map(fn($r) => $r->toArray(), $result), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . PHP_EOL; // Output: // [ // { // "name": "Agent A", // "amount": 500, // "ratio": 0.1 // }, // { // "name": "Platform", // "amount": 250, // "ratio": 0.05 // } // ]
Recursive Split recursive
Each level’s share is calculated based on the remaining amount from the previous level.
Useful for multi-tier agent or channel commission systems.
$result = Splitter::split(10000, [ ['name' => 'Level 1', 'rate' => 0.2], ['name' => 'Level 2', 'rate' => 0.2], ['name' => 'Level 3', 'rate' => 0.2], ], 'recursive'); echo json_encode(array_map(fn($r) => $r->toArray(), $result), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . PHP_EOL; // Output: // [ // { // "name": "Level 1", // "amount": 1600, // "ratio": 0.2 // }, // { // "name": "Level 2", // "amount": 320, // "ratio": 0.2 // }, // { // "name": "Level 3", // "amount": 80, // "ratio": 0.2 // } // ]
🧠 Custom Strategy
Implement the Hejunjie\TradeSplitter\Contracts\StrategyInterface and register it:
use Hejunjie\TradeSplitter\Contracts\StrategyInterface; use Hejunjie\TradeSplitter\Models\SplitContext; use Hejunjie\TradeSplitter\Models\Allocation; use Hejunjie\TradeSplitter\Splitter; class MyStrategy implements StrategyInterface { public function split(SplitContext $context): array { // Custom split logic // total: $context->total // participants: $context->participants return [ new Allocation('someone', $context->total, 1.0) ]; } } Splitter::registerStrategy('my_strategy', MyStrategy::class); // Usage $total = 1000; $participants = []; $result = Splitter::split($total, $participants, 'my_strategy');
🧪 Run the Demo
A demo script is included in the repository:
php tests/demo.php
This script demonstrates all four built-in strategies.
💡 Motivation
This component was born from my frustration with rigid, hard-coded profit-sharing logic in various projects.
I wanted a clear, pluggable, and reusable solution that could be integrated into any project — without reinventing the wheel each time.
If you’ve encountered strange or complex split scenarios in your business,
feel free to collaborate and help make this tool even more powerful!
🤝 Contributing
Got ideas, feedback, or found a bug? PRs and Issues are always welcome 🙌
If you find this project helpful, please consider giving it a ⭐ Star — that’s the biggest motivation for me to keep improving it!