Shop Order
ON THIS PAGE
Allows suppliers to fetch a shop order and update its fulfilment status, tracking link, or send a message to the customer. The order body matches the order_placed webhook. Order status and delivery tracking_link are added on this API.
Authentication
You must include a valid bearer token in the Authorization header to authenticate your request. Refer to Using Bearer Tokens for guidance. The caller must be a supplier admin or an account manager on :org_id.
- Supplier admins can fetch any order for their linked distributor.
- Account managers can fetch only orders assigned to them. Any other order returns
404.
Endpoint
| METHOD | Endpoint | Description | Path Parameters |
|---|---|---|---|
| GET | /suppliers/:org_id/shop_orders/:order_id/ | Get one shop order | org_id, order_id |
| PATCH | /suppliers/:org_id/shop_orders/:order_id/ | Update status, tracking link, and/or send a message | org_id, order_id |
:org_idyour OpenSolar Organization ID:order_idID of the order
PUT, POST, and DELETE are not supported. There is no list URL.
A successful PATCH returns the same object as GET. message is accepted on the request and is not returned.
Get a shop order
The payload is the current order, including line-item edits made after checkout.
Request
curl "https://api.opensolar.com/api/suppliers/100/shop_orders/456/" \
--header "Authorization: Bearer <token>"
Response
{
"org_id": 100,
"supplier_id": 123,
"order_id": 456,
"seller_org_reference": "customer-123",
"preferred_supplier_location": "london",
"total_items": 2,
"subtotal_price": "1200.00",
"total_tax": "216.00",
"total_price": "1441.00",
"project_ids": [
999
],
"items": [
{
"quantity": 8,
"product_code": "PANEL-A",
"title": "Panel A",
"total_price": "1000.00",
"distributor_product_code": "DIST-PANEL-A"
},
{
"quantity": 1,
"product_code": "INV-1",
"title": "Inverter",
"total_price": "200.00",
"distributor_product_code": "DIST-INV-1"
}
],
"shipping_info": {
"payment_option": "cash",
"delivery_date": "2026-04-01",
"delivery_method": "delivery",
"delivery_instructions": "Leave with reception",
"address": {
"address": "123 Main St",
"locality": "Sydney",
"state": "NSW",
"zip": "2000",
"country_name": "Australia"
}
},
"contact_info": {
"email": "pro@example.com",
"phone_number": "+61 400 000 000",
"first_name": "Alex",
"last_name": "Nguyen",
"org_name": "Acme Solar"
},
"shipping_cost": {
"label": "Standard Delivery",
"cost": 25.0
},
"discounts": null,
"status": "processing",
"tracking_link": null
}
preferred_supplier_location is included only when the distributor has active stock locations. carrier_service and carrier_name are included on shipping_info only when a freight option is returned to the Customer (see Supplier-fed Freight Charges). collection_location is included when the customer choose a pickup location.
shipping_cost is null when no shipping cost was recorded.
discounts is null when no Deal and no Supplier Assist discount applied. When one did apply, discounts has currency, total_discount_amount, discount_applications, and discount_allocations.
total_tax is present when the order recorded tax. Australia, the United Kingdom, and Germany include calculated tax. Other countries, including the United States and Canada, record "0.00".
Update order status
Update the status of the order on OpenSolar and keep your customer updated. Status changes are saved, recorded on the order, and emailed to the customer. Sending a status already applied to the order succeeds and does not send a repeat email.
| Allowed values | Allowed status transitions |
|---|---|
ordered | processing, completed, cancelled |
processing | shipped, ready_for_pickup, completed, cancelled |
shipped | completed |
ready_for_pickup | completed |
draft | abandoned, cancelled |
completed, cancelled, abandoned | none |
shipped is only for delivery orders. ready_for_pickup is only for collection orders. Any other transition returns 400 with Cannot transition from <current> to <requested>. An unknown status returns 400 with Invalid order status.
Request
curl -X PATCH "https://api.opensolar.com/api/suppliers/100/shop_orders/456/" \
--header "Authorization: Bearer <token>" \
--header "Content-Type: application/json" \
--data '{
"status": "processing"
}'
Response
The full order object, with "status": "processing".
Set a tracking link
To provide your customer with a delivery tracker, send a tracking_link to be saved and recorded on the order. Sending the same link again succeeds and does not write another activity record.
The link is stored exactly as you send it. Send "" or nullto clear the link. A value that is not a URL returns 400.
Collection orders cannot have a tracking link. That request returns 400 with Tracking links are not supported for collection orders.
Request
curl -X PATCH "https://api.opensolar.com/api/suppliers/100/shop_orders/456/" \
--header "Authorization: Bearer <token>" \
--header "Content-Type: application/json" \
--data '{
"tracking_link": "https://track.example/ABC123"
}'
Response
The full order object, with the stored tracking_link.
Send a message
To post a message to the customer about their order, send a message. The message is attributed to the authenticated user. The customer who placed the order is emailed. Repeated messages to the same person share one email. Each new message waits 10 minutes before that email is sent, so a burst of messages produces one email rather than one per message.
message must contain text. A blank message returns 400.
Request
curl -X PATCH "https://api.opensolar.com/api/suppliers/100/shop_orders/456/" \
--header "Authorization: Bearer <token>" \
--header "Content-Type: application/json" \
--data '{
"message": "Your order is booked for delivery on 1 April."
}'
Response
The full order object. The message itself is not in the body.
Update several fields at once
status, tracking_link, and message may be sent together. They are applied in that order.
If status is saved and a later field in the same request is rejected, the status change is already stored. After a 400, fetch the order again before retrying.
The example below assumes the order is already processing (for example, after Update order status), so shipped is a valid next status for a delivery order.
curl -X PATCH "https://api.opensolar.com/api/suppliers/100/shop_orders/456/" \
--header "Authorization: Bearer <token>" \
--header "Content-Type: application/json" \
--data '{
"status": "shipped",
"tracking_link": "https://track.example/ABC123",
"message": "Dispatched today."
}'