# 创建与更新商品

> 用 Open API 在 Shoplazza 店铺里创建、更新、上下架和删除商品，并说明新建商品为何默认是草稿。

使用 Open API 创建商品、更新商品字段、上架或下架商品，以及删除商品。在这里创建的商品初始状态为草稿，上架后才会在店铺前台可见。

## 适用场景

从你的应用发布新商品、批量导入商品目录，或搭建商品管理后台。

## 前置条件

- 一个已完成 OAuth 授权与 token 存储的公开应用——先完成 [开发独立应用](/docs/app/getting-started/create-public-app/develop-app)。下面的每个请求都带 `Access-Token: {token}` 头，使用你为每个店铺保存的 token。
- OAuth 授权时已获得 `product` 访问权限范围。

## 工作原理

商品通过一次调用构建完成：`options`、`variants`、`images` 都内联在同一个请求里。

- 对于带选项（如尺码、颜色）的商品，需将 `has_only_default_variant` 设为 `false`，声明 `options`，并为每个变体设置与之对应的 `option1` 值——同时设置 `need_variant_image: false`。
- 若 `inventory_tracking: true`，还需要传 `inventory_policy`。
- `images` 必须包含至少一张图片。
- 商品创建后初始状态为**草稿**，只有将 `published` 置为 `true`（或用 `auto_publish_at` 定时）才会上架。

### 创建商品

商品通过一次调用创建：请求体将所有字段嵌套在 `product` 下。`title`、`has_only_default_variant`、`images`、`variants` 均为必填，且每个变体都需要 `price`。

`POST /openapi/2026-01/products`

请求体：

```json5
{
  "product": {
    "title": "Summer cotton T-shirt",
    "published": false,          // 先作为草稿创建，之后再上架
    "has_only_default_variant": false,
    "need_variant_image": false, // has_only_default_variant 为 false 时必填
    "inventory_tracking": true,
    "inventory_policy": "deny",  // inventory_tracking 为 true 时必填
    "options": [{ "name": "Size", "values": ["S", "M"] }],
    "images": [{ "src": "https://cdn.example.com/tshirt.jpg" }], // 至少一张图片
    "variants": [
      { "option1": "S", "price": 19.9, "sku": "TS-S", "inventory_quantity": 100, "position": 1 },
      { "option1": "M", "price": 19.9, "sku": "TS-M", "inventory_quantity": 100, "position": 2 }
    ]
  }
}
```

响应（节选，创建的商品在 `data.data.product` 下）：

```json
{
  "code": "Success",
  "data": {
    "product": {
      "id": "4d3e7859-455c-4899-a296-7befe731c585",
      "title": "Summer cotton T-shirt",
      "handle": "summer-cotton-t-shirt",
      "inventory_tracking": true,
      "inventory_policy": "deny",
      "options": [
        { "id": "bca26b9d-c3f1-48ac-93aa-e4a975c44dce", "name": "Size", "values": ["S", "M"], "position": 1 }
      ],
      "variants": [
        { "id": "28ea5ee4-5b1d-4a9d-a92e-e60f0dff3da8", "title": "S", "option1": "S", "position": 1, "price": 19.9, "sku": "TS-S", "inventory_quantity": 100 }
      ],
      "price_min": 19.9,
      "price_max": 19.9,
      "created_at": "2026-07-02T02:57:25Z",
      "updated_at": "2026-07-02T02:57:25Z"
    }
  }
}
```

:::note
`images` 必须包含至少一项——传空数组会被拒绝，返回 `value must contain at least 1 item(s)`。请把图片托管到可公开访问的地址，并将该 URL 作为 `src` 传入。完整请求体见 [创建商品](/api/product-create)。
:::

### 获取商品

按 id 获取单个商品。

`GET /openapi/2026-01/products/{id}`

响应（节选）：完整商品对象，包含 `options[]`、`images[]`、`variants[]`、`primary_image`，以及 `id`、`title`、`handle`、`inventory_tracking`、`inventory_policy`、`price_min`、`price_max`、`created_at`、`updated_at`。

完整字段见 [获取商品](/api/product-detail)。

### 更新商品

使用 `PUT` 修改商品级字段（标题、描述、标签等）。只有你传入的字段会被修改。

`PUT /openapi/2026-01/products/{id}`

请求体：

```json5
{
  "product": {
    "title": "Summer cotton T-shirt (2026)" // 只传要改的字段
  }
}
```

返回更新后的商品。可编辑字段详见 [更新商品](/api/product-update) 参考文档。

### 上架与下架

上架本质上就是设置 `published` 字段。设为 `true` 使商品在店铺前台可见，设为 `false` 则重新隐藏——两个方向用的是同一个 `PUT` 接口。

`PUT /openapi/2026-01/products/{id}`

请求体：

```json5
{
  "product": {
    "published": true // 传 false 即可下架
  }
}
```

响应（节选，与创建响应结构相同，`published_at` 已填上具体时间）：

```json
{
  "code": "Success",
  "data": {
    "product": {
      "id": "4d3e7859-455c-4899-a296-7befe731c585",
      "title": "Summer cotton T-shirt",
      "published": true,
      "published_at": "2026-07-02T02:58:55Z"
    }
  }
}
```

上架后，可以通过 `https://<shop>/products/<handle>` 在店铺前台访问该商品。

:::note
如需定时上架，可在创建或更新时设置 `auto_publish_at`（RFC 3339 格式）。如需在售罄时自动下架，设置 `inventory_policy: auto_unpublished`。详见 [创建商品](/api/product-create)。
:::

### 删除商品

`DELETE /openapi/2026-01/products/{id}`

响应：

```json
{ "code": "Success", "data": {} }
```

见 [删除商品](/api/product-delete)。

如需批量删除，使用 `DELETE /products?product_ids=id1,id2`——见 [批量删除商品](/api/product-batch-delete)。

### 列出商品

列表接口使用游标分页（`cursor` 配合 `per_page`，最大 250），并支持 `title`、`collection_id`、`published_status` 等过滤条件。

`GET /openapi/2026-01/products`

响应（节选，列表在 `data.data.products` 下，游标在 `data.data.cursor` 下）：

```json
{
  "code": "Success",
  "data": {
    "cursor": "MjAyNi0wMS0yM1QxMDowODoyN1o...",
    "products": [
      {
        "id": "ac7783d3-df2d-47fe-abca-7ee3d9bceb04",
        "title": "T-shirt",
        "handle": "t-shirt",
        "inventory_quantity": 666,
        "price_min": 11,
        "price_max": 33,
        "created_at": "2026-07-01T09:25:50Z"
      }
    ]
  }
}
```

完整过滤条件见 [商品列表](/api/products)。

只需要总数时，用 `GET /products/count`——见 [统计商品数量](/api/product-count)。

## 下一步

- [管理变体与图片](/docs/app/use-cases/product-merchandising/manage-variants-and-images)
- [组织商品集合](/docs/app/use-cases/product-merchandising/organize-collections)
