Skip to main content
The ShipmentService provides methods for managing shipments, including listing orders, retrieving shipment details, updating status, and tracking delivery history.

Service Creation

import { createShipmentService } from '@/services/shipments/shipments.service';
import { httpClient } from '@/services/http.service';

const shipmentsService = createShipmentService(httpClient);
Source: src/services/shipments/shipments.service.ts:6-20

Methods

list

Retrieve a paginated list of shipments with optional filtering.
shipmentsService.list(query: Query): ApiResponse<GetShipmentsResponse>

Parameters

query
Query
required
Query parameters for filtering and pagination
query.page
number
Page number (1-based)
query.limit
number
Number of items per page
query.status
string
Filter by shipment status (e.g., “pending”, “in_transit”, “delivered”)
Search by reference number or recipient phone

Response

meta
PaginationMeta
required
Pagination metadata
meta.totalItems
number
Total number of items across all pages
meta.itemCount
number
Number of items in current page
meta.itemsPerPage
number
Items per page
meta.totalPages
number
Total number of pages
meta.currentPage
number
Current page number
items
Shipment[]
required
Array of shipment objects

Example Usage

import { shipmentsService } from '@/services';

try {
  const response = await shipmentsService.list({
    page: 1,
    limit: 20,
    status: 'in_transit',
  });

  console.log(`Total shipments: ${response.data.meta.totalItems}`);
  console.log(`Current page: ${response.data.meta.currentPage}`);
  response.data.items.forEach(shipment => {
    console.log(`${shipment.reference}: ${shipment.status}`);
  });
} catch (error) {
  console.error('Failed to fetch shipments:', error.message);
}

getRiderLatestOrders

Retrieve the latest orders assigned to a specific rider.
shipmentsService.getRiderLatestOrders(riderId: string): ApiResponse<GetShipmentsResponse>

Parameters

riderId
string
required
The unique identifier of the rider

Response

Returns the same structure as the list method, containing the rider’s latest orders.

Example Usage

try {
  const response = await shipmentsService.getRiderLatestOrders('rider-123');
  
  console.log(`Latest orders for rider: ${response.data.items.length}`);
  response.data.items.forEach(order => {
    console.log(`${order.reference}: ${order.dropOffCity}`);
  });
} catch (error) {
  console.error('Failed to fetch rider orders:', error.message);
}

getByReference

Retrieve detailed information about a shipment by its reference number.
shipmentsService.getByReference(reference: string): ApiResponse<Shipment>

Parameters

reference
string
required
The unique reference number of the shipment

Response

Returns a single Shipment object with complete details.
id
string
Unique shipment identifier
reference
string
Unique reference number for tracking
status
string
Current shipment status
pickupCity
string
Pickup city name
pickupArea
string
Pickup area/neighborhood
senderPhone
string
Sender’s phone number
pickupDate
string | null
Scheduled pickup date (ISO 8601 format)
dropOffCity
string
Destination city name
dropOffArea
string
Destination area/neighborhood
recipientPhone
string
Recipient’s phone number
dropOffDate
string | null
Scheduled delivery date (ISO 8601 format)
extraInformation
string | null
Additional delivery instructions or notes
shipmentOption
string
Shipment option (e.g., “standard”, “express”)
modeOfShipment
string
Mode of shipment (e.g., “motorcycle”, “bicycle”)
rider
Rider | null
Assigned rider information (if assigned)
history
ShipmentHistory[]
Array of status history entries
shipmentCost
ShipmentCost | null
Cost breakdown for the shipment
shipmentCost.pickupFee
number
Pickup fee amount
shipmentCost.deliveryFee
number
Delivery fee amount
shipmentCost.riderCommission
number
Rider’s commission amount
shipmentCost.repackagingFee
number
Repackaging fee (if applicable)
shipmentCost.totalCost
number
Total cost of shipment
shipmentCost.paid
boolean
Whether the shipment has been paid for
createdAt
string
Creation timestamp (ISO 8601 format)
updatedAt
string
Last update timestamp (ISO 8601 format)

Example Usage

try {
  const response = await shipmentsService.getByReference('SHIP-2024-0001');
  const shipment = response.data;
  
  console.log(`Shipment: ${shipment.reference}`);
  console.log(`Status: ${shipment.status}`);
  console.log(`From: ${shipment.pickupCity}, ${shipment.pickupArea}`);
  console.log(`To: ${shipment.dropOffCity}, ${shipment.dropOffArea}`);
  
  if (shipment.rider) {
    console.log(`Rider: ${shipment.rider.fullName}`);
  }
  
  if (shipment.shipmentCost) {
    console.log(`Total Cost: ${shipment.shipmentCost.totalCost}`);
    console.log(`Rider Commission: ${shipment.shipmentCost.riderCommission}`);
  }
} catch (error) {
  if (error.status === 404) {
    console.error('Shipment not found');
  } else {
    console.error('Failed to fetch shipment:', error.message);
  }
}

updateStatus

Update the status of a shipment with optional proof of delivery (image/signature).
shipmentsService.updateStatus(
  shipmentId: string, 
  data: FormData
): ApiResponse<Shipment>

Parameters

