$fees * @param list $lineItems * @return array{ * results: array, * total_fee_amount: int, * net_amount: int * } */ public function calculate(array $fees, int $totalAmount, array $lineItems): array { $results = []; $balance = $totalAmount; $totalFeeAmount = 0; foreach ($fees as $key => $ruleData) { $amount = $this->calculateFeeAmount( MarketplaceFeeRule::fromArray($ruleData), $totalAmount, $lineItems, ); $balance = max($balance - $amount, 0); $totalFeeAmount += $amount; $results[$key] = [ 'amount' => $amount, 'balance_after' => $balance, ]; } return [ 'results' => $results, 'total_fee_amount' => $totalFeeAmount, 'net_amount' => max($totalAmount - $totalFeeAmount, 0), ]; } /** * @param list $lineItems */ private function calculateFeeAmount(MarketplaceFeeRule $rule, int $totalAmount, array $lineItems): int { if ($rule->scope === MarketplaceFeeScope::TRANSACTION) { return $this->calculateFromBasis( $rule, $totalAmount, ); } return (int) collect($lineItems)->sum(function (array $item) use ($rule): int { if ($rule->valueType === MarketplaceFeeValueType::FLAT) { return (int) round($rule->value * $item['quantity']); } return (int) round($item['subtotal'] * $rule->value / 100); }); } private function calculateFromBasis(MarketplaceFeeRule $rule, int $basis): int { if ($rule->valueType === MarketplaceFeeValueType::FLAT) { return (int) round($rule->value); } return (int) round($basis * $rule->value / 100); } }