Ride Pausing
Ride pausing allows customers to temporarily stop their ride while keeping the vehicle reserved. This feature is essential for mid-ride breaks and is also used by the system for automatic interventions when certain conditions are detected.
Overview
The pause feature serves two primary purposes:
- Customer-initiated pause - Let customers take breaks without ending their ride
- System-initiated pause - Automatically pause rides when conditions warrant intervention
Understanding the different types of pauses and their behaviors is crucial for operators, as they have different safety implications and vehicle command patterns.
Key Concepts
| Concept | Description |
|---|---|
| Manual pause | Customer-initiated through the app |
| Auto-pause | System-initiated based on ride conditions |
| Pause rate billing | Reduced rate during paused periods |
| Vehicle immobilization | Different levels based on pause reason |
| Auto-resume | Some pauses can be automatically cleared |
| Auto-end | Prolonged pauses can trigger automatic ride ending |
Types of Pauses
Manual Pause (Customer-Initiated)
When a customer pauses their ride through the app:
| Aspect | Behavior |
|---|---|
| Trigger | Customer taps "Pause" in app |
| Vehicle Lock | Yes - vehicle is locked |
| Throttle | Disabled |
| Billing | Pause rate applies |
| Resume | Customer taps "Resume" in app |
| Status Badge | "Paused (Locked)" |
Common Uses:
- Quick store stops
- Coffee breaks
- Waiting for friends
- Multi-destination trips
Auto-Pause: Idle Movement
When the vehicle has been stationary for an extended period:
| Aspect | Behavior |
|---|---|
| Trigger | No movement detected for X minutes |
| Vehicle Lock | Yes - vehicle is locked |
| Throttle | Disabled |
| Billing | Pause rate applies |
| Resume | Customer taps "Resume" in app |
| Status Badge | "Paused (Locked)" |
| Reason Code | idle_movement |
Detection Logic:
IF vehicle hasn't moved beyond stationary_radius_m
for stationary_minutes duration
AND no recent motion detected (speed < recent_motion_speed_kmh)
THEN trigger auto-pause
Auto-Pause: No Location
When the vehicle stops reporting GPS location:
| Aspect | Behavior |
|---|---|
| Trigger | No GPS data received for X minutes |
| Vehicle Lock | Yes - vehicle is locked |
| Throttle | Disabled |
| Billing | Pause rate applies |
| Resume | Automatic when GPS restored, or manual |
| Status Badge | "Paused (Locked)" |
| Reason Code | no_location |
Common Causes:
- Indoor parking (GPS blocked)
- Signal dead zones
- IoT device issues
- Battery problems
Auto-Pause: Insufficient Funds
Critical Safety Feature
When wallet balance is insufficient, the system uses a different approach that prioritizes rider safety.
| Aspect | Behavior |
|---|---|
| Trigger | Wallet drops below threshold during billing |
| Vehicle Lock | NO - vehicle is NOT locked |
| Throttle | Disabled (motor power cut) |
| Billing | Continues at pause rate |
| Resume | Automatic when wallet topped up |
| Status Badge | "Paused (Throttle Disabled)" |
| Reason Code | insufficient_funds |
Why No Lock?
This is a critical safety decision:
When pausing for insufficient funds, the rider may be actively moving at speed. Locking the wheels while in motion could cause a dangerous crash. Instead, we only disable the throttle, which allows the rider to safely coast to a stop before the vehicle becomes unusable.
The throttle disable:
- Cuts power to the motor
- Allows wheels to spin freely (coasting)
- Rider can glide to a safe stopping point
- Vehicle doesn't abruptly stop
Safety Matrix
The system uses this decision matrix for pause behaviors:
| Pause Reason | Lock Vehicle | Throttle Off | Rationale |
|---|---|---|---|
| Manual pause | Yes | Yes | Vehicle stationary, full immobilization safe |
| Idle movement | Yes | Yes | Vehicle stationary, full immobilization safe |
| No location | Yes | Yes | Assume stationary (no GPS = likely indoors) |
| Insufficient funds | No | Yes | Rider may be moving - safety critical |
Why This Matters
Scenario: Customer is riding at 15 mph when their wallet runs out.
Correct behavior (throttle only):
- Motor power cuts
- Customer coasts to natural stop
- Customer safely dismounts
- Customer tops up wallet or ends ride
Incorrect behavior (lock wheels):
- Wheels lock at 15 mph
- Customer crashes
- Potential serious injury
- Major liability
Throttle-Pause Upgrade
When a ride is throttle-paused (insufficient funds), the system monitors for an opportunity to upgrade to a full lock.
Why Upgrade?
Throttle-only pause is a safety measure for moving vehicles. Once the vehicle becomes stationary, it's safe to apply the full lock for better security.
Upgrade Process
The auto-pause cron job monitors throttle-paused rides:
1. Check if ride is throttle-paused (auto_pause_reason = 'insufficient_funds')
2. Check if vehicle is now stationary
3. If stationary for sufficient time:
a. Send LOCK command to vehicle
b. Update ride status to show "Paused (Locked)"
c. Log the upgrade event
Detection Criteria
A throttle-paused ride is upgraded to full lock when:
- Vehicle hasn't moved beyond
stationary_radius_mthreshold - No recent motion detected (speed <
recent_motion_speed_kmh) - Vehicle is responding to commands
Safety + Security
This provides both safety (no crash from sudden lock) and security (vehicle locked when parked).
Pause Billing
How Pause Rates Work
During paused periods, a reduced rate applies:
Active Riding: $0.39 per minute
Paused: $0.10 per minute (example)
Pause rates are configured in the pricing rules for each vehicle model.
Billing Calculation Example
Ride: 20 minutes total
- 15 minutes active riding
- 5 minutes paused
Unlock Fee: $1.00
Active Time: 15 × $0.39 = $5.85
Pause Time: 5 × $0.10 = $0.50
────────────────────────────────────────
Total: $7.35
Continuous Billing
During auto-pause for insufficient funds:
- Billing continues at pause rate
- Wallet balance may go more negative
- Customer receives push notification
- Ride continues until wallet topped up or auto-ended
Auto-Pause Configuration
Configure auto-pause behavior in Settings > Other:
Stationary Detection Settings
{
"auto_pause_if_stationary": {
"enabled": true,
"stationary_minutes": 30,
"stationary_radius_m": 100,
"max_movement_within_radius_m": 0,
"recent_motion_window_seconds": 60,
"recent_motion_speed_kmh": 2
}
}
| Setting | Description | Default |
|---|---|---|
enabled | Enable/disable auto-pause for idleness | false |
stationary_minutes | Minutes of no movement before pause | 30 |
stationary_radius_m | Distance threshold for "stationary" | 100 |
max_movement_within_radius_m | Allowed movement within radius | 0 |
recent_motion_window_seconds | Time window for motion detection | 60 |
recent_motion_speed_kmh | Speed threshold for "moving" | 2 |
Low Balance Settings
{
"payments": {
"stop_vehicle_on_low_balance": true,
"stop_vehicle_threshold_cents": 0
}
}
| Setting | Description | Default |
|---|---|---|
stop_vehicle_on_low_balance | Enable throttle-off on low balance | false |
stop_vehicle_threshold_cents | Wallet level triggering throttle-off | 0 |
Setting threshold to 0 means the vehicle stops when wallet goes negative.
Resume Requirements
Wallet Balance Check on Resume
Before allowing a ride to resume, the system validates the customer has sufficient funds:
Required Balance = per_minute_rate_cents × 1 minute
If wallet balance is below this minimum:
- Resume is blocked
- Customer receives error with required vs. current balance
- Customer must top up wallet first
- Auto-top-up may trigger if enabled
Example:
Per-minute rate: $0.39
Required minimum: $0.39 (39 cents)
Customer wallet: $0.25
Result: Resume blocked - "Insufficient funds"
Required: $0.39 | Current: $0.25
Auto-End After Pause
Rides can be automatically ended if paused for too long:
Configuration
{
"auto_end_if_not_moving": {
"enabled": true,
"not_moving_radius_m": 75,
"end_after_pause_minutes": 30
}
}
| Setting | Description | Default |
|---|---|---|
enabled | Enable/disable auto-end | false |
not_moving_radius_m | Radius to consider "not moving" | 75 |
end_after_pause_minutes | Minutes of pause before ending | 30 |
Auto-End Behavior
When conditions are met:
- System checks if vehicle is in valid parking zone
- If valid, ride is automatically ended
- Final fare is calculated and charged
- Customer receives push notification
- Vehicle becomes available for next rental
If not in valid zone:
- Ride remains paused
- System continues monitoring
- Manual intervention may be needed
API Endpoints
Pause Ride (Mobile)
POST /api/mobile/rides/{ride_id}/pause/
Authentication: Customer JWT required
Request Body:
{
"pause_location": {
"latitude": 37.7749,
"longitude": -122.4194
}
}
Response (200 OK):
{
"ok": true,
"ride_status": "paused",
"paused_at": "2024-01-15T14:30:00Z",
"lock": {
"attempted": true,
"success": true,
"protocol": "OKAI"
}
}
Resume Ride (Mobile)
POST /api/mobile/rides/{ride_id}/resume/
Authentication: Customer JWT required
Response (200 OK):
{
"ok": true,
"ride_status": "active",
"resumed_at": "2024-01-15T14:45:00Z",
"unlock": {
"attempted": true,
"success": true,
"protocol": "OKAI"
}
}
Error Response (Insufficient Funds):
{
"error": "Insufficient funds",
"required": 0.39,
"balance": 0.25
}
Admin Pause/Resume
Administrators can also pause and resume rides:
POST /api/rides/{ride_id}/pause/
POST /api/rides/{ride_id}/resume/
Authentication: Admin session required
Permission: ride:update
Webhook Integration
The system sends webhooks to partner APIs when pauses and resumes occur.
Pause Webhook
When a ride is paused, the system queues a ride.paused webhook:
{
"event": "ride.paused",
"data": {
"ride_id": "uuid-12345",
"customer_id": "uuid-customer",
"vehicle_id": "uuid-vehicle",
"paused_at": "2024-01-15T14:30:00Z",
"pause_reason": "manual",
"subaccount_id": "uuid-subaccount"
}
}
| Field | Description |
|---|---|
ride_id | The paused ride's UUID |
customer_id | Customer who owns the ride |
vehicle_id | Vehicle being paused |
paused_at | ISO timestamp of pause |
pause_reason | manual, idle_movement, no_location, or insufficient_funds |
subaccount_id | Subaccount for multi-tenant filtering |
Resume Webhook
When a ride is resumed, the system queues a ride.resumed webhook:
{
"event": "ride.resumed",
"data": {
"ride_id": "uuid-12345",
"customer_id": "uuid-customer",
"vehicle_id": "uuid-vehicle",
"resumed_at": "2024-01-15T14:45:00Z",
"pause_duration_seconds": 900,
"subaccount_id": "uuid-subaccount"
}
}
| Field | Description |
|---|---|
pause_duration_seconds | How long the ride was paused |
Vehicle Commands
Lock Sequence (Standard Pause)
When a ride is paused normally:
1. Send LOCK command to vehicle
2. Wait for acknowledgment (up to 10 seconds)
3. Send THROTTLE_OFF command
4. Wait for acknowledgment
5. Update ride status to 'paused'
6. Queue webhook notification
Throttle-Only Sequence (Low Balance)
When pausing for insufficient funds:
1. Send THROTTLE_OFF command only
2. Wait for acknowledgment
3. Update ride status to 'paused'
4. DO NOT send LOCK command (safety)
5. Queue webhook notification
Resume Sequence
When resuming a paused ride:
1. Validate wallet balance (must cover at least 1 minute of riding)
2. Send UNLOCK command to vehicle
3. Wait for acknowledgment
4. Send THROTTLE_ON command
5. Wait for acknowledgment
6. Update ride status to 'active'
7. Clear pause fields (auto_paused_at, auto_pause_reason)
8. Queue webhook notification to partner API
Command Failures
If vehicle commands fail:
| Command | Failure Impact | Mitigation |
|---|---|---|
| LOCK fails | Vehicle may remain unlocked | Logged, manual follow-up |
| THROTTLE_OFF fails | Motor may stay powered | Retry automatically |
| UNLOCK fails | Customer can't resume | Dashboard shows warning |
| THROTTLE_ON fails | Customer can't ride | Retry, then support ticket |
Customer Experience
Pause Notifications
When a ride is paused, the customer receives:
Manual Pause:
Ride Paused
Your ride is paused. Billing continues at the reduced pause rate.
Tap Resume when ready to continue.
Auto-Pause (Idle):
Ride Auto-Paused
Your ride was paused due to inactivity. The vehicle is locked.
Tap Resume to continue your ride.
Auto-Pause (Low Balance):
Low Balance - Vehicle Stopped
Your wallet balance is too low. The motor has been disabled.
Top up your wallet to continue riding.
[Top Up Now]
Resume Flow
- Customer opens app
- Sees "Paused" status
- Taps "Resume" button
- App sends resume request
- Vehicle unlocks and enables throttle
- Billing switches back to active rate
- Customer continues riding
Dashboard Management
Viewing Paused Rides
On the Rides list page:
- Filter by "Paused" status
- Status badge shows pause type
- Duration column shows total time including pause
Admin Actions
From the Ride Detail page:
Resume Button:
- Visible when ride is paused
- Sends unlock + throttle-on commands
- Updates ride to active status
End Ride Button:
- Available for both active and paused rides
- Ends ride at current location
- Calculates final fare
Troubleshooting
Vehicle Won't Lock on Pause
Possible Causes:
- IoT device offline
- Weak cellular signal
- Command timeout
- Device firmware issue
Resolution:
- Check vehicle's last signal time
- Retry pause command
- Use dashboard to send manual lock
- Dispatch field team if needed
Vehicle Won't Unlock on Resume
Possible Causes:
- IoT device offline
- Command didn't reach vehicle
- Physical lock mechanism stuck
Resolution:
- Retry resume command
- Check IoT device status
- End ride if unable to resume
- Issue refund if warranted
- Mark vehicle for maintenance
Customer Stuck in Paused State
If customer can't resume:
- Check ride status in dashboard
- Try admin resume action
- End ride if necessary
- Issue appropriate refund
- Investigate vehicle/IoT issue
Auto-Pause Triggering Too Frequently
Adjust settings:
- Increase
stationary_minutes - Increase
stationary_radius_m - Adjust motion detection thresholds
- Consider disabling for specific locations
Best Practices
For Operators
- Monitor paused rides - Check daily for extended pauses
- Review auto-pause logs - Look for patterns indicating issues
- Configure thresholds carefully - Balance convenience vs. abuse
- Train support team - Know how to handle pause-related issues
For Configuration
- Start conservative - Begin with auto-pause disabled
- Test thoroughly - Verify vehicle commands work before enabling
- Consider your market - Urban areas may need different settings
- Communicate to customers - Explain pause policies in app
For Safety
- Never lock moving vehicles - Always use throttle-only for low balance
- Test command reliability - Ensure vehicles respond consistently
- Have manual overrides - Dashboard should always allow intervention
- Document incidents - Track any safety-related issues