Skip to main content

Overview

Orders Admin API provides comprehensive order management tools for platform administrators. Includes order listing with filtering, status management, revenue analytics, store performance rankings, and bulk delete operations. All functions require admin authorization. Location: convex/admins/ordersAdmin.ts

Get All Orders

Fetches all orders with filtering and cursor-based pagination. Orders are returned newest first, enriched with customer name, store name, and item count. Supports filtering by status, store, customer, date range, and text search (searches customer name, store name, and order ID).
status
string
Filter by order status: pending, preparing, ready, out_for_delivery, delivered, cancelled
storeId
Id<'stores'>
Filter orders by store. Uses the by_store index for efficient lookup.
customerId
Id<'customers'>
Filter orders by customer
searchQuery
string
Text search across customer name, store name, and order ID (case-insensitive)
startDate
number
Filter orders created on or after this timestamp (milliseconds)
endDate
number
Filter orders created on or before this timestamp (milliseconds)
paginationOpts
PaginationOptions
required
Pagination options (numItems, cursor)
const orders = await convex.query(api.admins.ordersAdmin.getAllOrders, {
  paginationOpts: { numItems: 20, cursor: null },
  status: "pending",
  searchQuery: "Pizza"
});
{
  "page": [
    {
      "_id": "o123456789",
      "_creationTime": 1700000000000,
      "status": "pending",
      "totalAmount": 125.50,
      "customerId": "c111",
      "storeId": "s222",
      "customerName": "Ahmed Ali",
      "storeName": "Pizza Palace",
      "itemsCount": 3,
      "orderItems": [...]
    }
  ],
  "continueCursor": "abc123",
  "isDone": false
}

Get Store Orders

Fetches orders for a specific store with pagination. Returns enriched orders with customer name, phone number, and item count, plus the store name and total order count.
storeId
Id<'stores'>
required
Store ID to fetch orders for
status
string
Filter by order status: pending, preparing, ready, out_for_delivery, delivered, cancelled
paginationOpts
PaginationOptions
required
Pagination options (numItems, cursor)
const storeOrders = await convex.query(api.admins.ordersAdmin.getStoreOrders, {
  storeId: "s222",
  status: "delivered",
  paginationOpts: { numItems: 20, cursor: null }
});
{
  "page": [
    {
      "_id": "o123456789",
      "_creationTime": 1700000000000,
      "status": "delivered",
      "totalAmount": 85.00,
      "customerName": "Ahmed Ali",
      "customerPhone": "+971501234567",
      "itemsCount": 2
    }
  ],
  "continueCursor": "abc123",
  "isDone": true,
  "storeName": "Pizza Palace",
  "totalOrders": 156
}

Get Order Status Counts

Returns live order counts grouped by status. Used for dashboard cards showing per-status totals. No arguments required.
const counts = await convex.query(api.admins.ordersAdmin.getOrderStatusCounts, {});
{
  "pending": 12,
  "preparing": 8,
  "ready": 5,
  "out_for_delivery": 15,
  "delivered": 1240,
  "cancelled": 42,
  "total": 1322
}

Get Order Statistics

Returns order statistics from the pre-computed adminOrderStats aggregate table. Supports daily or all-time views.
date
string
Date in YYYY-MM-DD format for daily stats. Omit for all-time statistics.
// All-time stats
const allTime = await convex.query(api.admins.ordersAdmin.getOrderStatistics, {});

// Daily stats
const daily = await convex.query(api.admins.ordersAdmin.getOrderStatistics, {
  date: "2026-03-09"
});
{
  "totalOrders": 1322,
  "completedOrders": 1240,
  "cancelledOrders": 42,
  "totalRevenue": 156000.50,
  "averageOrderValue": 125.81,
  "lastUpdated": 1700000000000
}
When no stats exist for the requested date, all values return as zero. The averageOrderValue is calculated as totalRevenue / completedOrders.

Get Order Details

