Orders
Create order
POST /access/api/v1/orders
Places a new order. The customer does not need to be logged in.
Request body:
{
"cart": [
{
"productId": "69bc36fda53000e2ede23dca",
"type": "product",
"quantity": 1,
"variationKey": ""
}
],
"name": "Jane Doe",
"email": "customer@example.com",
"phone": "0700xxx000",
"town": "Nairobi",
"city": "",
"apartment": "",
"room": "",
"note": "",
"coupons": [],
"shippingId": null,
"pickupLocationId": null,
"cartUserId": null
}
Required fields: cart, name, email, phone, town
Field notes:
coupons — array of coupon codes. Validate the code first using the Coupons endpoint to confirm it is valid and get the discount amount. Pass the validated code here when submitting the order.
shippingId — the _id of the standard shipping rate the customer selected. Available rates are in settings.shipping.standard from the settings response. Each rate has a title, price, and description to display in your shipping selector. Pass null if the customer chose pickup or if shipping is disabled (settings.shipping.standardActive is false).
pickupLocationId — the _id of the pickup location the customer selected. Available locations are in settings.shipping.pickup from the settings response. Each location has name, buildingName, description, openingHours, fee, and a mapUrl. Pass null if the customer chose standard delivery or if pickup is disabled (settings.shipping.pickupActive is false).
If settings.shipping.removeAddress is true, hide the delivery address fields (town, city, apartment, room) and the shipping selector entirely — the merchant does not collect a delivery address for this shop.
cartUserId — pass the logged-in customer's _id if they are authenticated (available from the Get current customer response). If the customer is logged in, pre-fill the checkout form with their saved name, email, phone, and address. Pass null for guest checkouts. This links the order to the customer's account so it appears in their order history.
Response when payments are enabled:
{
"status": "success",
"data": {
"action": "CHECKOUT-LINK",
"link": "https://..."
}
}
Check for action === "CHECKOUT-LINK" and redirect the customer to link. The payment provider handles the transaction and redirects back to your theme when done — see Payment Callbacks.
Response when no payments are activated:
{
"status": "success",
"data": {
"_id": "69e93be95c08152c63f2b8ef",
"orderNumber": "dels-4584--main",
"products": [
{ "_id": "69bc36fda53000e2ede23dca", "title": "Running Shoes", "quantity": 1 }
],
"shippingTotal": 0,
"productsTotal": 49.99,
"cartTotal": 49.99,
"taxTotal": 0
}
}
Show the order confirmation directly from this response — no redirect needed.
Possible errors:
| Code | HTTP | What to show |
|---|---|---|
ORDER_VALIDATION_FAILED | 422 | "Could not place your order, please review your cart" |
INVALID_SHIPPING_ID | 422 | "Selected shipping method is no longer available" |
PAYMENTS_NOT_ENABLED | 403 | "Online payments are not available for this store" |
Get my orders
GET /access/api/v1/orders
Requires customer JWT. Returns a paginated list of the customer's orders.
Query parameters: page, limit
Headers:
Authorization: Bearer <customer_token>
Response:
{
"status": "success",
"total": 5,
"page": 1,
"limit": 10,
"totalPages": 1,
"data": [
{
"_id": "69e93be95c08152c63f2b8ef",
"orderNumber": "dels-4584--main",
"status": "pending",
"couponTotal": 0,
"shippingTotal": 0,
"productsTotal": 49.99,
"cartTotal": 49.99,
"taxTotal": 0,
"note": "",
"paymentTotal": 0,
"paymentStatus": "unpaid",
"paymentBalance": 49.99,
"coupons": [],
"products": [],
"shipping": null,
"date": "2026-04-10T09:22:11.000Z"
}
]
}
Get single order
GET /access/api/v1/orders/:id
Requires customer JWT. Returns a fully populated order with products, shipping, coupons, and downloadables (if any).
Headers:
Authorization: Bearer <customer_token>
Response:
{
"status": "success",
"data": {
"_id": "69e93be95c08152c63f2b8ef",
"orderNumber": "dels-4584--main",
"status": "delivered",
"couponTotal": 0,
"shippingTotal": 5,
"productsTotal": 49.99,
"cartTotal": 54.99,
"taxTotal": 0,
"note": "",
"paymentTotal": 54.99,
"paymentStatus": "fully-paid",
"paymentBalance": 0,
"refundExpiryDate": "2026-05-10T09:22:11.000Z",
"refundStatus": "VALID",
"coupons": [],
"products": [
{
"_id": "...",
"title": "Running Shoes",
"quantity": 1,
"price": 49.99,
"shippingId": null
}
],
"shipping": {
"_id": "...",
"name": "Standard Delivery",
"price": 5
},
"downloadables": [],
"date": "2026-04-10T09:22:11.000Z"
}
}
refundStatus is one of VALID (refund window open), EXPIRED (window closed), EXISTING (refund requested), DONE (refunded), or INVALID (not applicable).
downloadables is only populated when the order is fully paid (paymentStatus: "fully-paid") and the order contains digital products. Each downloadable entry has a files array — use the file _id and product _id to request a download via the endpoint below.
When status is delivered, completed, cancelled, or refunded, the customer is eligible to leave a review. Show a review prompt for each product in the order and submit it via Add a review.
Possible errors: ORDER_NOT_FOUND
Download order files
POST /access/api/v1/orders/download-files/:id
For shops that sell digital products. Once an order has been fully paid, the customer can request a file download from this endpoint. :id is the order _id.
The fileId and productId to send come from the downloadables array on the Get single order response. The downloadables are only visible on a fully paid order — do not show the download UI if paymentStatus is not "fully-paid".
Headers:
Authorization: Bearer <customer_token>
Request body:
{
"fileId": "69ac367da7e93c257591ff59",
"productId": "69bc36fda53000e2ede23dca"
}
Response: Binary file stream with Content-Disposition: attachment header. Not a JSON response — trigger it as a download directly in the browser.
Possible errors:
| Code | Meaning |
|---|---|
ORDER_NOT_FOUND | Order not found or not owned by this customer |
DOWNLOAD_PRODUCT_NOT_FOUND | Product not found in the order's downloadables |
DOWNLOAD_FILE_NOT_FOUND | File ID not found in the product |
DOWNLOAD_NOT_ACTIVE | Merchant has disabled this download |
DOWNLOAD_LIMIT_REACHED | Customer has exceeded the allowed download count |
DOWNLOAD_EXPIRED | The download period has ended |
DOWNLOAD_FILE_MISSING | File not found on the server |