Skip to main content

Receiving Trip Requests

When you’re online and available, Viax automatically searches for nearby trip requests and notifies you with sound alerts.
Trip requests are prioritized based on distance, ConfianzaScore, and whether passengers have marked you as a favorite driver.

Sound Notification System

Viax uses an audio notification system similar to Uber and DiDi to alert you of new ride requests:

How It Works

1

New Request Detected

System finds a matching trip request near your location
2

Sound Alert Plays

request_notification.mp3 plays at maximum volume to get your attention
3

Visual Panel Appears

Trip details slide up from the bottom of the screen
4

30-Second Timer

You have 30 seconds to accept or reject the request

Sound Service Implementation

Sound Notification Service
import 'package:audioplayers/audioplayers.dart';

class SoundService {
  static final AudioPlayer _audioPlayer = AudioPlayer();
  
  /// Play notification sound for new trip request
  static Future<void> playRequestNotification() async {
    try {
      await _audioPlayer.setVolume(1.0); // Maximum volume
      await _audioPlayer.play(
        AssetSource('sounds/request_notification.mp3'),
        mode: PlayerMode.mediaPlayer,
      );
    } catch (e) {
      debugPrint('Error playing notification sound: $e');
    }
  }
  
  /// Play confirmation sound when accepting
  static Future<void> playAcceptSound() async {
    try {
      await _audioPlayer.play(
        AssetSource('sounds/accept.mp3'),
        mode: PlayerMode.mediaPlayer,
      );
    } catch (e) {
      debugPrint('Error playing accept sound: $e');
    }
  }
  
  /// Stop any currently playing sound
  static Future<void> stopSound() async {
    try {
      await _audioPlayer.stop();
    } catch (e) {
      debugPrint('Error stopping sound: $e');
    }
  }
}
Make sure your phone volume is turned up and not in silent mode, or you might miss ride requests!

Trip Request Information

Each request displays comprehensive information to help you decide:

Request Data Model

Trip Request View Model
class TripRequestView {
  final int id;                    // Request ID
  final int clienteId;             // Passenger user ID
  final String clienteNombre;      // Passenger name
  final String? clienteFoto;       // Passenger profile photo
  final double? clienteCalificacion; // Passenger rating
  
  // Origin details
  final double latitudOrigen;
  final double longitudOrigen;
  final String direccionOrigen;
  
  // Destination details
  final double latitudDestino;
  final double longitudDestino;
  final String direccionDestino;
  
  // Trip metrics
  final double? distanciaKm;       // Distance in kilometers
  final double? precioEstimado;    // Estimated price
  final DateTime fechaSolicitud;   // Request timestamp
  
  // Trust information
  final ConfianzaInfo? confianza;  // Trust score if available
  
  LatLng get origen => LatLng(latitudOrigen, longitudOrigen);
  LatLng get destino => LatLng(latitudDestino, longitudDestino);
}

Visual Request Panel

The request panel shows:

Passenger Info

  • Name and photo
  • Rating (if available)
  • Favorite badge (if you’re their favorite)

Trip Details

  • Pickup address
  • Destination address
  • Distance and duration

Earnings

  • Estimated fare
  • Your potential earnings
  • Commission breakdown

Route Preview

  • Map with route highlighted
  • Distance to pickup
  • Traffic conditions

Accepting a Request

Accept Flow

1

Review Details

Examine the trip information displayed on the request panel
Request Panel
RequestActionPanel(
  request: selectedRequest,
  routeToClient: routeToClient,
  currentLocation: currentLocation,
  onAccept: _acceptRequest,
  onReject: _rejectRequest,
  onTimeout: _rejectRequest,
  isDark: isDark,
)
2

Tap Accept Button

Click the green “Accept” button to accept the trip
Accept Request
Future<void> _acceptRequest() async {
  if (_selectedRequest == null || _requestProcessed) return;
  _requestProcessed = true;
  
  // Stop notification sound
  SoundService.stopSound();
  
  // Show loading indicator
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (context) => Center(
      child: CircularProgressIndicator(color: AppColors.primary),
    ),
  );
  
  // Call API to accept request
  final result = await TripRequestSearchService.acceptRequest(
    solicitudId: solicitudData.id,
    conductorId: widget.conductorId,
  );
  
  Navigator.pop(context); // Close loading
  
  if (result['success'] == true) {
    // Navigate to active trip screen
    final viajeId = int.tryParse(result['viaje_id']?.toString() ?? '0');
    
    Navigator.pushAndRemoveUntil(
      context,
      MaterialPageRoute(
        builder: (context) => ConductorActiveTripScreen(
          conductorId: conductorId,
          solicitudId: solicitudData.id,
          viajeId: viajeId,
          clienteId: solicitudData.clienteId,
          origenLat: solicitudData.latitudOrigen,
          origenLng: solicitudData.longitudOrigen,
          destinoLat: solicitudData.latitudDestino,
          destinoLng: solicitudData.longitudDestino,
          direccionOrigen: solicitudData.direccionOrigen,
          direccionDestino: solicitudData.direccionDestino,
          clienteNombre: solicitudData.clienteNombre,
        ),
      ),
      (route) => false,
    );
  } else {
    // Show error - request already taken
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(result['message'] ?? 'Request unavailable')),
    );
  }
}
3

