Create, list, track, and poll deliveries in Flutter.

flasho.deliveries

flasho.deliveries

create()

Books a delivery. Returns a Delivery object on success.

On-demand

final delivery = await flasho.deliveries.create(
  CreateDeliveryRequest(
    customerName: 'Ahmed Ali',
    customerNumber: '99887766',
    pickupLatitude: 29.3764,
    pickupLongitude: 47.9785,
    deliveryLatitude: 29.3117,
    deliveryLongitude: 48.0034,
  ),
);
 
print(delivery.orderNumber);    // FLH4001
print(delivery.status.name);    // pending
print(delivery.estimatedPrice); // "1.250"

Cash-on-delivery

final delivery = await flasho.deliveries.create(
  CreateDeliveryRequest(
    customerName: 'Sara Mohammed',
    customerNumber: '66554433',
    pickupLatitude: 29.3764,
    pickupLongitude: 47.9785,
    deliveryLatitude: 29.3117,
    deliveryLongitude: 48.0034,
    collectCash: true,
    totalAmount: '15.750',
    specialNotes: 'Collect exact amount',
  ),
);

Scheduled delivery

// Always check availability first
final settings = await flasho.account.getScheduledDeliverySettings();
if (!settings.available) throw Exception('Scheduled delivery not enabled');
 
final delivery = await flasho.deliveries.create(
  CreateDeliveryRequest(
    customerName: 'Ahmed Ali',
    customerNumber: '99887766',
    pickupLatitude: 29.3764,
    pickupLongitude: 47.9785,
    deliveryLatitude: 29.3117,
    deliveryLongitude: 48.0034,
    isScheduled: true,
    scheduledDeliveryAt: DateTime.now().toUtc().add(const Duration(hours: 2)),
  ),
);

⚠️ Scheduled time constraints

scheduledDeliveryAt must be at least 30 minutes from now and no more than 14 days ahead.

Request fields

FieldTypeRequiredDefaultDescription
customerNameString✓—Recipient full name
customerNumberString✓—Recipient phone
pickupLatitudedouble✓—Pickup GPS latitude
pickupLongitudedouble✓—Pickup GPS longitude
deliveryLatitudedouble✓—Drop-off GPS latitude
deliveryLongitudedouble✓—Drop-off GPS longitude
alternateCustomerNumberString?——Secondary phone
additionalAddressDetailString?——Apartment/floor
deliveryAddressList<String>?—AutoAddress parts
pickupNameString?——Override pickup contact
pickupNumberString?——Override pickup phone
collectCashbool—falseEnable COD
totalAmountString—"0.000"COD amount in KWD
specialNotesString?——Driver instructions
vehicleTypeVehicleType—bikebike, car, van
isScheduledbool—falseScheduled delivery
scheduledDeliveryAtDateTime?✓ if scheduled—UTC delivery time

list()

Returns List<Delivery> newest-first.

// Latest 20
final deliveries = await flasho.deliveries.list(limit: 20);
 
// Filter by status
final pending = await flasho.deliveries.list(
  status: DeliveryStatus.pending,
);
 
final active = await flasho.deliveries.list(
  status: DeliveryStatus.enroute,
);

get()

Fetch a single delivery by ID.

final delivery = await flasho.deliveries.get('clx...');
 
print(delivery.status.name);  // enroute
print(delivery.driverName);   // Mohammed
print(delivery.driverPhone);  // 99112233
 
for (final entry in delivery.statusHistory) {
  print('${entry.status.name} at ${entry.timestamp}');
}

poll()

Poll until a terminal state is reached. Handles the loop for you.

final finalDelivery = await flasho.deliveries.poll(
  delivery.id,
  interval: const Duration(seconds: 5),
  timeout: const Duration(minutes: 15),
  onUpdate: (d) {
    debugPrint('Status: ${d.status.name}');
    if (d.driverName != null) {
      debugPrint('Driver: ${d.driverName} — ${d.driverPhone}');
    }
  },
);
 
switch (finalDelivery.status) {
  case DeliveryStatus.delivered:
    print('Delivered!');
  case DeliveryStatus.cancelled:
    print('Cancelled.');
  default:
    print('Ended: ${finalDelivery.status.name}');
}

📝 Terminal states

poll() resolves when status reaches delivered, cancelled, rejected, or failed. It throws TimeoutException if the timeout elapses first.


Flutter widget example

class DeliveryTracker extends StatefulWidget {
  final String deliveryId;
  const DeliveryTracker({required this.deliveryId, super.key});
 
  @override
  State<DeliveryTracker> createState() => _DeliveryTrackerState();
}
 
class _DeliveryTrackerState extends State<DeliveryTracker> {
  String _status = 'Loading...';
  String? _driver;
 
  @override
  void initState() {
    super.initState();
    _startPolling();
  }
 
  void _startPolling() {
    final flasho = context.read<FlashoClient>();
    flasho.deliveries.poll(
      widget.deliveryId,
      onUpdate: (d) {
        if (mounted) {
          setState(() {
            _status = d.status.name;
            _driver = d.driverName;
          });
        }
      },
    );
  }
 
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Status: $_status'),
        if (_driver != null) Text('Driver: $_driver'),
      ],
    );
  }
}

Order statuses

StatusDescription
pendingBooked, awaiting dispatch
requestedDriver request sent
acceptedDriver accepted
inprogressDriver heading to pickup
pickedupOrder collected
enrouteDriver heading to customer
deliveredComplete ✓
cancelledCancelled
rejectedNo driver available
failedDelivery failed

Check delivery.isTerminal to test whether a delivery has reached a final state.