Cập nhật thông tin sản phẩm
API này giúp bạn cập nhật thông tin của một sản phẩm đã tồn tại trong hệ thống, dựa trên product-id được cung cấp trong URL.
Bạn chỉ cần truyền các trường muốn thay đổi trong request body — các trường không truyền sẽ được giữ nguyên giá trị hiện tại.
Endpoint
PATCH https://staging-manage.api.miniai.vn/api/external/v1/products/{product-id}
https://staging-manage.api.miniai.vn/api/external/v1/products/68c93dba802d36826bc45c9c
PATCH https://manage-api.miniap.vn/api/external/v1/products/{product-id}
Tham số đường dẫn (Path Params)
| Tham số | Kiểu dữ liệu | Yêu cầu | Mô tả |
|---|---|---|---|
product-id | string | Bắt buộc | ID của sản phẩm cần cập nhật |
Dữ liệu yêu cầu (Request Body)
- Request Body
{
"shopId": "64204a17a5a97a86f12e1f0a",
"name": "Tên sản phẩm (đã cập nhật)",
"slug": "ten-san-pham-da-cap-nhat",
"aliasName": "Tên gợi nhớ nội bộ",
"description": "Mô tả sản phẩm mới",
"price": 25000,
"originPrice": 20000,
"categoryId": "685ba1be4792d338d2ec3cbe",
"status": "active",
"vat": 5,
"images": [
"https://dmcl0k8mc5oht.cloudfront.net/64204a17a5a97a86f12e1f0a/e888246f-2647-42f1-9d89-53eacdb7bf64.webp"
],
"itemSku": "Sku",
"barcode": "12344"
}
| Trường | Kiểu dữ liệu | Yêu cầu | Mô tả |
|---|---|---|---|
shopId | string | Bắt buộc | ID của shop sở hữu sản phẩm |
name | string | Tùy chọn | Tên sản phẩm |
slug | string | Tùy chọn | Đường dẫn thân thiện (SEO) của sản phẩm |
aliasName | string | Tùy chọn | Tên gợi nhớ nội bộ |
description | string | Tùy chọn | Mô tả sản phẩm |
price | number | Tùy chọn | Giá bán |
originPrice | number | Tùy chọn | Giá gốc |
categoryId | string | Tùy chọn | ID danh mục sản phẩm |
status | string | Tùy chọn | Trạng thái sản phẩm: active hoặc inactive |
vat | number | Tùy chọn | Thuế VAT (%) |
images | array<string> | Tùy chọn | Danh sách URL hình ảnh sản phẩm |
itemSku | string | Tùy chọn | Mã SKU chung của sản phẩm |
barcode | string | Tùy chọn | Mã vạch sản phẩm |
variantMatrix | object | Tùy chọn | Toàn bộ cấu trúc biến thể + SKU của sản phẩm (xem mục riêng) |
- Chỉ
shopIdlà bắt buộc, các trường còn lại đều tùy chọn — chỉ gửi trường nào bạn muốn thay đổi. - Nếu không truyền
slug, hoặc sản phẩm hiện chưa cóslug, hệ thống sẽ tự động sinhslugmới dựa trênname. price/originPriceở cấp gốc chỉ áp cho sản phẩm không có biến thể. Với sản phẩm nhiều biến thể, giá của từng biến thể nằm trongvariantMatrix.skus[].
variantMatrix — cập nhật giá theo từng SKU
Dùng khi sản phẩm có nhiều biến thể và mỗi biến thể có giá / barcode riêng — ví dụ bán theo đơn vị tính Lẻ / Lốc / Thùng.
variantMatrix chỉ có hiệu lực khi sản phẩm thoả cả hai điều kiện:
platform=mini_apptypekháccombo
Sản phẩm đồng bộ từ hệ thống bán hàng khác thì kh ông sửa được biến thể qua API này — nguồn dữ liệu gốc nằm ở hệ thống đó, sửa ở MiniAI sẽ bị lần đồng bộ kế tiếp ghi đè.
platform | Sửa biến thể qua variantMatrix |
|---|---|
mini_app — tạo trực tiếp trên MiniAI | ✅ Được |
haravan, sapo, nhanh, kiotviet, odoo, pancakepos, mini_pos | ❌ Không |
Gửi variantMatrix cho sản phẩm không đủ điều kiện, API vẫn trả 200 success nhưng biến thể không hề thay đổi — không có cảnh báo nào.
Luôn kiểm tra trước bằng GET /v1/products/{id} và đọc trường platform. Sau khi PATCH, gọi lại GET /v1/products/{id}?select=skus,variants để xác nhận giá đã đổi thật.
Ràng buộc liên quan: với sản phẩm platform khác mini_app, đổi price ở cấp sản phẩm cũng bị từ chối kèm lỗi You can not update this item price. Gửi lại đúng giá hiện tại thì không lỗi. Các trường còn lại (name, description, images, status, categoryId…) vẫn sửa được bình thường ở mọi platform.
Khác với các trường còn lại của API này, variantMatrix thay thế toàn bộ cấu trúc biến thể hiện có. Mọi thứ không xuất hiện trong payload sẽ bị xoá:
| Đối tượng bị thiếu trong payload | Hậu quả |
|---|---|
| SKU | Chuyển sang isActive: false (ngừng bán) |
| Nhóm biến thể | Xoá vĩnh viễn |
| Tùy chọn biến thể | Xoá vĩnh viễn |
Quy trình bắt buộc: gọi GET /v1/products/{id}?select=skus,variants để lấy cấu trúc hiện tại → sửa những giá trị cần đổi → gửi lại nguyên vẹn toàn bộ danh sách.
Mỗi SKU / nhóm / tùy chọn đã tồn tại phải kèm id thật của nó. Thiếu id, hệ thống sẽ coi đó là bản ghi mới: tạo thêm bản trùng và vô hiệu hoá bản cũ.
Cách liên kết 3 tầng: key và id
Payload có 3 tầng — nhóm biến thể → tùy chọn → SKU. Việc nối nhóm với tùy chọn, và tùy chọn với SKU, không dùng ID thật mà dùng key:
key— mã tạm do bạn tự đặt, chỉ có ý nghĩa trong phạm vi một request. Đặt gì cũng được ("dvt","1","unit-le"…), miễn không trùng nhau. Chỉ nhóm biến thể và tùy chọn cầnkey; SKU thì không.id— ID thật trong hệ thống MiniAI. Chỉ gửi khi bản ghi đã tồn tại. Bỏ trống để tạo mới.
Hai chỗ dễ nhầm nhất:
| Trường | Chứa giá trị gì |
|---|---|
variants[].options[].itemVariantId | key của nhóm biến thể cha — không phải ID thật |
skus[].variantOptions[].id | key của tùy chọn — không phải ID thật |
Cấu trúc
variantMatrix.variants[] — nhóm biến thể:
| Trường | Kiểu | Yêu cầu | Mô tả |
|---|---|---|---|
key | string | Bắt buộc | Mã tạm của nhóm, do bạn đặt |
name | string | Bắt buộc | Tên nhóm, ví dụ Đơn vị tính |
id | string | Tùy chọn | ID thật nếu nhóm đã tồn tại |
options | array | Bắt buộc | Danh sách tùy chọn của nhóm |
options[].key | string | Bắt buộc | Mã tạm của tùy chọn, do bạn đặt |
options[].name | string | Bắt buộc | Tên tùy chọn, ví dụ Thùng |
options[].itemVariantId | string | Bắt buộc | key của nhóm cha |
options[].id | string | Tùy chọn | ID thật nếu tùy chọn đã tồn tại |
Thứ tự hiển thị của tùy chọn lấy theo thứ tự phần tử trong mảng options — muốn đổi thứ tự thì sắp xếp lại mảng.
variantMatrix.skus[] — từng biến thể bán được:
| Trường | Kiểu | Yêu cầu | Mô tả |
|---|---|---|---|
name | string | Bắt buộc | Tên hiển thị của biến thể |
price | number | Bắt buộc | Giá bán riêng của biến thể này |
variantOptions | array | Bắt buộc | Các tùy chọn tạo nên biến thể |
variantOptions[].id | string | Bắt buộc | key của tùy chọn |
id | string | Tùy chọn | ID thật nếu SKU đã tồn tại |
originPrice | number | Tùy chọn | Giá gốc (giá gạch ngang) |
sku | string | Tùy chọn | Mã SKU riêng của biến thể |
barcode | string | Tùy chọn | Mã vạch riêng của biến thể |
image | string | Tùy chọn | Ảnh riêng của biến thể |
dimension | object | Tùy chọn | length, width, height, weight |
Ví dụ — đổi giá Lẻ / Lốc / Thùng
Cả 3 biến thể đã tồn tại nên đều kèm id; chỉ price và originPrice thay đổi.
{
"shopId": "64204a17a5a97a86f12e1f0a",
"variantMatrix": {
"variants": [
{
"id": "6a55f75ab1047f301c36e062",
"key": "dvt",
"name": "Đơn vị tính",
"options": [
{ "id": "6a55f75ab1047f301c36e064", "key": "le", "name": "Lẻ", "itemVariantId": "dvt" },
{ "id": "6a55f75ab1047f301c36e065", "key": "loc", "name": "Lốc", "itemVariantId": "dvt" },
{ "id": "6a55f75ab1047f301c36e066", "key": "thung", "name": "Thùng", "itemVariantId": "dvt" }
]
}
],
"skus": [
{
"id": "6a55f75ab1047f301c36e06a",
"name": "Lẻ",
"price": 12000,
"originPrice": 15000,
"barcode": "8938500001001",
"variantOptions": [{ "id": "le" }]
},
{
"id": "6a55f75ab1047f301c36e06b",
"name": "Lốc",
"price": 68000,
"originPrice": 75000,
"barcode": "8938500001002",
"variantOptions": [{ "id": "loc" }]
},
{
"id": "6a55f75ab1047f301c36e06c",
"name": "Thùng",
"price": 380000,
"originPrice": 420000,
"barcode": "8938500001003",
"variantOptions": [{ "id": "thung" }]
}
]
}
}
- Mã trong
skus[].skuphải không trùng với SKU của sản phẩm khác trong cùng shop, và không trùng nhau trong cùng payload — vi phạm sẽ bị từ chối. - Nếu sản phẩm đang không có biến thể, gửi
variantMatrixvớiskuskhác rỗng sẽ chuyển nó thành sản phẩm có biến thể và vô hiệu hoá SKU mặc định. - Chỉ gửi
variantMatrixkhi thực sự muốn thay đổi cấu trúc biến thể. Đổi tên, mô tả hay ảnh sản phẩm thì không cần gửi trường này.
Phản hồi (Response)
- Response
{
"success": true,
"message": "success",
"data": {
"_id": "68c93dba802d36826bc45c9c",
"type": "product",
"name": "Tên sản phẩm (đã cập nhật)",
"description": "Mô tả sản phẩm mới",
"search": "ten san pham da cap nhat sku 12344",
"images": [
"https://dmcl0k8mc5oht.cloudfront.net/64204a17a5a97a86f12e1f0a/e888246f-2647-42f1-9d89-53eacdb7bf64.webp"
],
"subItemsGroupIds": [],
"price": 25000,
"originPrice": 20000,
"configs": [],
"tags": "",
"hashtags": [],
"canBook": false,
"shopId": "64204a17a5a97a86f12e1f0a",
"collectionIDs": [],
"status": "active",
"totalRating": 0,
"totalReview": 0,
"reservedQuantity": 0,
"totalQuantity": 0,
"isNullSortOrder": true,
"isCustomerInquiry": false,
"platform": "mini_app",
"brandProductIds": [],
"fakeReviewIds": [],
"comboItems": [],
"createdAt": "2025-09-16T10:36:42.809Z",
"updatedAt": "2025-09-16T11:02:10.221Z",
"__v": 0,
"customPriceId": null,
"slug": "ten-san-pham-da-cap-nhat",
"updatedBy": "64204a17a5a97a86f12e1f0a",
"virtualSold": 0,
"aliasName": "Tên gợi nhớ nội bộ",
"barcode": "12344",
"categoryId": "685ba1be4792d338d2ec3cbe",
"itemSku": "Sku",
"vat": 5,
"id": "68c93dba802d36826bc45c9c"
}
}