Ending Group Rides
The End Group Rides feature allows a customer who started a group ride session to end all rides in that session simultaneously. This is used when one person has rented multiple vehicles for a group (family, friends, tour group) and needs to end the entire session at once.
Overview
Group rides allow one customer to start multiple vehicles for a group outing. When the group is done, they need an efficient way to end all rides together. The End Group Rides feature:
- Ends the parent ride and all child rides in a group session
- Calculates and charges final fares for each ride
- Sends lock commands to all affected vehicles
- Returns a summary of all ended rides
Key Concepts
| Term | Definition |
|---|---|
| Parent Ride | The first ride started in a group session (marked as is_group_ride_parent: true) |
| Child Rides | Additional rides linked to the parent via parent_ride_id |
| Group Session | All rides (parent + children) under one customer account |
| Batch End | Single API call ends all rides in the session |
Key Features
- Session-based - Ends rides linked to a specific parent ride
- Safety-first - Locks all vehicles after ending
- Comprehensive billing - Calculates accurate fare for each ride
- Error resilience - Continues processing even if individual rides fail
- Detailed response - Reports success/failure for each ride
How Group Rides Work
Starting a Group Ride
Start First Vehicle
Customer scans and starts the first vehicle - this becomes the Parent Ride.
Add More Vehicles
Customer scans additional vehicles - these become Child Rides linked to the parent.
Track Under One Account
All rides are tracked under the same customer account.
Respect Limits
Maximum number of rides per session is configurable (default: 5).
During the Group Ride
- All rides run independently (separate billing, separate routes)
- Customer can pause/resume individual rides
- Customer can end individual rides if someone leaves early
- Dashboard shows all rides linked by parent relationship
Ending the Group Session
When ending the entire group:
- Customer taps "End All Rides" in the app
- App calls the end-all endpoint with the parent ride ID
- System validates the parent ride exists and is active
- System ends parent + all active child rides
- Customer sees summary of all ended rides and total charges
API Endpoint
Request
POST /api/mobile/rides/end-all/
Authentication: Required (Customer JWT token)
Request Body:
{
"parent_ride_id": "uuid-of-parent-ride",
"end_location": {
"latitude": 37.7749,
"longitude": -122.4194
}
}
| Field | Type | Required | Description |
|---|---|---|---|
parent_ride_id | String (UUID) | Yes | The ID of the parent ride in the group session |
end_location | Object | Yes | Customer's current GPS location |
end_location.latitude | Number | Yes | Latitude coordinate |
end_location.longitude | Number | Yes | Longitude coordinate |
Response
Success (200 OK):
{
"ok": true,
"ended_rides": [
{
"ride_id": "uuid-parent",
"ride_number": "R-12345",
"vehicle_id": "VH-001",
"final_amount_cents": 685,
"duration_seconds": 912,
"distance_m": 2340,
"status": "completed",
"is_parent": true
},
{
"ride_id": "uuid-child-1",
"ride_number": "R-12346",
"vehicle_id": "VH-002",
"final_amount_cents": 445,
"duration_seconds": 654,
"distance_m": 1890,
"status": "completed",
"is_parent": false
}
],
"total_charged_cents": 1130,
"warnings": []
}
Partial Success (200 OK with warnings):
{
"ok": true,
"ended_rides": [
{
"ride_id": "uuid-parent",
"ride_number": "R-12345",
"vehicle_id": "VH-001",
"final_amount_cents": 685,
"status": "completed"
}
],
"total_charged_cents": 685,
"warnings": [
{
"ride_id": "uuid-child-1",
"ride_number": "R-12346",
"message": "Failed to lock vehicle - command timeout"
}
]
}
Error Responses:
| Status | Condition |
|---|---|
400 Bad Request | parent_ride_id not provided |
400 Bad Request | Ride is not a group ride parent |
401 Unauthorized | Invalid or missing authentication |
404 Not Found | Parent ride not found |
500 Internal Server Error | System error during processing |
Group Ride Configuration
Maximum Rides Per Session
Configure the maximum vehicles allowed in a single group session:
Location: Settings > Other
{
"group_rides_max": 5
}
| Value | Behavior |
|---|---|
1 | Group rides disabled (only single rides allowed) |
5 | Default - up to 5 vehicles per group |
10 | Larger groups (e.g., tour operators) |
Common Use Cases
| Scenario | Typical Max | Notes |
|---|---|---|
| Consumer app | 3-5 | Families, small friend groups |
| Tourism | 10-15 | Guided tours |
| Corporate | 10-20 | Team outings, events |
Processing Details
Ride Ending Sequence
For each ride in the group (parent + children):
-
Status Update
- Sets
ride_statustocompleted - Records
ended_attimestamp - Records
end_locationcoordinates
- Sets
-
Fare Calculation
- Calculates active time charges
- Calculates pause time charges
- Applies any discounts (promo codes, subscriptions)
- Applies daily cap if reached
- Applies minimum price if applicable
-
Wallet Deduction
- Debits final amount from customer wallet
- Records transaction in wallet history
- Handles negative balance if insufficient funds
-
Vehicle Commands
- Sends lock command to vehicle
- Disables throttle (for supported vehicles)
- Updates vehicle status to "available"
-
Notifications
- Sends ride completion push notification
- Includes final charge amount
- Links to ride receipt
Error Handling
The system uses a "best effort" approach:
- If one child ride fails to end, others still process
- Vehicle lock failures are logged but don't block completion
- Billing errors are logged for manual review
- Customer sees warnings for any issues
Resilient Processing
Group ride ending continues even if some rides encounter errors. Check the warnings array in the response for any issues that need attention.
What Can Fail
| Failure | Impact | Resolution |
|---|---|---|
| Vehicle lock timeout | Ride ends, vehicle may remain unlocked | Manual lock via dashboard |
| Wallet deduction fails | Ride ends, balance goes negative | Collect on next top-up |
| Location missing | Uses last known vehicle location | Acceptable fallback |
| Database error | That specific ride not ended | Retry or manual end |
Zone Validation
When ending group rides, the system validates parking zones:
Parking Zone Check
Each ride in the group is validated:
- Check if end_location is within a designated parking zone
- If outside parking zone:
- Check if
allow_end_ride_outside_parking_zonesetting is true - If not allowed, that ride remains active (warning returned)
- Check if
- If in no-parking zone:
- That ride remains active (warning returned)
- Customer must move that vehicle to valid zone
Location Sources
The system uses two location sources for validation:
| Source | Priority | Use Case |
|---|---|---|
| User Device Location | Primary | Customer's phone GPS |
| Vehicle Location | Fallback | IoT device GPS |
The parking_zone_validation_mode setting determines which source is used:
vehicle_only- Only check vehicle GPSboth- Both must be in valid zonehybrid- Either can satisfy the requirement
Billing Implications
Multiple Ride Charges
Each ride in the group is calculated independently:
Parent Ride: $6.85 (15 min active, $1 unlock, $0.39/min)
Child Ride 1: $5.05 (10 min active + 2 min pause, $1 unlock)
Child Ride 2: $4.45 (8 min active, $1 unlock)
────────────────────────────────────────────
Total: $16.35 charged to wallet
Daily Cap Across Group
The daily cap applies per customer across all rides in the group:
Customer has $30 daily cap
Parent Ride: $12.00
Child Ride 1: $15.00
Child Ride 2: $18.00 (would exceed cap)
────────────────────────────────────────────
Child Ride 2 capped at: $3.00 (reaches $30 total)
Total charged: $30.00
Insufficient Wallet Balance
If wallet balance is insufficient:
- All rides still end normally
- Wallet balance goes negative
- Customer cannot start new rides until topped up
- Auto-top-up triggers if enabled
Use Cases
Family Day Out
- Parent starts ride for themselves (parent ride)
- Parent starts rides for 2 children (child rides)
- Family rides together for 45 minutes
- At destination, parent taps "End All Rides"
- All 3 vehicles lock, single wallet charge
Guided Tour
- Tour guide starts parent ride
- Guide starts 8 child rides for tour participants
- Group completes 2-hour tour route
- At tour end point, guide ends all rides
- All 9 vehicles secured, total billed to guide's account
Friend Group Split
- One friend starts 4 rides for the group
- After 30 minutes, one person leaves early
- That individual ride is ended separately
- Later, remaining 3 rides ended together via end-all
- Only active child rides are affected by end-all
Dashboard Management
Viewing Group Rides
In the Rides list:
- Parent rides show indicator (group icon)
- Filter available to show only group rides
- Click parent ride to see all linked children
Ride Detail Page
For parent rides:
- "Child Rides" section lists all rides in the session
- Click any child ride to view its details
- Shows aggregate statistics (total duration, total revenue)
Admin Actions
Operators can:
- End individual rides from a group session
- End all rides in a group from dashboard
- View group ride history for a customer
Integration Notes
For App Developers
When implementing the End Group Rides feature:
- Track Parent Ride ID - Store the parent ride ID when starting group session
- Location Permission - Ensure location access before calling
- Confirmation UX - Show preview of all rides being ended
- Loading State - Endpoint may take several seconds for multiple rides
- Error Display - Show any warnings to customer
- Receipt Screen - Navigate to summary after completion
Expected Response Times
| Number of Rides | Expected Time |
|---|---|
| 1-2 rides | 1-2 seconds |
| 3-5 rides | 2-4 seconds |
| 6-10 rides | 4-8 seconds |
Error Handling
If the request times out:
- Check individual ride statuses before retrying
- Some rides may have ended successfully
- Show current state to customer
- Only remaining active rides will be processed on retry
Troubleshooting
"parent_ride_id required"
Cause: Request body missing the parent ride ID Resolution: Ensure app sends the stored parent ride UUID
"Ride is not a group ride parent"
Cause: The provided ride ID is a child ride, not the parent Resolution: Use the original parent ride ID from when session started
"Failed to lock vehicle"
Cause: Vehicle IoT command failed Impact: Ride ends but vehicle may remain unlocked Resolution: Manually lock via dashboard or dispatch field team
"Location not in valid zone"
Cause: One or more vehicles are in no-parking/no-go zone Resolution:
- Those specific rides remain active
- Customer must move those vehicles to valid parking
- Other rides in the group still end successfully
Timeout During Processing
Cause: Network issues or high load Resolution:
- Wait 30 seconds
- Check Rides list for current status
- Manually end any remaining active rides
Permissions and Security
Authentication
- Requires valid customer JWT token
- Token must not be expired
- Customer account must be active (not suspended)
Authorization
- Customer can only end their own group rides
- Parent ride must belong to the authenticated customer
- Cannot end another customer's group session
- Admin endpoints exist for operator intervention
Rate Limiting
To prevent abuse:
- Maximum 10 requests per minute per customer
- Helps prevent accidental duplicate requests