Skip to main content

Order Management

Author: Josh S. Sakweli, Backend Lead Team Last Updated: 2025-10-25 Version: v1.0

Base URL: api/v1/e-commerce/orders

Short Description: The Order Management API handles the complete order lifecycle for the NextGate e-commerce platform. It supports multiple purchase types, order tracking, shipping management, delivery confirmation with 6-digit codes, escrow integration, and digital product downloads.

Hints:

  • All endpoints require Bearer token authentication
  • Order sources: DIRECT_PURCHASE, CART_PURCHASE, DIGITAL_PURCHASE, INSTALLMENT, GROUP_PURCHASE
  • Delivery confirmation uses a 6-digit code (SHA-256 hashed with salt, expires in 30 days, max 5 attempts)
  • Digital orders have deliveryStatus: NOT_APPLICABLE
  • Confirm-delivery response is returned directly (not wrapped in the standard response envelope)

Endpoints

1. Get Order by ID

Purpose: Retrieve detailed information about a specific order.

Endpoint: GET {base}/{orderId}

Access Level: 🔒 Protected (Buyer or Seller only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
orderId UUID Yes Unique identifier of the order

Response JSON Sample:

{
  "success": true,
  "message": "Order retrieved successfully",
  "data": {
    "orderId": "550e8400-e29b-41d4-a716-446655440000",
    "orderNumber": "ORD-2025-12345",
    "buyer": {
      "accountId": "123e4567-e89b-12d3-a456-426614174000",
      "userName": "johndoe",
      "email": "john@example.com",
      "firstName": "John",
      "lastName": "Doe"
    },
    "seller": {
      "shopId": "789e0123-e45b-67d8-a901-234567890abc",
      "shopName": "TechStore",
      "shopLogo": "https://cdn.example.com/shops/techstore.png",
      "shopSlug": "techstore"
    },
    "productOrderStatus": "SHIPPED",
    "deliveryStatus": "IN_TRANSIT",
    "productOrderSource": "DIRECT_PURCHASE",
    "items": [
      {
        "orderItemId": "111e2222-e33b-44d5-a666-777788889999",
        "productId": "abc12345-def6-7890-ghij-klmnopqrstuv",
        "productName": "Wireless Headphones",
        "productSlug": "wireless-headphones",
        "productImage": "https://cdn.example.com/products/headphones.jpg",
        "quantity": 2,
        "unitPrice": 85000.00,
        "subtotal": 170000.00,
        "tax": 0.00,
        "total": 170000.00
      }
    ],
    "subtotal": 170000.00,
    "shippingFee": 5000.00,
    "tax": 0.00,
    "totalAmount": 175000.00,
    "platformFee": 8750.00,
    "sellerAmount": 166250.00,
    "currency": "TZS",
    "paymentMethod": "MPESA",
    "amountPaid": 175000.00,
    "amountRemaining": 0.00,
    "deliveryAddress": "123 Main St, Dar es Salaam, Tanzania",
    "trackingNumber": "TRACK-550E8400",
    "carrier": "NextGate Shipping",
    "isDeliveryConfirmed": false,
    "deliveryConfirmedAt": null,
    "orderedAt": "2025-10-20T14:30:00",
    "shippedAt": "2025-10-21T09:15:00",
    "deliveredAt": null,
    "cancelledAt": null,
    "cancellationReason": null
  }
}

Response Fields:

Field Description
orderId Unique identifier of the order
orderNumber Human-readable order number
buyer Buyer account info (accountId, userName, email, firstName, lastName)
seller Shop info (shopId, shopName, shopLogo, shopSlug)
productOrderStatus PENDING_PAYMENT, PENDING_SHIPMENT, SHIPPED, DELIVERED, COMPLETED, CANCELLED, REFUNDED
deliveryStatus PENDING, SHIPPED, IN_TRANSIT, DELIVERED, CONFIRMED, NOT_APPLICABLE
productOrderSource DIRECT_PURCHASE, CART_PURCHASE, DIGITAL_PURCHASE, INSTALLMENT, GROUP_PURCHASE
items Array of order items (orderItemId, productId, productName, productSlug, productImage, quantity, unitPrice, subtotal, tax, total)
subtotal Sum of all item totals before shipping and tax
shippingFee Shipping cost
tax Tax amount
totalAmount Final amount (subtotal + shipping + tax)
platformFee Platform commission
sellerAmount Amount seller receives after platform fee
currency Currency code (TZS)
paymentMethod Payment method used
amountPaid Amount already paid
amountRemaining Remaining balance (installment orders)
deliveryAddress Shipping address
trackingNumber Shipping tracking number (null until shipped)
carrier Shipping carrier (null until shipped)
isDeliveryConfirmed Whether buyer confirmed delivery
deliveryConfirmedAt Timestamp of delivery confirmation (null if not confirmed)
orderedAt Order creation timestamp
shippedAt Shipping timestamp (null until shipped)
deliveredAt Delivery timestamp (null until delivered)
cancelledAt Cancellation timestamp (null if not cancelled)
cancellationReason Reason for cancellation (null if not cancelled)

Error Responses:

  • 400 Bad Request: Access denied — user is not buyer or seller of this order
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Order not found

2. Get Order by Order Number

Purpose: Retrieve order details using the human-readable order number.

Endpoint: GET {base}/number/{orderNumber}

Access Level: 🔒 Protected (Buyer or Seller only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
orderNumber string Yes Human-readable order number (e.g. ORD-2025-12345)

Response: Same structure as Get Order by ID.

Error Responses:

  • 400 Bad Request: Access denied — user is not buyer or seller of this order
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Order not found

3. Get My Orders

Purpose: Retrieve all orders for the authenticated customer.

Endpoint: GET {base}/my-orders

Access Level: 🔒 Protected (Customer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Response JSON Sample:

{
  "success": true,
  "message": "Orders retrieved successfully",
  "data": [ ...array of order objects (same structure as endpoint 1)... ]
}

Error Responses:

  • 401 Unauthorized: Authentication required
  • 404 Not Found: User account not found

4. Get My Orders by Status

Purpose: Retrieve customer orders filtered by order status.

Endpoint: GET {base}/my-orders/status/{status}

Access Level: 🔒 Protected (Customer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
status enum Yes PENDING_PAYMENT, PENDING_SHIPMENT, SHIPPED, DELIVERED, COMPLETED, CANCELLED, REFUNDED

Response: Array of order objects (same structure as endpoint 1).

Error Responses:

  • 400 Bad Request: Invalid status value
  • 401 Unauthorized: Authentication required
  • 404 Not Found: User account not found

5. Get My Orders (Paginated)

Purpose: Retrieve customer orders with pagination.

Endpoint: GET {base}/my-orders/paged

Access Level: 🔒 Protected (Customer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Query Parameters:

Parameter Type Required Default Description
page integer No 1 Page number (1-based)
size integer No 10 Number of items per page

Response JSON Sample:

{
  "success": true,
  "message": "Orders retrieved successfully",
  "data": {
    "orders": [ "...order objects (same structure as endpoint 1)..." ],
    "currentPage": 1,
    "pageSize": 10,
    "totalElements": 25,
    "totalPages": 3,
    "hasNext": true,
    "hasPrevious": false,
    "isFirst": true,
    "isLast": false
  }
}

Error Responses:

  • 401 Unauthorized: Authentication required
  • 404 Not Found: User account not found

6. Get My Orders by Status (Paginated)

Purpose: Retrieve customer orders filtered by status with pagination.

Endpoint: GET {base}/my-orders/status/{status}/paged

Access Level: 🔒 Protected (Customer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
status enum Yes PENDING_PAYMENT, PENDING_SHIPMENT, SHIPPED, DELIVERED, COMPLETED, CANCELLED, REFUNDED

Query Parameters:

Parameter Type Required Default Description
page integer No 1 Page number (1-based)
size integer No 10 Number of items per page

Response: Same paginated structure as endpoint 5.

Error Responses:

  • 400 Bad Request: Invalid status value
  • 401 Unauthorized: Authentication required
  • 404 Not Found: User account not found

7. Get Shop Orders

Purpose: Retrieve all orders for a specific shop.

Endpoint: GET {base}/shop/{shopId}/orders

Access Level: 🔒 Protected (Shop Owner only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
shopId UUID Yes Unique identifier of the shop

Response: Array of order objects (same structure as endpoint 1).

Error Responses:

  • 400 Bad Request: User is not the owner of this shop
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Shop not found

8. Get Shop Orders by Status

Purpose: Retrieve shop orders filtered by order status.

Endpoint: GET {base}/shop/{shopId}/orders/status/{status}

Access Level: 🔒 Protected (Shop Owner only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
shopId UUID Yes Unique identifier of the shop
status enum Yes PENDING_PAYMENT, PENDING_SHIPMENT, SHIPPED, DELIVERED, COMPLETED, CANCELLED, REFUNDED

Response: Array of order objects (same structure as endpoint 1).

Error Responses:

  • 400 Bad Request: Invalid status value or user is not shop owner
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Shop not found

9. Get Shop Orders (Paginated)

Purpose: Retrieve shop orders with pagination.

Endpoint: GET {base}/shop/{shopId}/orders/paged

Access Level: 🔒 Protected (Shop Owner only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
shopId UUID Yes Unique identifier of the shop

Query Parameters:

Parameter Type Required Default Description
page integer No 1 Page number (1-based)
size integer No 10 Number of items per page

Response: Same paginated structure as endpoint 5.

Error Responses:

  • 400 Bad Request: User is not the owner of this shop
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Shop not found

10. Get Shop Orders by Status (Paginated)

Purpose: Retrieve shop orders filtered by status with pagination.

Endpoint: GET {base}/shop/{shopId}/orders/status/{status}/paged

Access Level: 🔒 Protected (Shop Owner only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
shopId UUID Yes Unique identifier of the shop
status enum Yes PENDING_PAYMENT, PENDING_SHIPMENT, SHIPPED, DELIVERED, COMPLETED, CANCELLED, REFUNDED

Query Parameters:

Parameter Type Required Default Description
page integer No 1 Page number (1-based)
size integer No 10 Number of items per page

Response: Same paginated structure as endpoint 5.

Error Responses:

  • 400 Bad Request: Invalid status value or user is not shop owner
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Shop not found

11. Mark Order as Shipped

Purpose: Seller marks an order as shipped. Generates a delivery confirmation code and sends it to the buyer.

Endpoint: POST {base}/{orderId}/ship

Access Level: 🔒 Protected (Shop Owner/Seller only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
orderId UUID Yes Unique identifier of the order

Response JSON Sample:

{
  "success": true,
  "message": "Order marked as shipped",
  "data": {
    "orderId": "550e8400-e29b-41d4-a716-446655440000",
    "orderNumber": "ORD-2025-12345",
    "shippedAt": "2025-10-25T10:30:45",
    "message": "Order marked as shipped. Confirmation code sent to customer.",
    "confirmationCodeSent": true,
    "codeExpiresAt": "2025-11-24T10:30:45",
    "maxVerificationAttempts": 5
  }
}

Response Fields:

Field Description
orderId UUID of the shipped order
orderNumber Human-readable order number
shippedAt Timestamp when order was marked as shipped
message Confirmation message
confirmationCodeSent Whether confirmation code was sent to customer
codeExpiresAt When the confirmation code expires (30 days from generation)
maxVerificationAttempts Maximum number of code verification attempts allowed

Error Responses:

  • 400 Bad Request: Order status is not PENDING_SHIPMENT, or user is not the seller
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Order not found

12. Confirm Delivery

Purpose: Customer confirms order delivery using the 6-digit confirmation code. Releases escrow to seller.

Endpoint: POST {base}/{orderId}/confirm-delivery

Access Level: 🔒 Protected (Buyer/Customer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication
User-Agent string No Device info for verification tracking
X-Forwarded-For string No Client IP address (if behind proxy)
X-Real-IP string No Real client IP address

Path Parameters:

Parameter Type Required Description
orderId UUID Yes Unique identifier of the order

Request JSON Sample:

{
  "confirmationCode": "123456"
}

Request Body Parameters:

Parameter Type Required Description Validation
confirmationCode string Yes 6-digit delivery confirmation code Exactly 6 digits (0-9)

Response JSON Sample:

{
  "orderId": "550e8400-e29b-41d4-a716-446655440000",
  "orderNumber": "ORD-2025-12345",
  "deliveredAt": "2025-10-25T10:30:45",
  "confirmedAt": "2025-10-25T10:30:45",
  "escrowReleased": true,
  "sellerAmount": 166250.00,
  "currency": "TZS",
  "message": "Delivery confirmed successfully. Order completed!"
}

Note: This response is returned directly without the standard success envelope.

Response Fields:

Field Description
orderId UUID of the confirmed order
orderNumber Human-readable order number
deliveredAt Timestamp when order was marked as delivered
confirmedAt Timestamp when delivery was confirmed
escrowReleased Whether escrow funds were released to seller
sellerAmount Amount released to seller after platform fee
currency Currency code
message Confirmation message

Error Responses:

  • 400 Bad Request: Invalid confirmation code, order not SHIPPED, user is not buyer, max attempts exceeded, code expired, or escrow already released
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Order not found or no active confirmation code
  • 422 Unprocessable Entity: Confirmation code format invalid

13. Regenerate Confirmation Code

Purpose: Customer requests a new delivery confirmation code if the previous one was lost or expired.

Endpoint: POST {base}/{orderId}/regenerate-code

Access Level: 🔒 Protected (Buyer/Customer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
orderId UUID Yes Unique identifier of the order

Response JSON Sample:

{
  "success": true,
  "message": "Confirmation code regenerated successfully",
  "data": {
    "orderId": "550e8400-e29b-41d4-a716-446655440000",
    "orderNumber": "ORD-2025-12345",
    "codeSent": true,
    "destination": "email",
    "codeExpiresAt": "2025-11-24T10:30:45",
    "maxAttempts": 5,
    "message": "New confirmation code sent to your email"
  }
}

Response Fields:

Field Description
orderId UUID of the order
orderNumber Human-readable order number
codeSent Whether new code was successfully sent
destination Where the code was sent (email)
codeExpiresAt When the new code expires (30 days from generation)
maxAttempts Maximum number of verification attempts allowed
message Confirmation message

Error Responses:

  • 400 Bad Request: Order status is not SHIPPED, user is not the buyer, or delivery already confirmed
  • 401 Unauthorized: Authentication required
  • 404 Not Found: Order not found

14. Get Digital Download URL

Purpose: Generates a presigned download URL for a digital file linked to an order. The URL expires in 5 minutes.

Endpoint: GET {base}/{orderId}/downloads/{fileId}

Access Level: 🔒 Protected (Buyer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description
orderId UUID Yes Unique identifier of the order
fileId UUID Yes Unique identifier of the digital file

Response JSON Sample:

{
  "success": true,
  "message": "Download URL generated — link expires in 5 minutes",
  "data": {
    "fileId": "abc12345-def6-7890-ghij-klmnopqrstuv",
    "fileName": "course-material.pdf",
    "downloadUrl": "https://storage.example.com/files/...",
    "expiresAt": "2025-10-25T10:35:45",
    "downloadsRemaining": 3,
    "downloadCount": 2
  }
}

Response Fields:

Field Description
fileId Unique identifier of the digital file
fileName Name of the file
downloadUrl Presigned URL for downloading the file (expires in 5 minutes)
expiresAt Timestamp when the download URL expires
downloadsRemaining Number of downloads remaining for this buyer
downloadCount Number of times this file has been downloaded

Error Responses:

  • 401 Unauthorized: Authentication required
  • 404 Not Found: Order or file not found
  • 422 Unprocessable Entity: Download limit exceeded or access not permitted