shipmentId
string
required
The unique identifier of the shipment
data
FormData
required
Form data containing status update information
data.status
string
required
New status value (e.g., “picked_up”, “in_transit”, “delivered”, “cancelled”)
data.description
string
Description or notes about the status update
data.image
File
Proof of delivery image (for delivered status)
data.signature
string
Base64 encoded signature (for delivered status)

Response

Returns the updated Shipment object with the new status reflected in the history.

Example Usage

import * as ImagePicker from 'expo-image-picker';

try {
  // Create FormData for status update
  const formData = new FormData();
  formData.append('status', 'delivered');
  formData.append('description', 'Package delivered successfully');
  
  // Add proof of delivery image
  const imageResult = await ImagePicker.launchCameraAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.Images,
    quality: 0.8,
  });
  
  if (!imageResult.canceled) {
    formData.append('image', {
      uri: imageResult.assets[0].uri,
      type: 'image/jpeg',
      name: 'proof_of_delivery.jpg',
    } as any);
  }
  
  const response = await shipmentsService.updateStatus(
    'shipment-123',
    formData
  );
  
  console.log('Status updated:', response.data.status);
  console.log('History entries:', response.data.history.length);
} catch (error) {
  console.error('Failed to update status:', error.message);
}
The updateStatus method uses multipart/form-data content type to support file uploads for proof of delivery images.

API Endpoints

MethodEndpointDescription
listGET /shippingList shipments with query params
getRiderLatestOrdersGET /shipping/riders/{riderId}/latest-ordersGet rider’s latest orders
getByReferenceGET /shipping/reference/{reference}Get shipment by reference
updateStatusPATCH /shipping/{shipmentId}/update-historyUpdate shipment status
Source: src/services/api/end-points.ts:29-41

Type Definitions

Shipment

interface Shipment {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: any;
  pickupCity: string;
  pickupArea: string;
  senderPhone: string;
  pickupDate: any;
  dropOffCity: string;
  dropOffArea: string;
  recipientPhone: string;
  dropOffDate: any;
  extraInformation: string | null;
  shipmentOption: string;
  modeOfShipment: string;
  status: string;
  reference: string;
  rider: Rider | null;
  history: ShipmentHistory[];
  shipmentCost: ShipmentCost | null;
}
Source: src/types/shipment.types.ts:9-30

ShipmentHistory

interface ShipmentHistory {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: any;
  status: string;
  description: any;
  data: Record<string, any>;
}
Source: src/types/shipment.types.ts:47-55

ShipmentCost

interface ShipmentCost {
  id: string;
  createdAt: string;
  updatedAt: string;
  deletedAt: any;
  pickupFee: number;
  deliveryFee: number;
  riderCommission: number;
  repackagingFee: number;
  paid: boolean;
  includeRepackagingFee: boolean;
  paidAt: string;
  totalCost: number;
}
Source: src/types/shipment.types.ts:32-45

GetShipmentsResponse

interface GetShipmentsResponse {
  meta: PaginationMeta;
  items: Shipment[];
}
Source: src/types/shipment.types.ts:4-7

Shipment Status Flow

Shipments typically follow this status progression:

Common Use Cases

Display Active Deliveries

const fetchActiveDeliveries = async (riderId: string) => {
  try {
    const response = await shipmentsService.list({
      riderId,
      status: 'in_transit',
      limit: 50,
    });
    
    return response.data.items;
  } catch (error) {
    console.error('Error fetching active deliveries:', error);
    return [];
  }
};

Track Shipment

const trackShipment = async (reference: string) => {
  try {
    const response = await shipmentsService.getByReference(reference);
    const shipment = response.data;
    
    return {
      status: shipment.status,
      currentLocation: shipment.rider ? 'En route' : 'Au dépôt',
      history: shipment.history.map(h => ({
        status: h.status,
        timestamp: h.createdAt,
        description: h.description,
      })),
    };
  } catch (error) {
    throw new Error('Unable to track shipment');
  }
};

Complete Delivery

const completeDelivery = async (
  shipmentId: string,
  proofImageUri: string,
  signature: string
) => {
  const formData = new FormData();
  formData.append('status', 'delivered');
  formData.append('description', 'Colis livré avec succès');
  
  // Add proof image
  formData.append('image', {
    uri: proofImageUri,
    type: 'image/jpeg',
    name: `delivery_${shipmentId}.jpg`,
  } as any);
  
  // Add signature
  formData.append('signature', signature);
  
  try {
    const response = await shipmentsService.updateStatus(shipmentId, formData);
    return response.data;
  } catch (error) {
    throw new Error('Failed to complete delivery');
  }
};

Error Handling

404 - Shipment Not Found

{
  "message": "Ressource non trouvée",
  "status": 404,
  "isApiError": true
}

422 - Validation Error

{
  "message": "Erreur de validation",
  "status": 422,
  "data": {
    "message": "Invalid status transition",
    "errors": ["Cannot transition from delivered to in_transit"]
  },
  "isApiError": true
}

Best Practices

  • Always validate status transitions before updating
  • Include descriptive notes when updating status
  • Capture proof of delivery for completed shipments
  • Use reference numbers for customer-facing tracking
  • Cache shipment lists to reduce API calls
  • Implement pull-to-refresh for real-time updates

Users Service

Manage rider stats and earnings

Services Overview

Back to services overview

Build docs developers (and LLMs) love