# Tạo Ticket

> Tạo một yêu cầu hỗ trợ (ticket) cho một trong các đơn của bạn.

## Endpoint

| Môi trường | URL |
| --- | --- |
| Production | `https://online-gateway.ghn.vn/shiip/public-api/ticket/create` |
| Staging | `https://dev-online-gateway.ghn.vn/shiip/public-api/ticket/create` |

**Method**: `POST`

## Headers

| Header | Bắt buộc | Mô tả |
| --- | --- | --- |
| `Content-Type` | Có | Định dạng **form**: `multipart/form-data` (bắt buộc khi gửi file đính kèm) hoặc `application/x-www-form-urlencoded`. **Không** dùng `application/json` — body JSON sẽ bị bỏ qua âm thầm và mọi trường đọc ra rỗng |
| `Token` | Có | Token của shop (do GHN cấp) — [lấy token](https://developer.ghn.vn/vi/docs/token/get-token.md) |
| `ShopId` | Không | Shop ID (số nguyên). Mặc định là shop chính của tài khoản. Quyền được kiểm tra theo shop của đơn, nhưng request vẫn bị từ chối nếu shop được phân giải không hoạt động hoặc không thuộc về bạn |

## Tham số

Gửi mọi trường dưới dạng **form value** (multipart hoặc URL-encoded). Giá trị đặt trong body JSON hay query string sẽ không được đọc.

- **order_code** (String): Mã vận đơn GHN của đơn cần tạo ticket (1–32 ký tự). Phải là đơn đang tồn tại và thuộc shop mà tài khoản của bạn sở hữu. Việc tạo ticket **không** idempotent — cùng một đơn có thể có nhiều ticket
- **category** (String): Loại ticket. Đồng thời tạo tiêu đề ticket `<order_code> - <category>`. Dùng đúng các giá trị chuẩn:<br>`Tư vấn`: yêu cầu tư vấn<br>`Khiếu nại`: khiếu nại<br>`Hối Giao/Lấy/Trả hàng`: hối giao / lấy / trả hàng<br>`Thay đổi thông tin`: thay đổi thông tin đơn
- **description** (String): Nội dung ticket (tối đa 2000 ký tự). Được sao chép vào trường `reason` của ticket khi tạo
- **attachments** (File(s)): File đính kèm (chỉ multipart). Tối đa **10 file**, mỗi file tối đa **~2 MB**. Phần mở rộng cho phép: `.docx` `.doc` `.xls` `.xlsx` `.pdf` `.jpg` `.jpeg` `.png` `.zip` `.pptx`. **Không** cho phép `.csv`

> **NOTE**
> Request này là **form-data, không phải JSON**. Đây là lỗi tích hợp phổ biến nhất của API này — phải gửi bằng `--form`/`-F` hoặc `--data-urlencode`, tuyệt đối không dùng `--data '{...}'`.

## Ví dụ Request

```bash
curl -X POST https://dev-online-gateway.ghn.vn/shiip/public-api/ticket/create \
  -H "Token: 5c1d8a9e-2f4b-11ed-..." \
  -H "ShopId: 92837" \
  -F "order_code=LADH94" \
  -F "category=Tư vấn" \
  -F "description=Cần tư vấn thời gian giao hàng" \
  -F "attachments=@/path/to/photo.jpg"
```

> **NOTE**
> Với `-F`, curl tự set `Content-Type: multipart/form-data` (kèm boundary đúng) — đừng tự set bằng tay. Nếu không có file đính kèm, bạn có thể dùng `application/x-www-form-urlencoded`: `--data-urlencode "order_code=LADH94" --data-urlencode "category=Tư vấn" --data-urlencode "description=..."`.

## Response

### Thành công (HTTP 200)

`data` là ticket vừa tạo. Hãy lưu `data.id` — bạn cần nó cho [Lấy Ticket](https://developer.ghn.vn/vi/docs/ticket/detail.md) và [Tạo Phản hồi Ticket](https://developer.ghn.vn/vi/docs/ticket/create-feedback.md).

```json
{
  "code": 200,
  "message": "Success",
  "data": {
    "id": 1234567,
    "type": "Tư vấn",
    "reason": "Cần tư vấn thời gian giao hàng",
    "order_code": "LADH94",
    "description": "Cần tư vấn thời gian giao hàng",
    "status": "Đang xử lý",
    "status_id": 1,
    "client_id": "2509893",
    "shop_id": "196560",
    "created_at": "2026-07-15T04:49:47Z",
    "created_by": 45678,
    "updated_at": "2026-07-15T04:49:47Z",
    "conversations": [],
    "attachments": []
  }
}
```

### Các trường Response

| Trường | Kiểu | Mô tả |
| --- | --- | --- |
| `code` | Int | Mã HTTP (`200` nếu thành công) |
| `message` | String | Thông báo kết quả (`Success`) |
| `data.id` | Int | Mã ticket — hãy lưu lại; cần cho Lấy Ticket và Tạo Phản hồi |
| `data.type` | String | Loại ticket (chính là `category` bạn gửi) |
| `data.reason` | String | Lý do ticket (bỏ qua khi rỗng); bản sao của `description` lúc tạo |
| `data.order_code` | String | Mã đơn của ticket |
| `data.description` | String | Nội dung ticket |
| `data.status` | String | Nhãn trạng thái tiếng Việt tương ứng `status_id` |
| `data.status_id` | Int | Trạng thái ticket:<br>`1`: `Đang xử lý`<br>`2`: `Chờ KH phản hồi`<br>`3`: `Hoàn thành` |
| `data.client_id` | String | Client ID của bạn (bỏ qua khi rỗng) |
| `data.shop_id` | String | Shop mà ticket thuộc về (bỏ qua khi rỗng) |
| `data.created_at` | String | Thời điểm tạo (RFC 3339) |
| `data.created_by` | Int | User ID nội bộ được ghi nhận là người yêu cầu |
| `data.updated_at` | String | Thời điểm cập nhật cuối (RFC 3339) |
| `data.conversations` | Array | Các phản hồi; rỗng với ticket mới tạo |
| `data.attachments` | Array | Danh sách file đính kèm |

### Lỗi — thiếu order_code (HTTP 400)

_Lấy từ một lần gọi thật trên môi trường Staging._

```json
{
  "code": 400,
  "message": "Key: 'createRequest.OrderCode' Error:Field validation for 'OrderCode' failed on the 'required' tag",
  "data": null
}
```

### Lỗi — không tìm thấy đơn (HTTP 404)

_Lấy từ một lần gọi thật trên môi trường Staging (mã đơn không tồn tại)._

```json
{
  "code": 404,
  "message": "Có lỗi xảy ra khi lấy thông tin đơn hàng",
  "data": null
}
```

## Bảng mã lỗi

| Điều kiện | HTTP | Ý nghĩa |
| --- | --- | --- |
| Thiếu/sai `order_code`, `category` hoặc `description` | 400 | Một trường form bắt buộc bị thiếu hoặc không hợp lệ |
| File đính kèm bị từ chối | 400 | Quá số file (>10), file lớn hơn ~2 MB, hoặc phần mở rộng không cho phép (vd `.csv`) |
| Không tìm thấy đơn (`Có lỗi xảy ra khi lấy thông tin đơn hàng` / `Không tìm thấy thông tin đơn hàng`) | 404 | Mã đơn không tồn tại |
| Không có quyền (`Bạn không có quyền tạo yêu cầu cho đơn hàng này`) | 403 | Đơn không thuộc shop mà tài khoản của bạn sở hữu |
