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
- 🔧 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
composer require hejunjie/trade-splitter<?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
)
)| 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() |
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
// }
// ]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
// }
// ]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
// }
// ]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
// }
// ]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');A demo script is included in the repository:
php tests/demo.phpThis script demonstrates all four built-in strategies.
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!
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!