Skip to main content

Orders API

Orders live in ec/v1. Admin/staff operations require manage_options or the wpec_manage_orders capability (canViewOrders for reads, canEditOrders for writes). Customer self-service reads own orders separately — see Customer orders below.

Since the April 2026 controller split, order data is served by five controllers sharing one permission model: the core Orders controller plus dedicated line-items, payments, shipments, and courier sub-controllers. Their endpoints are documented here together.

List orders

GET /ec/v1/orders

Requires wpec_manage_orders.

Query parameters

ParameterTypeDefaultDescription
pageint1Page number
per_pageint20Items per page
statusstringOrder status filter
payment_statusstringPayment status filter
fulfillment_statusstringFulfilment status filter
customer_idintFilter by customer
date_fromstringISO date start
date_tostringISO date end
searchstringSearch term
orderbystringSort field
orderstringASC / DESC

Response

List responses use an orders key with pagination fields alongside it (not a success / data.items wrapper):

{
"orders": [
{
"id": 101,
"order_number": "ORD-00101",
"status": "processing",
"payment_status": "paid",
"fulfillment_status": "unfulfilled",
"total": "80.58",
"created_at": "2026-03-01T14:22:00Z"
}
],
"total": 45,
"page": 1,
"per_page": 20,
"total_pages": 3
}

Get a single order

GET /ec/v1/orders/{id}

Returns the full order object (order->toArray()) — items, addresses, payment info, totals, and status. 404 order_not_found if it doesn't exist.

Create order

POST /ec/v1/orders

Requires wpec_manage_orders. Accepts customer_id, status, currency, payment_method, shipping_method, customer_note, admin_note, a billing and shipping address object, and an items array. Order number is generated server-side.

Update order

PUT /ec/v1/orders/{id}
PATCH /ec/v1/orders/{id}

General update. For status-only changes prefer the dedicated transition endpoints below (they run the stock side-effects).

Status / payment / fulfilment transitions

MethodEndpointBodyEffect
PUT/PATCH/ec/v1/orders/{id}/status{ "status": "shipped" }Change order status. Moving into cancelled/refunded/failed restores stock; moving out of a terminal status re-reduces it.
PUT/PATCH/ec/v1/orders/{id}/payment-status{ "payment_status": "paid" }Update payment status
PUT/PATCH/ec/v1/orders/{id}/fulfillment-status{ "fulfillment_status": "fulfilled" }Update fulfilment status

status is required on /status — omitting it returns 400 missing_status.

Delete order

DELETE /ec/v1/orders/{id}

Requires wpec_manage_orders. Restores stock first if the order was in a non-terminal status.

Bulk actions

POST /ec/v1/orders/bulk

Requires wpec_manage_orders. Apply one action to many orders at once:

{ "ids": [101, 102, 103], "action": "shipped" }
  • action is either delete or a target status to transition every order to.
  • Status transitions run the same stock side-effects as the single-order /status endpoint.

Returns a per-batch tally:

{ "success": 2, "failed": 1 }

Stats & statuses

MethodEndpointPurpose
GET/ec/v1/orders/statsAggregate order stats (admin)
GET/ec/v1/orders/statusesThe list of valid order statuses

Order sub-resources

Each sub-resource is served by its own controller but shares the wpec_manage_orders permission model (GET = view, writes = edit).

Line items

MethodEndpointPurpose
GET/ec/v1/orders/{id}/itemsList line items — { "items": [ … ] }
POST/ec/v1/orders/{id}/itemsAdd a line item (recalculates totals)
PUT/PATCH/ec/v1/orders/{id}/items/{item_id}Update a line item
DELETE/ec/v1/orders/{id}/items/{item_id}Remove a line item

Payments

MethodEndpointPurpose
GET/ec/v1/orders/{id}/paymentsList payments — { "payments": [ … ] }
POST/ec/v1/orders/{id}/paymentsRecord a payment against the order
PUT/PATCH/ec/v1/payments/{id}Update a payment (note: not nested under the order)
DELETE/ec/v1/payments/{id}Delete a payment

Shipments

MethodEndpointPurpose
GET/ec/v1/orders/{id}/shipmentsList shipments — { "shipments": [ … ] }
POST/ec/v1/orders/{id}/shipmentsCreate a shipment
PUT/PATCH/ec/v1/shipments/{id}Update a shipment (not nested under the order)
DELETE/ec/v1/shipments/{id}Delete a shipment

Courier (order-aware)

Wraps the courier providers (Geniki / ELTA / ACS) in an order context:

MethodEndpointPurpose
POST/ec/v1/orders/{id}/courier/create-voucherCreate a courier voucher for the order
GET/ec/v1/orders/{id}/courier/label/{shipment_id}Fetch the label for a shipment
GET/ec/v1/orders/{id}/courier/track/{shipment_id}Track a shipment
POST/ec/v1/orders/{id}/courier/cancel/{shipment_id}Cancel a courier voucher

For raw, order-independent courier operations and provider configuration, see the /courier/* group in the REST overview.

Customer orders

There is no /orders/my endpoint. Logged-in customers read their own orders through the My Account API (own data only, no admin capability required):

GET /ec/v1/account/orders
GET /ec/v1/account/orders/{id}

A public, key-verified order-confirmation read also exists for the "order received" page:

GET /ec/v1/order-received/{id}?key={nonce}

Access is granted by a valid key nonce, by an admin, or to the logged-in user who owns the order — otherwise 403.

Where to go next