Fare System
The fare calculation engine supports zone-based pricing, surge multipliers, time-of-day adjustments, and vehicle type differentiation.
Calculation Flow
FareHelper::calculateFare($distance, $duration, $vehicleType, $zoneId, $surgeMultiplier)
Step 1: Load Fare Rule
The system finds the most specific matching fare rule:
- Zone + vehicle type match (most specific)
- Zone + "all" vehicle types
- No zone + vehicle type match
- No zone + "all" vehicle types (fallback)
Rules with effective_from/effective_to dates are checked for currency.
Step 2: Base Calculation
base_fare + (distance * per_km) + (duration * per_minute)
Step 3: Night Surcharge
Applied between 22:00 and 06:00 (server timezone via Factory::getDate()->format('H')):
subtotal += night_surcharge (flat fee)
The system tracks whether the night surcharge was applied to avoid double-counting in the fare breakdown.
Step 4: Peak Hours Multiplier
Only applied when the current hour falls within the rule's peak_hours_start and peak_hours_end window:
if (hour >= peak_hours_start && hour < peak_hours_end) {
subtotal *= peak_multiplier
}
Step 5: Surge Multiplier
Applied last, using the multiplier captured at ride request time (not current conditions):
subtotal *= surge_multiplier
Step 6: Minimum Fare
The final fare is clamped to the rule's minimum_fare if the calculated amount is lower.
Fare Breakdown
The ride record stores individual components:
| Field | Description |
|---|---|
| base_fare | Base charge from rule |
| distance_charge | Distance component |
| time_charge | Duration component |
| surge_multiplier | Applied surge (1.0 = none) |
| surcharges | Night + airport + other fees |
| total_fare | Final amount |
Surge Pricing
Surge multipliers are determined by supply/demand ratio in each zone:
surge = available_drivers / active_rides_in_zone
See Dispatch Engine for how surge interacts with driver availability.
Surge Cap
The maximum surge multiplier is capped by the max_surge_multiplier plugin parameter (default: 3.0).
Airport Surcharge
Fare rules can include an airport_surcharge applied to pickups or dropoffs in airport-type zones.
Commission Split
After fare calculation:
platform_fee = total_fare * commission_rate
driver_payout = total_fare - platform_fee
The commission rate comes from the driver record (per-driver override) or the global plugin parameter.