Delivery

Armada

Armada last-mile delivery provider — estimation, dispatch, tracking, and webhooks.

The @commercejs/delivery-armada package implements the DeliveryProvider interface for Armada, a last-mile delivery platform popular in the MENA region.

Installation

pnpm add @commercejs/delivery-armada

Quick Start

import { ArmadaDeliveryProvider } from '@commercejs/delivery-armada'

const armada = new ArmadaDeliveryProvider({
  accessToken: process.env.ARMADA_ACCESS_TOKEN!,
})

// Estimate delivery fee
const estimate = await armada.estimate({
  origin: {
    contactName: 'Store',
    contactPhone: '+966500000000',
    firstLine: 'Olaya St, Riyadh',
    latitude: 24.7136,
    longitude: 46.6753,
  },
  destination: {
    contactName: 'Customer',
    contactPhone: '+966512345678',
    firstLine: 'King Fahd Rd, Riyadh',
    latitude: 24.7743,
    longitude: 46.7386,
  },
})

Configuration

OptionTypeRequiredDescription
accessTokenstringArmada API access token
baseUrlstringAPI base URL (default: https://api.armadadelivery.com/v1)
fetchFntypeof fetchCustom fetch function for testing

Methods

All methods follow the DeliveryProvider interface from @commercejs/types.

estimate

Estimates the delivery fee between two points:

const estimate = await armada.estimate({
  origin: { latitude: 24.7136, longitude: 46.6753 },
  destination: { latitude: 24.7743, longitude: 46.7386 },
})

console.log(estimate.fee)              // 12.5
console.log(estimate.currency)         // 'SAR'
console.log(estimate.estimatedDuration) // 25 (minutes)

Armada supports two origin formats:

  • Branch origin — pass { branchId: 'branch_123' } to use a pre-configured branch
  • Location origin — pass { latitude, longitude } for ad-hoc pickup points

createDelivery

Creates a new delivery order:

const delivery = await armada.createDelivery({
  origin: {
    contactName: 'Shop Manager',
    contactPhone: '+966500000000',
    firstLine: 'King Abdullah Road',
    latitude: 24.7136,
    longitude: 46.6753,
  },
  destination: {
    contactName: 'Ahmed',
    contactPhone: '+966512345678',
    firstLine: 'Al Malqa District',
    latitude: 24.8021,
    longitude: 46.6271,
    instructions: 'Ring the bell twice',
  },
  orderId: 'order_123',
})

getDelivery

Retrieves the current state of a delivery:

const delivery = await armada.getDelivery('DEL-ABC123')
console.log(delivery.status) // 'in_transit'
console.log(delivery.driver) // { name: 'Mohammed', phone: '...', latitude: ..., longitude: ... }

cancelDelivery

Cancels an active delivery:

const cancelled = await armada.cancelDelivery('DEL-ABC123')
console.log(cancelled.status) // 'cancelled'

Status Mapping

Armada statuses are normalized to the DeliveryStatus union:

Armada StatusDeliveryStatus
pendingpending
dispatchedassigned
waiting_packpickup
en_routein_transit
completeddelivered
canceledcancelled
failedfailed

Webhook Verification

Armada sends webhooks for delivery status changes. The verifyWebhook method parses the payload using the x-armada-webhook-topic header:

const event = await armada.verifyWebhook(
  request.body,                               // raw body
  request.headers['x-armada-webhook-topic'],   // topic header as signature
)

console.log(event.type)       // 'delivery.updated' | 'delivery.location'
console.log(event.deliveryId) // 'DEL-ABC123'
console.log(event.status)     // 'delivered'
console.log(event.location)   // { latitude: 24.73, longitude: 46.69 }

Webhook Topics

TopicEvent Type
order.updateddelivery.updated
order.location.updateddelivery.location

Using with the Orchestrator

import { createCommerce } from '@commercejs/core'
import { ArmadaDeliveryProvider } from '@commercejs/delivery-armada'

const commerce = createCommerce({
  adapter,
  delivery: {
    armada: new ArmadaDeliveryProvider({
      accessToken: process.env.ARMADA_ACCESS_TOKEN!,
    }),
  },
  defaultDelivery: 'armada',
})