> For the complete documentation index, see [llms.txt](https://developer.esw.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.esw.com/order-api/resources/tutorials/cancelling-an-order.md).

# Cancelling an Order

{% stepper %}
{% step %}

### Order-Level vs Line Item-Level Activity

|                     | `POST /OrderActivity`                                           | `POST /LineItemActivity`                               |
| ------------------- | --------------------------------------------------------------- | ------------------------------------------------------ |
| Scope               | Entire order — all line items                                   | One specific line item                                 |
| Granularity         | Order-level only                                                | Per line item, per quantity                            |
| `activityStatus`    | `"Cancel"` only                                                 | `"Cancel"` or `"Fulfil"`                               |
| Line item targeting | Not applicable                                                  | `lineItemId` or `productCode`                          |
| Partial quantity    | Not applicable                                                  | ✅ Supported                                            |
| Typical use         | Fraud cancel, retailer full cancel, shopper self-service cancel | Warehouse fulfilment scan, out-of-stock partial cancel |

Use `POST /OrderActivity` when the action applies to the whole order with a single reason. Use `POST /LineItemActivity` when you need per-product control — for example, when a multi-item order ships in multiple parcels and each line is fulfilled separately, or when only some items are out of stock.
{% endstep %}

{% step %}
{% hint style="info" icon="puzzle-piece-simple" %}

### Part A — Cancelling an Entire Order (`POST /OrderActivity`)

{% endhint %}

```http
POST /v2/{tenantCode}/Order/{brandOrderReference}/OrderActivity
Authorization: Bearer <token>
Content-Type: application/json
```

#### Request body — `OrderActivityRequest`

```json
{
  "activityStatus": "Cancel",
  "reasonCode": "ShopperCancel",
  "transactionReference": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890",
  "transactionDateTime": "2024-11-01T15:00:00.000Z",
  "actionedBy": "Shopper",
  "actionedByUser": "jane.smith@example.com",
  "settlementReference": "657100201"
}
```

<details>

<summary>Field reference</summary>

| Field                  | Required | Description                                                       |
| ---------------------- | -------- | ----------------------------------------------------------------- |
| `activityStatus`       | ✅        | Must be `"Cancel"` for order-level activity                       |
| `reasonCode`           | ✅        | Why the order is being cancelled — `OrderActivityReasonCode` enum |
| `transactionReference` | ✅        | Unique UUID for this transaction                                  |
| `transactionDateTime`  | ✅        | ISO 8601 UTC timestamp of the cancellation event                  |
| `actionedBy`           | ✅        | Who cancelled — `"Shopper"`, `"Retailer"`, or `"ESW"`             |
| `actionedByUser`       | ❌        | Identifier of the specific person who actioned it                 |
| `settlementReference`  | ❌        | Self-billing settlement reference — include only if applicable    |

</details>

#### `OrderActivityReasonCode` values

| Value              | When to use                                                                                      |
| ------------------ | ------------------------------------------------------------------------------------------------ |
| `"ShopperCancel"`  | The shopper requested cancellation — self-service, CS-assisted, or via your portal               |
| `"RetailerCancel"` | The retailer is cancelling for an operational reason — e.g. the entire order cannot be fulfilled |
| `"Fraud"`          | The order has been identified as fraudulent by your fraud detection systems                      |

#### What happens when an order is cancelled

* All line items in the order move to `Cancelled` article status
* A single `OrderCancel` transaction is recorded against the order
* ESW initiates the refund process for any pre-authorised payment
* The order `status` transitions to `"Cancelled"`

<details>

<summary>Order-level cancellation example — shopper cancel</summary>

```json
POST /v2/my-brand-001/Order/ORD-2024-78542/OrderActivity

{
  "activityStatus": "Cancel",
  "reasonCode": "ShopperCancel",
  "transactionReference": "A1B2C3D4-E5F6-7890-ABCD-EF1234567890",
  "transactionDateTime": "2024-11-01T15:00:00.000Z",
  "actionedBy": "Shopper",
  "actionedByUser": "jane.smith@example.com"
}
```

</details>

<details>

<summary>Order-level cancellation example — fraud cancel</summary>

```json
POST /v2/my-brand-001/Order/ORD-2024-78542/OrderActivity

{
  "activityStatus": "Cancel",
  "reasonCode": "Fraud",
  "transactionReference": "B2C3D4E5-F6A7-8901-BCDE-F12345678901",
  "transactionDateTime": "2024-11-01T15:05:00.000Z",
  "actionedBy": "Retailer",
  "actionedByUser": "fraud-detection-system@mybrand.com"
}
```

</details>
{% endstep %}

{% step %}
{% hint style="info" icon="puzzle-piece-simple" %}

### Part B — Cancelling and Fulfilling Line Items (`POST /LineItemActivity`)

{% endhint %}

```
POST /v2/{tenantCode}/Order/{brandOrderReference}/LineItemActivity
Authorization: Bearer <token>
Content-Type: application/json
```

#### Request body — `LineItemActivityRequest`

{% code expandable="true" %}

```json
{
  "lineItemId": "1",
  "productCode": null,
  "quantity": 1,
  "activityStatus": "Fulfil",
  "reasonCode": "ItemFulfilled",
  "transactionReference": "C3D4E5F6-A7B8-9012-CDEF-123456789012",
  "transactionDateTime": "2024-11-03T09:15:00.000Z",
  "actionedBy": "Retailer",
  "actionedByUser": "warehouse-system@mybrand.com",
  "settlementReference": null
}
```

{% endcode %}

<details>

<summary>Field reference</summary>

| Field                  | Required | Description                             |
| ---------------------- | -------- | --------------------------------------- |
| `activityStatus`       | ✅        | `"Cancel"` or `"Fulfil"`                |
| `reasonCode`           | ✅        | Why — `LineItemActivityReasonCode` enum |
| `quantity`             | ✅        | Number of units to cancel or fulfil     |
| `transactionReference` | ✅        | Unique UUID for this transaction        |
| `transactionDateTime`  | ✅        | ISO 8601 UTC timestamp of the event     |
| `actionedBy`           | ✅        | Who actioned it                         |
| `lineItemId`           | ❌\*      | ID of the line item to act on           |
| `productCode`          | ❌\*      | SKU of the product to act on            |
| `actionedByUser`       | ❌        | Human identifier                        |
| `settlementReference`  | ❌        | Self-billing settlement reference       |

</details>

\*Either `lineItemId` **or** `productCode` is required — at least one must be provided.
{% endstep %}

{% step %}

### Line Item Targeting: `lineItemId` vs `productCode`

You have two ways to target a specific line item. Only one needs to be provided per request.

#### Using `lineItemId` (recommended)

`lineItemId` is the value you assigned when creating the order. It is stable, unambiguous, and maps directly to a single line — even if the same product appears multiple times in the same order at different prices.

```json
"lineItemId": "1",
"productCode": null
```

Use `lineItemId` whenever you have it available.

#### Using `productCode`

`productCode` targets a line item by its SKU. Use this when your downstream system (e.g. warehouse WMS) identifies items by product code rather than line item ID.

```json
"lineItemId": null,
"productCode": "SKU-00123"
```

{% hint style="warning" %}
If the same product appears more than once in the order (same SKU, different lines), targeting by `productCode` may be ambiguous. In that case, always use `lineItemId` to ensure the correct line is actioned.
{% endhint %}
{% endstep %}

{% step %}

### `ActivityStatus` Values

| Value      | Description                                                          |
| ---------- | -------------------------------------------------------------------- |
| `"Cancel"` | Mark the specified quantity of this line item as cancelled           |
| `"Fulfil"` | Mark the specified quantity of this line item as fulfilled (shipped) |

#### When to use `"Fulfil"`

`"Fulfil"` signals to ESW that the specified quantity of a line item has physically left the warehouse and is in transit. ESW uses this to:

* Update article statuses from `Created` → `Shipped`
* Trigger shopper-facing shipment notifications
* Record the fulfilment timestamp for delivery SLA tracking
* Initiate settlement processing for fulfilled goods

Call `"Fulfil"` when your warehouse or logistics system confirms dispatch — not when the order is simply picked or packed.
{% endstep %}

{% step %}

### &#x20;`LineItemActivityReasonCode` Values

| Value             | When to use                                                                 |
| ----------------- | --------------------------------------------------------------------------- |
| `"OutOfStock"`    | The item cannot be fulfilled because stock is unavailable                   |
| `"ShopperCancel"` | The shopper requested cancellation of this specific line item               |
| `"ItemFulfilled"` | The item has been shipped — always use this with `activityStatus: "Fulfil"` |

{% hint style="info" %}
Note: `"ItemFulfilled"` is the only valid reason code for a `"Fulfil"` activity. The two cancel reason codes (`"OutOfStock"`, `"ShopperCancel"`) are only valid with `activityStatus: "Cancel"`.
{% endhint %}
{% endstep %}

{% step %}

### Partial Quantity Operations

The `quantity` field allows you to act on a subset of units in a line item. This is critical for multi-quantity lines where some units ship before others, or where only part of a quantity is out of stock.

**Scenario:** a belt was ordered in quantity 3. Two units are in stock and ship today; one unit is out of stock and must be cancelled.

{% code expandable="true" %}

```json
// First call — fulfil 2 units
{
  "lineItemId": "2",
  "quantity": 2,
  "activityStatus": "Fulfil",
  "reasonCode": "ItemFulfilled",
  "transactionReference": "D4E5F6A7-B8C9-0123-DEFG-234567890123",
  "transactionDateTime": "2024-11-03T09:15:00.000Z",
  "actionedBy": "Retailer"
}

// Second call — cancel 1 unit
{
  "lineItemId": "2",
  "quantity": 1,
  "activityStatus": "Cancel",
  "reasonCode": "OutOfStock",
  "transactionReference": "E5F6A7B8-C9D0-1234-EFGH-345678901234",
  "transactionDateTime": "2024-11-03T09:17:00.000Z",
  "actionedBy": "Retailer"
}
```

{% endcode %}

#### Quantity rules

* `quantity` must be a positive integer
* `quantity` must not exceed the remaining uncancelled/unfulfilled quantity for that line item
* You can call `LineItemActivity` multiple times on the same line item as long as there are still units in `Created` status
* Attempting to act on more units than are available will produce a `400` error
  {% endstep %}

{% step %}

### Article Status Transitions

Each unit of a line item is tracked as an **article**. Articles have three possible statuses:

| Status        | Meaning                                                    |
| ------------- | ---------------------------------------------------------- |
| `"Created"`   | The article exists in the order and is awaiting action     |
| `"Shipped"`   | The article has been fulfilled — in transit to the shopper |
| `"Cancelled"` | The article has been cancelled — will not be delivered     |

{% hint style="danger" %}
Once an article reaches `Shipped` or `Cancelled`, its status cannot be changed. Attempting to fulfil or cancel an already-processed article will produce an error.
{% endhint %}

#### Checking article statuses

Retrieve the order to see the current status of all articles:

```http
GET /v2/my-brand-001/Order/ORD-2024-78542
```

The response `lineItems[n].articles` array shows each article with its current `status` field.
{% endstep %}

{% step %}

### &#x20;`settlementReference` Field on Cancellations

When your brand uses **self-billing settlement**, include `settlementReference` on cancel requests. This links the cancellation to your own settlement document so ESW can reconcile the financial reversal against your records.

```json
"settlementReference": "SETTLE-2024-11534"
```

{% endstep %}

{% step %}

### Examples

<details>

<summary>Scenario A — Full order cancellation, shopper request</summary>

A shopper calls your CS team and asks to cancel their entire order before it ships.

```json
POST /v2/my-brand-001/Order/ORD-2024-78542/OrderActivity

{
  "activityStatus": "Cancel",
  "reasonCode": "ShopperCancel",
  "transactionReference": "F6A7B8C9-D0E1-2345-FGHI-456789012345",
  "transactionDateTime": "2024-11-02T10:30:00.000Z",
  "actionedBy": "Shopper",
  "actionedByUser": "cs-agent@mybrand.com"
}
```

</details>

<details>

<summary>Scenario B — Retailer cancels entire order due to fraud</summary>

```json
POST /v2/my-brand-001/Order/ORD-2024-78542/OrderActivity

{
  "activityStatus": "Cancel",
  "reasonCode": "Fraud",
  "transactionReference": "G7B8C9D0-E1F2-3456-GHIJ-567890123456",
  "transactionDateTime": "2024-11-02T11:00:00.000Z",
  "actionedBy": "Retailer",
  "actionedByUser": "fraud-team@mybrand.com"
}
```

</details>

<details>

<summary>Scenario C — Single line item fulfilled</summary>

The warehouse scans a wallet as dispatched at 09:15.

```json
POST /v2/my-brand-001/Order/ORD-2024-78542/LineItemActivity

{
  "lineItemId": "1",
  "quantity": 1,
  "activityStatus": "Fulfil",
  "reasonCode": "ItemFulfilled",
  "transactionReference": "H8C9D0E1-F2G3-4567-HIJK-678901234567",
  "transactionDateTime": "2024-11-03T09:15:00.000Z",
  "actionedBy": "Retailer",
  "actionedByUser": "warehouse-wms@mybrand.com"
}
```

</details>

<details>

<summary>Scenario D — Line item cancelled due to out of stock (targeted by product code)</summary>

```json
POST /v2/my-brand-001/Order/ORD-2024-78542/LineItemActivity

{
  "productCode": "SKU-00456",
  "quantity": 1,
  "activityStatus": "Cancel",
  "reasonCode": "OutOfStock",
  "transactionReference": "I9D0E1F2-G3H4-5678-IJKL-789012345678",
  "transactionDateTime": "2024-11-03T10:00:00.000Z",
  "actionedBy": "Retailer",
  "actionedByUser": "inventory-system@mybrand.com"
}
```

</details>

<details>

<summary>Scenario E — Multi-item order: line 1 fulfilled, line 2 partially fulfilled, line 3 partially cancelled</summary>

Three separate `LineItemActivity` calls, each with its own `transactionReference`:

```json
// Line 1 — wallet × 1 fulfilled
{
  "lineItemId": "1",
  "quantity": 1,
  "activityStatus": "Fulfil",
  "reasonCode": "ItemFulfilled",
  "transactionReference": "J0E1F2G3-H4I5-6789-JKLM-890123456789",
  "transactionDateTime": "2024-11-03T09:15:00.000Z",
  "actionedBy": "Retailer"
}

// Line 2 — belt × 2 of 3 fulfilled
{
  "lineItemId": "2",
  "quantity": 2,
  "activityStatus": "Fulfil",
  "reasonCode": "ItemFulfilled",
  "transactionReference": "K1F2G3H4-I5J6-7890-KLMN-901234567890",
  "transactionDateTime": "2024-11-03T09:16:00.000Z",
  "actionedBy": "Retailer"
}

// Line 2 — belt × 1 of 3 cancelled (out of stock)
{
  "lineItemId": "2",
  "quantity": 1,
  "activityStatus": "Cancel",
  "reasonCode": "OutOfStock",
  "transactionReference": "L2G3H4I5-J6K7-8901-LMNO-012345678901",
  "transactionDateTime": "2024-11-03T09:17:00.000Z",
  "actionedBy": "Retailer"
}

// Line 3 — scarf × 1 fulfilled from a later dispatch
{
  "lineItemId": "3",
  "quantity": 1,
  "activityStatus": "Fulfil",
  "reasonCode": "ItemFulfilled",
  "transactionReference": "M3H4I5J6-K7L8-9012-MNOP-123456789012",
  "transactionDateTime": "2024-11-05T14:30:00.000Z",
  "actionedBy": "Retailer"
}
```

</details>
{% endstep %}
{% endstepper %}

<details>

<summary>Summary — Activity Endpoint Quick Reference</summary>

| Goal                                    | Endpoint                 | `activityStatus` | `reasonCode`     |
| --------------------------------------- | ------------------------ | ---------------- | ---------------- |
| Cancel entire order — shopper request   | `POST /OrderActivity`    | `Cancel`         | `ShopperCancel`  |
| Cancel entire order — retailer decision | `POST /OrderActivity`    | `Cancel`         | `RetailerCancel` |
| Cancel entire order — fraud             | `POST /OrderActivity`    | `Cancel`         | `Fraud`          |
| Fulfil a line item (full or partial)    | `POST /LineItemActivity` | `Fulfil`         | `ItemFulfilled`  |
| Cancel a line item — out of stock       | `POST /LineItemActivity` | `Cancel`         | `OutOfStock`     |
| Cancel a line item — shopper request    | `POST /LineItemActivity` | `Cancel`         | `ShopperCancel`  |

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developer.esw.com/order-api/resources/tutorials/cancelling-an-order.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
