DClient - Order Management
Client-side order and delivery management separate from map operations.
DClient Overview
DClient provides order management functionality independent of the map interface:
- Create and manage delivery orders
- Track packages and shipments
- Manage waypoints and stops
- Real-time event subscriptions
- Customer and client operations
Works standalone or alongside MSI for complete delivery solutions.
Getting Started
typescript
import De from '@de./sdk'
// Initialize DClient
const dclient = new De.DClient({
workspace: 'your-workspace-id',
accessToken: 'your-access-token',
env: 'prod'
})
// Create order
const order = await dclient.orders.create({
type: 'delivery',
customer: {
name: 'John Doe',
phone: '+1234567890'
},
pickup: {
address: '123 Main St',
coordinates: { lng: -74.0060, lat: 40.7128 }
},
delivery: {
address: '456 Oak Ave',
coordinates: { lng: -73.9855, lat: 40.7580 }
}
})
console.log('Order created:', order.id)Order Management
Creating Orders
1
Basic Order
Simple delivery order
typescript
const order = await dclient.orders.create({
type: 'delivery',
customer: {
uid: 'user_123', // Optional: existing user ID
name: 'John Doe',
phone: '+1234567890',
email: '[email protected]'
},
pickup: {
address: '123 Main St, New York, NY',
coordinates: { lng: -74.0060, lat: 40.7128 },
contactName: 'Store Manager',
contactPhone: '+1234567891',
instructions: 'Ring doorbell'
},
delivery: {
address: '456 Oak Ave, New York, NY',
coordinates: { lng: -73.9855, lat: 40.7580 },
contactName: 'John Doe',
contactPhone: '+1234567890',
instructions: 'Leave at door',
scheduledAt: '2024-03-15T14:30:00Z'
},
items: [
{
name: 'Package A',
quantity: 1,
weight: 2.5,
value: 49.99
}
],
metadata: {
orderNumber: 'ORD-12345',
priority: 'standard'
}
})Order Types:
delivery- Standard deliverypickup- Customer pickupreturn- Return shipmentexchange- Exchange/swap
2
Multi-stop Order
Order with multiple waypoints
typescript
const order = await dclient.orders.create({
type: 'delivery',
customer: { /* ... */ },
pickup: { /* ... */ },
waypoints: [
{
type: 'pickup',
address: '789 Pine Rd',
coordinates: { lng: -73.9951, lat: 40.7489 },
instructions: 'Second pickup location'
},
{
type: 'delivery',
address: '321 Elm St',
coordinates: { lng: -73.9844, lat: 40.7614 },
instructions: 'First drop-off'
}
],
delivery: { /* Final destination */ }
})Retrieving Orders
1
Get Order by ID
Fetch specific order
typescript
const order = await dclient.orders.get('order_abc123')
console.log('Order status:', order.status)
console.log('Current location:', order.tracking?.currentLocation)
console.log('ETA:', order.tracking?.eta)2
List Orders
Query orders with filters
typescript
const orders = await dclient.orders.list({
status: 'in_transit',
limit: 20,
offset: 0,
sortBy: 'createdAt',
sortOrder: 'desc',
customerId: 'user_123'
})
console.log('Active orders:', orders.data.length)
console.log('Total:', orders.total)Filter Options:
typescript
{
status?: 'pending' | 'assigned' | 'in_transit' | 'delivered' | 'cancelled'
type?: 'delivery' | 'pickup' | 'return'
customerId?: string
agentId?: string
startDate?: string
endDate?: string
limit?: number
offset?: number
sortBy?: 'createdAt' | 'updatedAt' | 'scheduledAt'
sortOrder?: 'asc' | 'desc'
}Updating Orders
typescript
// Update order details
await dclient.orders.update('order_abc123', {
delivery: {
...existingDelivery,
instructions: 'Updated: Call on arrival'
},
metadata: {
...existingMetadata,
priority: 'urgent'
}
})
// Update status
await dclient.orders.updateStatus('order_abc123', 'in_transit')
// Assign agent
await dclient.orders.assign('order_abc123', 'agent_xyz789')Cancelling Orders
typescript
await dclient.orders.cancel('order_abc123', {
reason: 'customer_request',
notes: 'Customer changed plans'
})Package Management
Adding Packages
1
Add Package to Order
Attach package details
typescript
const package = await dclient.packages.add('order_abc123', {
trackingNumber: 'PKG-123456',
weight: 5.0,
dimensions: {
length: 30,
width: 20,
height: 15
},
contents: 'Electronics',
value: 299.99,
fragile: true,
requiresSignature: true
})Tracking Packages
typescript
// Get package status
const package = await dclient.packages.get('pkg_abc123')
console.log('Status:', package.status)
console.log('Location:', package.currentLocation)
console.log('Last scan:', package.lastScan)
// Get package history
const history = await dclient.packages.getHistory('pkg_abc123')
history.forEach(event => {
console.log(`${event.timestamp}: ${event.type} at ${event.location}`)
})Waypoint Operations
Managing Waypoints
1
Add Waypoint
Add stop to existing order
typescript
const waypoint = await dclient.waypoints.add('order_abc123', {
type: 'delivery',
address: '999 Broadway',
coordinates: { lng: -73.9712, lat: 40.7831 },
contactName: 'Jane Smith',
contactPhone: '+1234567892',
instructions: 'Apartment 5B',
order: 2 // Position in route
})2
Update Waypoint
Modify waypoint details
typescript
await dclient.waypoints.update('waypoint_xyz', {
status: 'completed',
completedAt: new Date().toISOString(),
notes: 'Successfully delivered'
})3
Reorder Waypoints
Change waypoint sequence
typescript
await dclient.waypoints.reorder('order_abc123', [
'waypoint_1',
'waypoint_3', // Swap order
'waypoint_2'
])Waypoint Status
typescript
// Complete waypoint
await dclient.waypoints.complete('waypoint_xyz', {
completedAt: new Date().toISOString(),
signature: signatureData,
photo: photoData,
notes: 'Delivered to resident'
})
// Skip waypoint
await dclient.waypoints.skip('waypoint_xyz', {
reason: 'customer_unavailable',
notes: 'No answer at door'
})
// Remove waypoint
await dclient.waypoints.remove('waypoint_xyz')Order Services & Operators
Service Configuration
1
Configure Service Options
Set delivery service parameters
typescript
const order = await dclient.orders.create({
// ... order details
service: {
type: 'express', // 'standard' | 'express' | 'same_day'
priority: 'high', // 'low' | 'normal' | 'high'
insuranceValue: 500, // Insurance coverage
requiresSignature: true,
contactlessDelivery: false,
ageVerification: false
}
})Operator Selection
typescript
// Assign to specific operator/LSP
await dclient.orders.assignOperator('order_abc123', {
operatorId: 'lsp_xyz789',
vehicleType: 'van',
specialRequirements: ['refrigerated']
})
// Auto-assign based on rules
await dclient.orders.autoAssign('order_abc123', {
preferredOperator: 'lsp_xyz789',
maxDistance: 50, // km from operator
vehicleTypes: ['van', 'truck']
})Order Lifecycle & Stages
Lifecycle Stages
typescript
// Order lifecycle
const lifecycle = {
created: 'Order created',
assigned: 'Agent assigned',
accepted: 'Agent accepted',
picking_up: 'Heading to pickup',
picked_up: 'Package collected',
in_transit: 'On the way to delivery',
nearby: 'Arriving soon',
delivered: 'Successfully delivered',
cancelled: 'Order cancelled'
}
// Track stage transitions
dclient.on('order:stage_changed', (data) => {
console.log(`Order ${data.orderId} moved to: ${data.stage}`)
updateUI(data)
})Intent Tokens & Routing
typescript
// Generate intent token for order tracking
const intent = await dclient.intents.create('order_abc123', {
type: 'tracking',
expiresIn: 86400, // 24 hours
permissions: ['view', 'location']
})
// Share tracking link
const trackingUrl = `https://track.example.com/${intent.token}`
sendToCustomer(trackingUrl)
// Validate and use intent
const order = await dclient.intents.resolve(intentToken)Event System
Subscribing to Events
1
Order Events
Real-time order updates
typescript
// Subscribe to specific order
dclient.on('order:order_abc123', (update) => {
console.log('Order updated:', update)
switch(update.type) {
case 'status_changed':
updateOrderStatus(update.status)
break
case 'location_updated':
updateMapMarker(update.location)
break
case 'eta_changed':
updateETA(update.eta)
break
}
})2
Global Events
All orders monitoring
typescript
// All order events
dclient.on('order:*', (event) => {
console.log('Order event:', event.type, event.orderId)
})
// Specific event types
dclient.on('order:created', (order) => {
notifyNewOrder(order)
})
dclient.on('order:delivered', (order) => {
sendDeliveryNotification(order)
})Event Filtering
typescript
// Filter events by criteria
dclient.events.filter({
customerId: 'user_123',
status: 'in_transit',
types: ['location_updated', 'eta_changed']
}, (event) => {
// Only receive filtered events
handleEvent(event)
})Unsubscribing
typescript
const handler = (order) => {
console.log('Order updated:', order)
}
// Subscribe
dclient.on('order:abc123', handler)
// Unsubscribe
dclient.off('order:abc123', handler)
// Remove all listeners for order
dclient.removeAllListeners('order:abc123')Client Operations
Customer Management
typescript
// Create customer profile
const customer = await dclient.customers.create({
name: 'John Doe',
phone: '+1234567890',
email: '[email protected]',
addresses: [
{
label: 'Home',
address: '123 Main St',
coordinates: { lng: -74.0060, lat: 40.7128 },
default: true
},
{
label: 'Work',
address: '456 Office Blvd',
coordinates: { lng: -73.9855, lat: 40.7580 }
}
],
preferences: {
contactlessDelivery: true,
notifications: {
sms: true,
email: true,
push: false
}
}
})
// Update customer
await dclient.customers.update('customer_123', {
preferences: {
notifications: {
sms: false,
email: true,
push: true
}
}
})
// Get customer orders
const customerOrders = await dclient.customers.getOrders('customer_123', {
status: 'delivered',
limit: 10
})Preference Management
typescript
// Set delivery preferences
await dclient.preferences.set('customer_123', {
deliveryWindow: {
start: '09:00',
end: '17:00'
},
preferredCarrier: 'lsp_xyz',
contactlessDelivery: true,
leaveAtDoor: true,
safePlace: 'Front porch',
specialInstructions: 'Ring doorbell twice'
})
// Get preferences
const prefs = await dclient.preferences.get('customer_123')Complete Examples
E-commerce Checkout Integration
typescript
async function createDeliveryOrder(cartItems, deliveryAddress) {
const dclient = new De.DClient({
workspace: workspaceId,
accessToken: token
})
// Create order from cart
const order = await dclient.orders.create({
type: 'delivery',
customer: {
uid: currentUser.id,
name: currentUser.name,
phone: currentUser.phone,
email: currentUser.email
},
pickup: {
address: warehouse.address,
coordinates: warehouse.coordinates,
contactName: 'Warehouse Manager',
contactPhone: warehouse.phone
},
delivery: {
address: deliveryAddress.formatted,
coordinates: deliveryAddress.coordinates,
contactName: currentUser.name,
contactPhone: currentUser.phone,
scheduledAt: selectedDeliverySlot,
instructions: deliveryNotes
},
items: cartItems.map(item => ({
name: item.name,
quantity: item.quantity,
weight: item.weight,
value: item.price
})),
service: {
type: deliverySpeed, // 'express' or 'standard'
insuranceValue: calculateInsurance(cartItems),
requiresSignature: totalValue > 100
},
metadata: {
cartId: cart.id,
orderNumber: generateOrderNumber(),
paymentId: payment.id
}
})
// Track order
trackOrder(order.id)
return order
}
function trackOrder(orderId) {
dclient.on(`order:${orderId}`, (update) => {
switch(update.type) {
case 'status_changed':
updateOrderStatus(update.status)
sendNotification(`Order ${update.status}`)
break
case 'agent_assigned':
showDriverInfo(update.agent)
break
case 'location_updated':
updateTrackingMap(update.location)
break
case 'eta_changed':
updateDeliveryETA(update.eta)
break
}
})
}Delivery Driver App
typescript
class DriverApp {
private dclient: any
private currentOrders: Map<string, any> = new Map()
async initialize(driverId: string) {
this.dclient = new De.DClient({
workspace: workspaceId,
accessToken: driverToken
})
// Get assigned orders
await this.loadOrders(driverId)
// Subscribe to new assignments
this.dclient.on('order:assigned', (order) => {
if (order.agent.uid === driverId) {
this.handleNewOrder(order)
}
})
}
async loadOrders(driverId: string) {
const orders = await this.dclient.orders.list({
agentId: driverId,
status: ['assigned', 'in_transit'],
sortBy: 'scheduledAt'
})
orders.data.forEach(order => {
this.currentOrders.set(order.id, order)
})
this.updateRoute()
}
async acceptOrder(orderId: string) {
await this.dclient.orders.updateStatus(orderId, 'accepted')
const order = this.currentOrders.get(orderId)
navigateToPickup(order.pickup.coordinates)
}
async completePickup(orderId: string) {
await this.dclient.waypoints.complete(
`${orderId}_pickup`,
{
completedAt: new Date().toISOString(),
photo: await capturePhoto()
}
)
await this.dclient.orders.updateStatus(orderId, 'picked_up')
const order = this.currentOrders.get(orderId)
navigateToDelivery(order.delivery.coordinates)
}
async completeDelivery(orderId: string) {
const signature = await getSignature()
const photo = await capturePhoto()
await this.dclient.waypoints.complete(
`${orderId}_delivery`,
{
completedAt: new Date().toISOString(),
signature,
photo,
notes: deliveryNotes
}
)
await this.dclient.orders.updateStatus(orderId, 'delivered')
this.currentOrders.delete(orderId)
showCompletionScreen()
}
private updateRoute() {
const stops = Array.from(this.currentOrders.values())
.flatMap(order => [order.pickup, order.delivery])
optimizeRoute(stops)
}
}Type Definitions
typescript
interface Order {
id: string
type: 'delivery' | 'pickup' | 'return' | 'exchange'
status: 'pending' | 'assigned' | 'in_transit' | 'delivered' | 'cancelled'
customer: Customer
pickup: Location
delivery: Location
waypoints?: Waypoint[]
items: Item[]
agent?: Agent
tracking?: {
currentLocation?: Coordinates
eta?: string
events: TrackingEvent[]
}
service?: ServiceOptions
pricing?: Pricing
metadata?: Record<string, any>
createdAt: string
updatedAt: string
}
interface Customer {
uid?: string
name: string
phone: string
email?: string
}
interface Location {
address: string
coordinates: Coordinates
contactName?: string
contactPhone?: string
instructions?: string
scheduledAt?: string
}
interface Item {
name: string
quantity: number
weight?: number
dimensions?: Dimensions
value?: number
}Best Practices
Do
- Validate data before creating orders
- Handle event subscriptions properly
- Clean up listeners when done
- Use metadata for custom fields
- Implement retry logic for API calls
- Cache frequently accessed data
Avoid
- Creating duplicate orders
- Storing sensitive data in metadata
- Ignoring error responses
- Over-polling for updates
- Hardcoding credentials
- Leaking event listeners