Fetches full details for a single order, including enriched customer info, store info, order items, and status history timeline.
orderId
Id<'orders'>
required
Order ID to retrieve
const details = await convex.query(api.admins.ordersAdmin.getOrderDetails, {
  orderId: "o123456789"
});
{
  "_id": "o123456789",
  "_creationTime": 1700000000000,
  "status": "delivered",
  "totalAmount": 125.50,
  "customer": {
    "_id": "c111",
    "name": "Ahmed Ali",
    "email": "ahmed@example.com",
    "phoneNumber": "+971501234567"
  },
  "store": {
    "_id": "s222",
    "name": "Pizza Palace",
    "phoneNumber": "+971509876543"
  },
  "enrichedItems": [...],
  "statusHistory": [
    {
      "_id": "h111",
      "_creationTime": 1700000000000,
      "orderId": "o123456789",
      "previousStatus": "pending",
      "newStatus": "preparing",
      "changedBy": { "userId": "u111", "userType": "store", "userName": "Store Owner" },
      "notes": "Order accepted"
    }
  ]
}
Status history is sorted chronologically (oldest first). Order items already contain productName and productImage from the original order.

Update Order Status

Admin override to update an order’s status. Records the change in the orderStatusHistory table with the admin marked as a system user type.
orderId
Id<'orders'>
required
Order ID to update
status
string
required
New status: pending, preparing, ready, out_for_delivery, delivered, cancelled
adminNotes
string
Optional notes explaining the status change. Defaults to a generated message.
await convex.mutation(api.admins.ordersAdmin.updateOrderStatus, {
  orderId: "o123456789",
  status: "cancelled",
  adminNotes: "Customer requested cancellation via support"
});
null

Get Revenue Analytics

Returns revenue analytics grouped by time period. Only counts delivered (completed) orders.
startDate
number
required
Start of date range (timestamp in milliseconds)
endDate
number
required
End of date range (timestamp in milliseconds)
groupBy
string
Grouping period: day, week, or month. Defaults to day.
const revenue = await convex.query(api.admins.ordersAdmin.getRevenueAnalytics, {
  startDate: 1700000000000,
  endDate: 1702600000000,
  groupBy: "week"
});
[
  {
    "period": "2024-11-12",
    "totalOrders": 85,
    "totalRevenue": 10625.00,
    "averageOrderValue": 125.00
  },
  {
    "period": "2024-11-19",
    "totalOrders": 92,
    "totalRevenue": 11500.00,
    "averageOrderValue": 125.00
  }
]
For week grouping, the period key is the Sunday (start of week) date. For month grouping, the format is YYYY-MM. Results are sorted chronologically.

Get Top Stores By Orders

Returns the top performing stores ranked by number of completed (delivered) orders, with revenue metrics.
limit
number
Maximum number of stores to return. Defaults to 10.
startDate
number
Filter orders created on or after this timestamp (milliseconds)
endDate
number
Filter orders created on or before this timestamp (milliseconds)
const topStores = await convex.query(api.admins.ordersAdmin.getTopStoresByOrders, {
  limit: 5,
  startDate: 1700000000000,
  endDate: 1702600000000
});
[
  {
    "storeId": "s222",
    "storeName": "Pizza Palace",
    "totalOrders": 320,
    "totalRevenue": 40000.00,
    "averageOrderValue": 125.00
  },
  {
    "storeId": "s333",
    "storeName": "Burger Hub",
    "totalOrders": 280,
    "totalRevenue": 33600.00,
    "averageOrderValue": 120.00
  }
]

Bulk Delete Orders

Permanently deletes multiple orders and their associated status history records. Processes in batches of 50 using internal mutations.
orderIds
Id<'orders'>[]
required
Array of order IDs to delete
const result = await convex.action(api.admins.ordersAdmin.bulkDeleteOrders, {
  orderIds: ["o111", "o222", "o333"]
});
{
  "ordersDeleted": 3,
  "historyDeleted": 12
}
This is a Convex action that delegates to internal mutations in batches of 50. Each order’s status history entries from orderStatusHistory are deleted before the order itself. Returns zero counts if an empty array is passed.