Confirmation

System assigns the trip to you and notifies the passenger
  • Trip status changes to “accepted”
  • Passenger receives notification
  • You’re navigated to active trip screen

Accept Request API

Trip Request Search Service
class TripRequestSearchService {
  static Future<Map<String, dynamic>> acceptRequest({
    required int solicitudId,
    required int conductorId,
  }) async {
    try {
      final response = await http.post(
        Uri.parse('$baseUrl/conductor/accept_request.php'),
        headers: {'Content-Type': 'application/json'},
        body: json.encode({
          'solicitud_id': solicitudId,
          'conductor_id': conductorId,
        }),
      );
      
      if (response.statusCode == 200) {
        return json.decode(response.body);
      } else {
        return {'success': false, 'message': 'Server error'};
      }
    } catch (e) {
      return {'success': false, 'message': 'Network error: $e'};
    }
  }
}

Rejecting a Request

Reject Flow

1

Tap Reject Button

Click the red “Reject” button or let the timer expire
Reject Request
Future<void> _rejectRequest() async {
  if (_selectedRequest == null || _requestProcessed) return;
  _requestProcessed = true;
  
  // Stop notification sound
  SoundService.stopSound();
  
  final solicitudData = _selectedRequest!;
  setState(() {
    _selectedRequest = null;
    _routeToClient = null;
  });
  
  // Mark as processed to avoid duplicate actions
  TripRequestSearchService.markRequestAsProcessed(solicitudData.id);
  
  // Notify server of rejection
  await TripRequestSearchService.rejectRequest(
    solicitudId: solicitudData.id,
    conductorId: widget.conductorId,
    motivo: 'Driver declined',
  );
  
  // Return to searching screen
  if (mounted) Navigator.pop(context);
}
2

Request Released

Request becomes available for other drivers
  • Your rejection is logged
  • Request offered to next available driver
  • You continue searching for other requests
Important: Excessive rejections may affect your priority in receiving future requests. Only reject if you have a valid reason.

Request Prioritization

How Requests Are Assigned

Viax uses intelligent prioritization to match drivers with passengers:
Closer drivers see requests first
  • Distance from your location to pickup point
  • Estimated time to reach passenger
  • Real-time traffic considerations
Trust relationship between you and passenger
Confianza Scoring
ConfianzaScore calculation:
- Previous trips together: 30%
- Your average rating: 25%
- Passenger's ratings of you: 15%
- Zone proximity: 20%
- Neighborhood popularity: 10%
- Bonus: +100 if passenger marked you as favorite
Passengers can mark preferred driversIf a passenger has marked you as favorite:
  • You get priority notification
  • +100 point bonus to ConfianzaScore
  • Badge displayed in request panel
Driver status and capacity
  • Must be online and available
  • No active trip in progress
  • Profile approved and complete

Request List Response

From the backend API:
{
  "success": true,
  "total": 1,
  "solicitudes": [
    {
      "id": 123,
      "usuario_id": 45,
      "nombre_usuario": "Juan Pérez",
      "foto_perfil": "uploads/profile/45.jpg",
      "latitud_origen": 4.6097,
      "longitud_origen": -74.0817,
      "direccion_origen": "Calle 100 #15-20",
      "latitud_destino": 4.6531,
      "longitud_destino": -74.0836,
      "direccion_destino": "Calle 127 #7-45",
      "distancia_km": 5.2,
      "precio_estimado": 12500,
      "fecha_solicitud": "2026-03-05 14:30:00",
      "confianza": {
        "score": 45.5,
        "score_total": 145.5,
        "viajes_previos": 5,
        "es_favorito": true
      }
    }
  ]
}

Auto-Rejection

If you don’t respond within 30 seconds:
1

Timer Expires

30-second countdown reaches zero
2

Auto-Reject

System automatically rejects the request
Timeout Handler
Timer? _requestTimer;

void _startRequestTimer() {
  _requestTimer = Timer(Duration(seconds: 30), () {
    if (_selectedRequest != null && !_requestProcessed) {
      _rejectRequest();
    }
  });
}

@override
void dispose() {
  _requestTimer?.cancel();
  super.dispose();
}
3

Sound Stops

Notification sound automatically stops
4

Continue Searching

You return to searching mode for new requests

Best Practices

Maximize Your Earnings:
  1. Respond Quickly - Faster responses increase your acceptance rate
  2. Check Distance - Consider pickup distance vs. trip fare
  3. Know Your Area - Accept trips in areas you know well
  4. Build Trust - High ratings lead to more favorite requests
  5. Stay Online - More availability means more opportunities
Avoid These Mistakes:
  • Don’t accept requests you can’t fulfill
  • Don’t reject too many consecutive requests
  • Don’t keep passengers waiting after accepting
  • Don’t ignore low-rated requests if you need income

Next Steps

After accepting a ride:

Trip Execution

Learn the complete trip workflow from pickup to completion

Navigation

Use maps and navigation to reach your passenger

Earnings

Track your income from completed trips

Notifications

Manage notification settings and alerts

Build docs developers (and LLMs) love