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
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
customerName | String | ✓ | — | Recipient full name |
customerNumber | String | ✓ | — | Recipient phone |
pickupLatitude | double | ✓ | — | Pickup GPS latitude |
pickupLongitude | double | ✓ | — | Pickup GPS longitude |
deliveryLatitude | double | ✓ | — | Drop-off GPS latitude |
deliveryLongitude | double | ✓ | — | Drop-off GPS longitude |
alternateCustomerNumber | String? | — | — | Secondary phone |
additionalAddressDetail | String? | — | — | Apartment/floor |
deliveryAddress | List<String>? | — | Auto | Address parts |
pickupName | String? | — | — | Override pickup contact |
pickupNumber | String? | — | — | Override pickup phone |
collectCash | bool | — | false | Enable COD |
totalAmount | String | — | "0.000" | COD amount in KWD |
specialNotes | String? | — | — | Driver instructions |
vehicleType | VehicleType | — | bike | bike, car, van |
isScheduled | bool | — | false | Scheduled delivery |
scheduledDeliveryAt | DateTime? | ✓ 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
| Status | Description |
|---|---|
pending | Booked, awaiting dispatch |
requested | Driver request sent |
accepted | Driver accepted |
inprogress | Driver heading to pickup |
pickedup | Order collected |
enroute | Driver heading to customer |
delivered | Complete ✓ |
cancelled | Cancelled |
rejected | No driver available |
failed | Delivery failed |
Check delivery.isTerminal to test whether a delivery has reached a final state.