Orders
Orders API
Create, read, and update orders for the authenticated store. Orders include line items, financial totals, fulfillment status, and payment information.
List Orders
Retrieve a paginated list of orders.
GET /api/apps/v1/orders
Authentication
Required. Must include valid app credentials.
Scope
read:orders
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 50 | Items per page (max 250) |
status | string | -- | Filter by order status (e.g. pending, confirmed, delivered, cancelled) |
since | string (ISO 8601) | -- | Only return orders created on or after this date |
until | string (ISO 8601) | -- | Only return orders created on or before this date |
customer_id | integer | -- | Filter orders by customer (user) ID |
sort | string | created_at:desc | Sort results. Format: column or column:asc/column:desc. Allowed columns: created_at, updated_at, grand_total |
Example Request
curl -X GET "https://api.selorax.io/api/apps/v1/orders?page=1&limit=10&status=confirmed" \
-H "Authorization: Bearer <token>"Filter by customer and sort by total:
curl -X GET "https://api.selorax.io/api/apps/v1/orders?customer_id=301&sort=grand_total:desc" \
-H "Authorization: Bearer <token>"Or using client credentials with a date range:
curl -X GET "https://api.selorax.io/api/apps/v1/orders?since=2025-01-01T00:00:00Z&until=2025-06-30T23:59:59Z&limit=50" \
-H "X-Client-Id: sx_app_..." \
-H "X-Client-Secret: sx_secret_..." \
-H "X-Store-Id: 22"Response
{
"data": [
{
"order_id": 1045,
"store_id": 22,
"user_id": 301,
"order_status": "confirmed",
"financial_status": "paid",
"fulfillment_status": "unfulfilled",
"sub_total": 1500.00,
"tax": 0.00,
"shipping": 60.00,
"discount": 100.00,
"grand_total": 1460.00,
"payment_method": "cod",
"note": "Please deliver before 5pm",
"created_at": "2025-06-15T10:30:00.000Z",
"updated_at": "2025-06-15T11:00:00.000Z"
},
{
"order_id": 1044,
"store_id": 22,
"user_id": 289,
"order_status": "pending",
"financial_status": "pending",
"fulfillment_status": "unfulfilled",
"sub_total": 800.00,
"tax": 0.00,
"shipping": 60.00,
"discount": 0.00,
"grand_total": 860.00,
"payment_method": "online",
"note": null,
"created_at": "2025-06-15T09:20:00.000Z",
"updated_at": "2025-06-15T09:20:00.000Z"
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 2
},
"status": 200
}Response Fields
| Field | Type | Description |
|---|---|---|
order_id | integer | Unique order identifier |
store_id | integer | Store the order belongs to |
user_id | integer | Customer who placed the order |
order_status | string | Current order status (pending, confirmed, processing, shipped, delivered, cancelled, returned) |
financial_status | string | Payment status (pending, paid, partially_paid, refunded) |
fulfillment_status | string | Fulfillment status (unfulfilled, partially_fulfilled, fulfilled) |
sub_total | number | Sum of line item prices before tax, shipping, and discounts |
tax | number | Tax amount |
shipping | number | Shipping charge |
discount | number | Discount applied |
grand_total | number | Final order total (sub_total + tax + shipping - discount) |
payment_method | string | Payment method used (e.g. cod, online, bkash) |
note | string or null | Customer note |
created_at | string (ISO 8601) | When the order was created |
updated_at | string (ISO 8601) | When the order was last updated |
Node.js Example
const response = await fetch(
"https://api.selorax.io/api/apps/v1/orders?status=confirmed&sort=created_at:desc",
{ headers: { Authorization: "Bearer sx_at_..." } }
);
const { data, pagination } = await response.json();
console.log(`Found ${pagination.total} orders`);Python Example
import requests
response = requests.get(
"https://api.selorax.io/api/apps/v1/orders",
headers={"Authorization": "Bearer sx_at_..."},
params={"status": "confirmed", "customer_id": 301, "limit": 50},
)
data = response.json()
for order in data["data"]:
print(f"Order #{order['order_id']}: {order['grand_total']} ({order['order_status']})")Get Order
Retrieve a single order by ID, including its line items.
GET /api/apps/v1/orders/:order_id
Authentication
Required. Must include valid app credentials.
Scope
read:orders
Path Parameters
| Parameter | Type | Description |
|---|---|---|
order_id | integer | The order ID to retrieve |
Example Request
curl -X GET "https://api.selorax.io/api/apps/v1/orders/1045" \
-H "Authorization: Bearer <token>"Response
{
"data": {
"order_id": 1045,
"user_id": 301,
"store_id": 22,
"tracking_code": "ST-2025061501",
"order_status": "confirmed",
"financial_status": "paid",
"fulfillment_status": "unfulfilled",
"sub_total": 1500.00,
"item_discount": 0.00,
"tax": 0.00,
"shipping": 60.00,
"total": 1560.00,
"promo": null,
"discount": 100.00,
"grand_total": 1460.00,
"paid_by_customer": 1460.00,
"note": "Please deliver before 5pm",
"address": "{\"name\":\"Rahim Ahmed\",\"phone\":\"+8801712345678\",\"address\":\"123 Main St\",\"city\":\"Dhaka\"}",
"billing_address": null,
"is_billing_same": 1,
"channel": "web",
"payment_method": "cod",
"is_delivery_paid": 0,
"created_at": "2025-06-15T10:30:00.000Z",
"updated_at": "2025-06-15T11:00:00.000Z",
"delivery_date": null,
"tags": null,
"processed_at": "2025-06-15T10:35:00.000Z",
"shipped_at": null,
"delivered_at": null,
"courier": null,
"courier_id": null,
"store_serial_order_no": 1045,
"customer_name": "Rahim Ahmed",
"customer_phone": "+8801712345678",
"customer_email": "[email protected]",
"items": [
{
"order_item_id": 2089,
"order_id": 1045,
"product_id": 150,
"variant_id": 451,
"bundle_id": null,
"name": "Premium Rose Bouquet - Large / Red",
"price": 750.00,
"discount": 0.00,
"quantity": 2,
"image": "products/prb-lg-red.jpg",
"created_at": "2025-06-15T10:30:00.000Z",
"updated_at": "2025-06-15T10:30:00.000Z"
}
]
},
"status": 200
}Order Detail Fields
The single order response includes all list fields plus:
| Field | Type | Description |
|---|---|---|
tracking_code | string or null | Courier tracking code |
item_discount | number | Sum of per-item discounts |
total | number | Order total before promo/discount |
promo | string or null | Promo code applied |
paid_by_customer | number | Amount actually paid by customer |
address | string (JSON) | Shipping address as JSON string with name, phone, address, city |
billing_address | string (JSON) or null | Billing address (if different from shipping) |
is_billing_same | integer (0 or 1) | Whether billing address matches shipping |
channel | string | Order channel (e.g. web, pos, manual) |
is_delivery_paid | integer (0 or 1) | Whether delivery cost was paid |
delivery_date | string or null | Scheduled delivery date |
tags | string or null | Order tags |
processed_at | string or null | When order was confirmed |
hold_at | string or null | When order was put on hold |
cancel_at | string or null | When order was cancelled |
shipped_at | string or null | When order was shipped |
delivered_at | string or null | When order was delivered |
returned_at | string or null | When order was returned |
courier | string or null | Courier service name |
courier_id | string or null | External courier order ID |
payment_date | string or null | When payment was received |
fulfilled_at | string or null | When order was fulfilled |
store_serial_order_no | integer | Store-specific sequential order number |
shipping_type | string or null | Shipping type |
is_bundle | integer (0 or 1) | Whether order contains bundle items |
followup_date | string or null | Follow-up date for the order |
printed | integer (0 or 1) | Whether the order has been printed |
printed_at | string or null | When the order was printed |
customer_name | string or null | Customer name (joined from users table) |
customer_phone | string or null | Customer phone (joined from users table) |
customer_email | string or null | Customer email (joined from users table) |
Item Fields
| Field | Type | Description |
|---|---|---|
order_item_id | integer | Line item ID |
order_id | integer | Parent order ID |
product_id | integer | Associated product ID |
variant_id | integer or null | Associated variant ID |
bundle_id | integer or null | Bundle ID (if part of a bundle) |
name | string | Product and variant name |
price | number | Unit price |
discount | number | Discount on this item |
quantity | integer | Quantity ordered |
image | string or null | Product image path |
created_at | string (ISO 8601) | When the item was added |
updated_at | string (ISO 8601) | When the item was last updated |
Error Responses
| Code | Status | Meaning |
|---|---|---|
invalid_token | 401 | Token is expired or invalid |
insufficient_scope | 403 | App does not have read:orders scope |
If the order_id does not belong to the authenticated store, the API returns a 404 with no code field:
{
"message": "Order not found.",
"status": 404
}Create Order
Create a new order with line items.
POST /api/apps/v1/orders
Scope
write:orders
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
customer_id | integer | No | Customer user ID (must exist in this store) |
address | object | Yes | Shipping address. Must include address field |
billing_address | object | No | Billing address (if different from shipping) |
is_billing_same | boolean | No | Whether billing matches shipping (default: false) |
order_items | array | Yes | Array of line items (min 1) |
order_status | string | No | Initial status (default: pending) |
financial_status | string | No | Payment status (default: pending) |
fulfillment_status | string | No | Fulfillment status (default: un-fulfilled) |
payment_method | string | No | Payment method (default: cod) |
channel | string | No | Order channel (default: other) |
note | string | No | Customer note |
internal_note | string | No | Internal note (not visible to customer) |
tags | string | No | Order tags |
delivery_date | string | No | Scheduled delivery date |
sub_total | number | No | Auto-calculated from items if omitted |
grand_total | number | No | Auto-calculated if omitted |
shipping | number | No | Shipping charge (default: 0) |
discount | number | No | Discount amount (default: 0) |
tax | number | No | Tax amount (default: 0) |
Order Item fields:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Item name |
price | number | Yes | Unit price |
quantity | integer | Yes | Quantity |
product_id | integer | No | Associated product ID |
variant_id | integer | No | Associated variant ID (cost auto-fetched) |
discount | number | No | Per-item discount |
image | string | No | Item image path |
Example Request
curl -X POST "https://api.selorax.io/api/apps/v1/orders" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"customer_id": 301,
"address": {
"name": "Rahim Ahmed",
"phone": "01712345678",
"address": "123 Main St",
"city": "Dhaka"
},
"payment_method": "cod",
"shipping": 60,
"order_items": [
{
"name": "Premium Rose Bouquet - Large / Red",
"product_id": 150,
"variant_id": 451,
"price": 750,
"quantity": 2
}
]
}'Response (201)
{
"data": {
"order_id": 1050,
"store_id": 22,
"user_id": 301,
"order_status": "pending",
"financial_status": "pending",
"fulfillment_status": "un-fulfilled",
"sub_total": 1500,
"grand_total": 1560,
"items_count": 1
},
"status": 201
}Auto-calculation
If sub_total or grand_total are omitted, they are auto-calculated from the items: sub_total = sum(price × quantity), grand_total = sub_total - discount + tax + shipping.
Update Order
Update order fields such as notes, tags, address, and payment details.
PUT /api/apps/v1/orders/:order_id
Scope
write:orders
Request Body
| Field | Type | Description |
|---|---|---|
note | string | Customer note |
internal_note | string | Internal note |
tags | string | Order tags |
address | object | Shipping address |
billing_address | object | Billing address |
is_billing_same | boolean | Whether billing matches shipping |
payment_method | string | Payment method |
paid_by_customer | number | Amount paid |
payment_date | string | Payment date |
payment_reference | string | Payment reference |
payment_remark | string | Payment remark |
delivery_date | string | Delivery date |
followup_date | string | Follow-up date |
shppping_type | string | Shipping type (inside, subarea, outside, free) |
is_delivery_paid | boolean | Whether delivery is paid |
Optimistic locking
Order updates use optimistic locking. If another request modifies the order simultaneously, a 409 Conflict is returned. Retry the request to pick up the latest version.
Example Request
curl -X PUT "https://api.selorax.io/api/apps/v1/orders/1045" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"note": "Updated delivery instructions",
"tags": "vip,express",
"payment_method": "Bkash",
"paid_by_customer": 1460
}'Update Order Status
Change the order status, financial status, or fulfillment status.
PUT /api/apps/v1/orders/:order_id/status
Scope
write:orders
Request Body
At least one status field is required.
| Field | Type | Valid Values |
|---|---|---|
order_status | string | pending, processing, scheduled, shipped, completed, cancelled, hold, returned, refunded, exchange |
financial_status | string | pending, partially_paid, paid, partially_refunded, refunded, voided |
fulfillment_status | string | un-fulfilled, fulfilled, partial, processing, ongoing, delivered, cancelled, hold, in_review, delivery-in-progress, pickup-pending, returning, returned, rejected |
Automatic timestamps
Status changes automatically set the corresponding timestamp field. For example, setting order_status to shipped sets shipped_at, and fulfilled sets fulfilled_at.
Example Request
curl -X PUT "https://api.selorax.io/api/apps/v1/orders/1045/status" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"order_status": "processing",
"financial_status": "paid"
}'Response
{
"data": {
"order_id": 1045,
"order_status": "processing",
"financial_status": "paid",
"fulfillment_status": "un-fulfilled",
"updated_at": "2025-06-20T12:00:00.000Z"
},
"changes": {
"order_status": { "from": "pending", "to": "processing" },
"financial_status": { "from": "pending", "to": "paid" }
},
"status": 200
}