Skip to main content

External Service Configuration

When the Customer Order service is configured to work in the proxy mode, it will proxy the requests to the external service. The external service must be able to handle the requests from the Customer Order service. The following sections describe the format that the external service must implement.

Endpoints​

The external service must implement the following endpoints. All three, if you want the current API to work against it:

EndpointUsed by
GET /business-units/{businessUnitId}/customer-orders/{customerOrderId}reading one order — both API versions
GET /business-units/{businessUnitId}/customer-orders:searchsearching — the current API
POST /business-units/{businessUnitId}/customer-orders:searchsearching — the older API

🛑 Search exists in two shapes, and the newer one is a GET. The current API forwards a search as GET …:search with the criteria as query parameters; the older API forwards the same search as a POST with a JSON body. The service does not translate between them: a GET search reaches you as a GET, and a POST search as a POST.

So an external service that only implements the POST will refuse every search made through the current API — and one that only implements the GET will refuse every search from a caller still on the older one.

Implement both. The older endpoints were deprecated on 1 October 2025, but deprecated is not gone — they still work, and the service still forwards them.

No withdrawal date has been announced. Hii Retail keeps a deprecated endpoint callable for at least 18 months after its deprecation date, so these will not be withdrawn before 1 April 2027. That is a floor and not a schedule: nothing is currently planned for that date, and they may well outlive it. Treat 1 April 2027 as the earliest you could be affected, not as a deadline to migrate by — if a withdrawal is scheduled it will be announced on the endpoint itself, with its own date.

So until they are actually withdrawn, either form can arrive.

🛑 The two forms do not take the same criteria, and this is the part that catches people out. They return the same response shape, but what they send you has no field in common:

GET …:search (current)POST …:search (older)
Criteria arrive asquery parametersa JSON body
Fields you may receivecustomerOrderId, userProfileId, operatorId, createdDatetimeFrom, createdDatetimeTo, orderStatus, fulfillmentStatus, name, phoneNumber, email, offsetcustomerId — and nothing else

So this is a second implementation rather than a routing change. Build the GET form first: it is what current callers use, and it is the one that carries real search criteria.

Searches reach your system in two forms, and neither is translated into the other. Current callers send GET  with the criteria as query parameters, such as userProfileId, createdDatetimeFrom and orderStatus. Callers of the older API send POST  with a JSON body holding only customerId. The two share no field, so implement both.

⚠ Filters on the single-order read are also passed as query parameters on the current API, so tolerate query parameters on the GET order endpoint rather than rejecting them.

  • GET: /business-units/{businessUnitId}/customer-orders/{customerOrderId}

Sample response:

{
"customerOrder": {
"customerOrderId": "111", // required
"customerId": "customerId", // required
"status": "CREATED", // required
"minimumDownPaymentAmount": 100,
"isLocked": false,
"invoicePaymentInstructions": {
"customerAccountId": "111", // required
"invoicingAmount": 100, // required
"additionalInformation": [
{
"id": "requisition", // required
"value": "111", // required
"displayText": "Requisition number", // required
"receiptLabel": "Requisition number" // required
}
]
},
"items": [ // required
{
"itemId": "111", // required
"quantityOrdered": 100, // required
"unitPrice": 100 // required
}
]
}
}
  • GET: /business-units/{businessUnitId}/customer-orders:search

All criteria arrive as query parameters and every one is optional — a search with none set asks for everything. orderStatus and fulfillmentStatus may repeat, and repeated values are OR-ed. The service checks the criteria before passing them on: the two dates always arrive as full UTC timestamps (a date given without a time becomes the start or the end of that day), and name, phoneNumber and email arrive as the caller typed them, for your system to match:

GET /business-units/BU-1/customer-orders:search
?userProfileId=111
&createdDatetimeFrom=2026-01-01T00:00:00Z
&orderStatus=CREATED&orderStatus=IN_PROGRESS
&offset=0

Sample response — the same shape the POST form returns:

{
"customerOrders": [
{
"customerOrderId": "111", // required
"status": "CREATED" // required
}
]
}

⚠ Only customerOrderId and status are read from your response. Other fields are accepted and ignored, so there is no benefit in populating them.

  • POST: /business-units/{businessUnitId}/customer-orders:search

Sample search body:

{
"customerId": "111"
}

Sample response:

{
"customerOrders": [
{
"customerOrderId": "111", // required
"customerId": "111", // required
"status": "CREATED" // required
}
]
}

Authentication​

The external service must be able to authenticate the requests from the Customer Order service. The tenant sets up the authentication in the logistics proxy configuration, choosing what the external service supports:

  • Basic Authentication
  • OAuth 2.0 client credentials (Bearer token)

Every request also carries the Tenant-Id header.

Errors. A 4xx answer is passed on to the caller as it is, so answer 404 for an order you do not have. A 5xx answer, or a body that does not match the samples above, reaches the caller as 502 Bad Gateway. An answer that does not arrive within the time limit reaches the caller as 504 Gateway Timeout, so keep your read endpoints fast: a colleague at the till is waiting for them.

Testing (Mock Service)​

HiiRetail provides a mock service for testing purposes. This service is meant to emulate the behavior of the external service with minimal setup. The mock service is available at https://cor-external-mock.retailsvc.com, and you can examine the OpenAPI documentation at https://cor-external-mock.retailsvc.com/schemas/v1/openapi.json. This can be used as a reference for the external service implementation or can be used as a testing service for test tenants.

For more details on the mock service, please refer to the Mock Service documentation.