Chuyển tới nội dung chính

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

🔗Endpoint Staging
PATCH https://staging-manage.api.miniai.vn/api/external/v1/products/{product-id}
Example
https://staging-manage.api.miniai.vn/api/external/v1/products/68c93dba802d36826bc45c9c
🔗Endpoint Production
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ệuYêu cầuMô tả
product-idstringBắt buộcID của sản phẩm cần cập nhật

Dữ liệu yêu cầu (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ườngKiểu dữ liệuYêu cầuMô tả
shopIdstringBắt buộcID của shop sở hữu sản phẩm
namestringTùy chọnTên sản phẩm
slugstringTùy chọnĐường dẫn thân thiện (SEO) của sản phẩm
aliasNamestringTùy chọnTên gợi nhớ nội bộ
descriptionstringTùy chọnMô tả sản phẩm
pricenumberTùy chọnGiá bán
originPricenumberTùy chọnGiá gốc
categoryIdstringTùy chọnID danh mục sản phẩm
statusstringTùy chọnTrạng thái sản phẩm: active hoặc inactive
vatnumberTùy chọnThuế VAT (%)
imagesarray<string>Tùy chọnDanh sách URL hình ảnh sản phẩm
itemSkustringTùy chọnMã SKU chung của sản phẩm
barcodestringTùy chọnMã vạch sản phẩm
variantMatrixobjectTùy chọnToàn bộ cấu trúc biến thể + SKU của sản phẩm (xem mục riêng)
Ghi chú
  • Chỉ shopId là 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 sinh slug mới dựa trên name.
  • 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 trong variantMatrix.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.

🔒Chỉ áp dụng cho sản phẩm tạo trên MiniAI

variantMatrix chỉ có hiệu lực khi sản phẩm thoả cả hai điều kiện:

  • platform = mini_app
  • type khác combo

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 đè.

platformSử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
🔇Bị bỏ qua trong im lặ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.

🛑Đây là thao tác GHI ĐÈ TOÀN BỘ, không phải cập nhật từng phần

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 payloadHậu quả
SKUChuyể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: keyid

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ần key; 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ườngChứa giá trị gì
variants[].options[].itemVariantIdkey của nhóm biến thể cha — không phải ID thật
skus[].variantOptions[].idkey 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ườngKiểuYêu cầuMô tả
keystringBắt buộcMã tạm của nhóm, do bạn đặt
namestringBắt buộcTên nhóm, ví dụ Đơn vị tính
idstringTùy chọnID thật nếu nhóm đã tồn tại
optionsarrayBắt buộcDanh sách tùy chọn của nhóm
options[].keystringBắt buộcMã tạm của tùy chọn, do bạn đặt
options[].namestringBắt buộcTên tùy chọn, ví dụ Thùng
options[].itemVariantIdstringBắt buộckey của nhóm cha
options[].idstringTùy chọnID 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ườngKiểuYêu cầuMô tả
namestringBắt buộcTên hiển thị của biến thể
pricenumberBắt buộcGiá bán riêng của biến thể này
variantOptionsarrayBắt buộcCác tùy chọn tạo nên biến thể
variantOptions[].idstringBắt buộckey của tùy chọn
idstringTùy chọnID thật nếu SKU đã tồn tại
originPricenumberTùy chọnGiá gốc (giá gạch ngang)
skustringTùy chọnMã SKU riêng của biến thể
barcodestringTùy chọnMã vạch riêng của biến thể
imagestringTùy chọnẢnh riêng của biến thể
dimensionobjectTùy chọnlength, 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ỉ priceoriginPrice 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" }]
}
]
}
}
Lưu ý thêm
  • Mã trong skus[].sku phả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 variantMatrix với skus khá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 variantMatrix khi 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)

{
"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"
}
}