# Tạo Shop bằng OTP

> Đối tác (affiliate) gọi Lấy OTP cho số điện thoại của chủ shop, GHN gửi OTP qua SMS tới số đó, sau đó đối tác gửi OTP này lên đây để tạo một shop mới thuộc sở hữu của khách hàng đó. Đây là bước 2 của luồng affiliate (xem [Lấy OTP](https://developer.ghn.vn/vi/docs/affiliate/get-otp.md)).

## Endpoint

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

**Method**: `POST`

## Headers

| Header | Bắt buộc | Mô tả |
| --- | --- | --- |
| `Content-Type` | Có | `application/json` |
| `Token` | Có | Token của bạn (đối tác), do GHN cấp. Tài khoản của bạn phải đang hoạt động — [lấy token](https://developer.ghn.vn/vi/docs/token/get-token.md) |
| `ShopId` | Không | Chọn ngữ cảnh shop của bạn; nếu bỏ trống, shop mặc định của tài khoản bạn được dùng. Shop được chọn phải đang hoạt động và thuộc về bạn, nếu không request sẽ bị từ chối |

## Tham số

- **phone** (String): SĐT của chủ shop (khách hàng của bạn) đã nhận OTP. Phải ứng với một tài khoản GHN đã đăng ký
- **otp** (String): OTP lấy từ [Lấy OTP](https://developer.ghn.vn/vi/docs/affiliate/get-otp.md). Dùng một lần: bị vô hiệu sau khi gọi thành công. OTP sai hoặc hết hạn sẽ lỗi `OTP_NOT_VALID`
- **address** (String): Địa chỉ lấy hàng của shop mới. Nếu bỏ trống, GHN lấy theo địa chỉ shop mặc định của chủ shop, rồi tới địa chỉ shop mặc định của bạn
- **district_id** (Int): Mã quận/huyện nội bộ GHN của shop mới, lấy từ [Lấy Quận/Huyện](https://developer.ghn.vn/vi/docs/master-data/get-district.md). Khi bằng `0`, dùng chuỗi fallback như `address`
- **ward_code** (String): Mã phường/xã nội bộ GHN của shop mới, lấy từ [Lấy Phường/Xã](https://developer.ghn.vn/vi/docs/master-data/get-ward.md). Khi bỏ trống, dùng chuỗi fallback như `address`
- **language** (String): Ngôn ngữ của `code_message_value` trong response lỗi. Mặc định `vi`.<br>`vi`: Tiếng Việt<br>`en`: Tiếng Anh

## Ví dụ Request

```bash
curl -X POST https://dev-online-gateway.ghn.vn/shiip/public-api/v2/shop/affiliateCreate \
  -H "Token: 5c1d8a9e-2f4b-11ed-..." \
  -H "ShopId: 92837" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "0987654321",
    "otp": "123456",
    "address": "72 Lê Thánh Tôn, P. Bến Nghé, Quận 1, TP. Hồ Chí Minh",
    "district_id": 1444,
    "ward_code": "20308"
  }'
```

## Response

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

Shop mới thuộc về khách hàng của bạn, không phải bạn. Tên shop do server sinh ra theo dạng `<tên khách hàng> - <tên đối tác của bạn>` (bạn không được tự đặt). Sau khi tạo, tài khoản của bạn tự động được thêm làm nhân viên của shop mới với bộ quyền member mặc định, để bạn vận hành thay khách hàng.

```json
{
  "code": 200,
  "message": "Success",
  "data": {
    "client_id": 1234567,
    "shop_id": 200996
  }
}
```

### 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.client_id` | Int | Mã tài khoản của chủ shop (khách hàng của bạn, tra từ `phone`) |
| `data.shop_id` | Int | Mã shop vừa được tạo |

### Lỗi — thiếu phone và otp (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: 'myRequest.Phone' Error:Field validation for 'Phone' failed on the 'required' tag\nKey: 'myRequest.OTP' Error:Field validation for 'OTP' failed on the 'required' tag",
  "data": null,
  "code_message": "USER_ERR_COMMON",
  "code_message_value": "Sai thông tin đầu vào. Vui lòng thử lại."
}
```

> **NOTE**
> Chuỗi tạo (tạo shop → thêm bạn làm nhân viên → cấp quyền → vô hiệu OTP) không phải atomic và không có rollback. Nếu lỗi ở giữa chừng (ví dụ ở bước thêm nhân viên) thì shop vẫn có thể đã được tạo dù bạn nhận về lỗi. Khi gặp lỗi, hãy kiểm tra bằng API Lấy Shop trước khi thử lại để tránh tạo trùng shop.

## Bảng mã lỗi

| Điều kiện | HTTP | code_message |
| --- | --- | --- |
| Thiếu `phone` hoặc `otp`, hoặc dữ liệu không hợp lệ | 400 | `USER_ERR_COMMON` |
| `otp` sai hoặc hết hạn | 400 | `OTP_NOT_VALID` |
| Số điện thoại chưa đăng ký tài khoản GHN | 400 | `USER_ERR_COMMON` |
| Bạn đã là nhân viên của shop được tạo | 400 | `CLIENT_HAVE_EXISTED` |
| Lỗi hệ thống | 500 | `SERVER_ERROR_COMMON` |
