# Cancel Order

## Endpoint

| Environment | URL |
| --- | --- |
| Production | `https://online-gateway.ghn.vn/shiip/public-api/v2/switch-status/cancel` |
| Staging | `https://dev-online-gateway.ghn.vn/shiip/public-api/v2/switch-status/cancel` |

**Method**: `POST`

## Headers

| Header | Required | Description |
| --- | --- | --- |
| `Content-Type` | Yes | `application/json` |
| `Token` | Yes | Shop token (issued by GHN) — [get a token](https://developer.ghn.vn/en/docs/token/get-token.md) |
| `ShopId` | Yes | Shop ID (int) |

## Parameters

- **order_codes** (String[]): GHN tracking codes to cancel, in one batch. **All-or-nothing**: if any code is unknown or does not belong to your account, the whole request is rejected and nothing is cancelled (see Response)
- **reason_code** (String): Cancellation reason, applied to every order in the batch. One of:<br>`GHN-CO001`: pickup is taking too long<br>`GHN-CO002`: out of stock, nothing to ship yet<br>`GHN-CO003`: recipient no longer wants the order<br>`GHN-CANCEL-OTHER`: other reason
- **reason** (String): Free-text cancellation note, applied to every order in the batch. Use it to add detail, e.g. together with `GHN-CANCEL-OTHER`. Default: none

## Request Example

```bash
curl -X POST https://dev-online-gateway.ghn.vn/shiip/public-api/v2/switch-status/cancel \
  -H "Token: 5c1d8a9e-2f4b-11ed-..." \
  -H "ShopId: 92837" \
  -H "Content-Type: application/json" \
  -d '{
    "order_codes": ["LADTC8", "LADFYR"],
    "reason_code": "GHN-CO001",
    "reason": "Buyer changed their mind"
  }'
```

## Response

### Success (HTTP 200)

_Captured from a real Staging-environment call._

```json
{
  "code": 200,
  "message": "Success",
  "data": [
    {
      "order_code": "LADTC8",
      "result": true,
      "message": "OK"
    }
  ]
}
```

### Response Fields

| Field | Type | Description |
| --- | --- | --- |
| `code` | Int | HTTP code (`200` on success) |
| `message` | String | Result message (`Success`) |
| `data` | Object[] | One entry per order code in the request |
| `data[].order_code` | String | The order this entry refers to |
| `data[].result` | Bool | `true` if the order was cancelled; `false` if GHN rejected it (e.g. the order is already at a status that can no longer be cancelled) |
| `data[].message` | String | Per-order result message (e.g. `OK`) |

### Error — order not found / not yours (HTTP 400)

_Captured from a real Staging-environment call (unknown order code)._ Because the batch is all-or-nothing, one bad code aborts the whole request with `data: null` — no order in the batch is cancelled.

```json
{
  "code": 400,
  "message": "Lỗi gọi API: corev2_tenant_order_detail - Đơn hàng không tồn tại",
  "data": null
}
```

> **NOTE**
> The meaningful part of `message` is the text after the last `-` (here `Đơn hàng không tồn tại` — "order not found"). The prefix is an internal reference.

## Error Codes

| Condition | HTTP | Meaning |
| --- | --- | --- |
| Order not found (`Đơn hàng không tồn tại`) | 400 | One of the order codes is unknown or does not belong to your account. The entire batch is aborted; nothing is cancelled |
| `result: false` in `data` | 200 | The order code is valid but its current status can no longer be cancelled |
| `CLIENT_NOT_OWNER_OF_SHOP` | 400 | Token does not own the shop |
| `SERVER_ERROR_COMMON` | 500 | Internal error |
