# 棒棒玛特 API Reference
Read endpoints are HTTP GET with query string params. Mutating/auth endpoints (`/shop/checkout`, `/shop/orders`) are HTTP POST with a JSON body.
## 常见问题 / FAQ
**读接口和写接口有什么区别?**
只读接口(`GET /shop/products`、`GET /shop/search`、`GET /shop/product`、`GET /shop/pay`、`GET /shop/order`)通过 URL 查询参数传参。写/鉴权接口(`POST /shop/checkout`、`POST /shop/orders`)使用 JSON body 传参,并需要 `api_key` 字段。
**API Key 是什么?**
API Key 是一个以 `sk_` 开头的字符串,用于在结账和订单列表接口中识别用户身份。请访问 [/human/account](/human/account) 登录并生成 API Key。
**Can I place a multi-item order in a single checkout call?**
Yes. Pass a `items` field in the POST `/shop/checkout` JSON body as a comma-separated string: `product_id:qty,product_id:qty` (e.g. `p_snacks_0001:2,p_snacks_0014:1`). Alternatively use `product_id` + `qty` for single-item orders.
**/shop/products 和 /shop/search 有什么区别?**
`/shop/products` 返回完整商品目录,`q` 为可选过滤,支持按标签、价格、促销筛选,默认按销量排序。`/shop/search` 以 `q`(关键词)为必填参数,专为全文语义搜索设计,支持自动重排序。
**如何获取某个分类的所有商品?**
使用 `GET /shop/products?q=坚果` 或 `GET /shop/search?q=牛肉干` 按关键词搜索,或直接访问分类页面:[零食](/human/shop/category/snacks)、[饮品](/human/shop/category/beverages)、[坚果](/human/shop/category/nuts)、[牛肉干](/human/shop/category/beef-jerky)、[特价](/human/shop/category/on-sale)。
---
## GET /shop/products
Browse the product catalog. All params optional.
- `q` — keyword search across title, variant, and tags
- `price_min`, `price_max` — price range in CNY
- `on_sale=true` — on-sale items only
- `sort` — `price_asc`, `price_desc`, `sales_desc` (default: `sales_desc`)
- `limit` — max results, 30–200 (default: 100)
Example: `/shop/products?on_sale=true&price_max=40&sort=price_asc`
## GET /shop/search
Keyword search across product title, variant, and tags.
- `q` *(required)* — search keyword
- `price_min`, `price_max` — price range in CNY
- `on_sale=true` — on-sale items only
- `sort` — `relevance` (default), `price_asc`, `price_desc`, `sales_desc`
- `limit` — max results, 30–200 (default: 100)
Example: `/shop/search?q=坚果&price_max=60&on_sale=true`
## GET /shop/product
Fetch details for a single product.
- `product_id` *(required)* — e.g. `p_snacks_0001`
Example: `/shop/product?product_id=p_snacks_0001`
## POST /shop/checkout
Create an order and get a payment link. Requires `api_key`.
Request body (JSON or form-encoded):
- `api_key` _(required)_ — API key (starts with `sk_`). Sign in at [/human/account](/human/account) to generate one.
- `product_id` + `qty` — single-item order
- `items` — multi-item order: `PRODUCT_ID:QTY,PRODUCT_ID:QTY` (use instead of `product_id`/`qty`)
- `note` — optional order note
Examples:
```
POST /shop/checkout
{"api_key":"sk_...","product_id":"p_snacks_0001","qty":2}
POST /shop/checkout
{"api_key":"sk_...","items":"p_snacks_0001:2,p_snacks_0014:1","note":"办公室分享"}
```
On success, returns order ID and a payment link (`/shop/pay?order_id=ORDER_ID`). Present the payment link to the user so they can click it.
## GET /shop/pay
Payment page for an order. Present this link to the user after checkout.
- `order_id` *(required)* — e.g. `ord_1a2b3c4d`
Example: `/shop/pay?order_id=ord_1a2b3c4d`
## GET /shop/order
Look up status of any order.
- `order_id` *(required)* — e.g. `ord_1a2b3c4d`
Example: `/shop/order?order_id=ord_1a2b3c4d`
## POST /shop/orders
List all orders for the authenticated viewer. Requires `api_key`.
Request body (JSON or form-encoded):
- `api_key` _(required)_ — API key (starts with `sk_`). Sign in at [/human/account](/human/account) to generate one.
Example:
```
POST /shop/orders
{"api_key":"sk_..."}
```