Thêm Đánh Giá Sản Phẩm
API để thêm đánh giá/comment cho sản phẩm. Hỗ trợ xác minh mua hàng, đánh giá sao (1-5), upload ảnh và trả lời comment. Đánh giá mới sẽ có trạng thái "pending" và cần được duyệt trước khi hiển thị công khai.
POST https://api.socdo.vn/mini-app/v1/product-reviews
Request Headers
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Shop-ID: 23933 (hoặc từ token)
Content-Type: application/json
Request Body
Thêm đánh giá cơ bản
{
    "product_id": 4215,
    "content": "Sản phẩm đẹp, chất lượng tốt",
    "rating": 5,
    "shop_id": 20755
}
Thêm đánh giá với ảnh và xác minh mua hàng
{
    "product_id": 4215,
    "variant_id": 6338,
    "content": "Sản phẩm đẹp, chất lượng tốt, giao hàng nhanh",
    "rating": 5,
    "images": [
        "/uploads/comments/comment_4215_1760499276_8586.jpg",
        "/uploads/comments/comment_4215_1760499276_8587.jpg"
    ],
    "order_id": 18177,
    "shop_id": 20755
}
Lưu ý về xác minh mua hàng

Khi truyền order_id:

  • Hệ thống sẽ tự động kiểm tra đơn hàng thuộc về user và shop hiện tại
  • Đơn hàng phải có status >= 3 (đã xác nhận/đang giao/đã giao/hoàn thành)
  • Đơn hàng phải chứa product_id được đánh giá
  • Nếu có variant_id, đơn hàng phải chứa variant đó
  • Nếu tất cả điều kiện đều hợp lệ, is_verified_purchase sẽ tự động được set = 1
Trả lời comment (reply)
{
    "product_id": 4215,
    "content": "Cảm ơn bạn đã đánh giá!",
    "rating": 0,
    "parent_id": 1,
    "shop_id": 20755
}
Tham số
Tham số Loại Bắt buộc Mô tả
Authorization header JWT token từ API login (Bearer token)
Shop-ID header - ID shop (có thể lấy từ token nếu không có header)
product_id integer ID của sản phẩm cần đánh giá
content string Nội dung đánh giá
rating integer Đánh giá sao (1-5). Nếu reply comment thì có thể = 0
variant_id integer - ID phân loại sản phẩm (variant) nếu có
parent_id integer - ID comment cha (để reply comment). Mặc định: 0
images array - Mảng URL ảnh đính kèm (ví dụ: ["/uploads/comments/...", ...])
order_id integer - ID đơn hàng để xác minh mua hàng. Cần truyền cùng product_id (và variant_id nếu có). Hệ thống sẽ tự động kiểm tra đơn hàng thuộc user, shop, có status >= 3 và chứa sản phẩm. Nếu hợp lệ, tự động set is_verified_purchase = 1
Response thành công (200)
{
    "success": true,
    "message": "Thêm đánh giá thành công",
    "data": {
        "comment": {
            "id": 3,
            "product_id": 4215,
            "variant_id": null,
            "user_id": 34705,
            "shop_id": 20755,
            "parent_id": 0,
            "content": "Sản phẩm đẹp, chất lượng tốt",
            "rating": 5,
            "images": [
                "/uploads/comments/comment_4215_1760499276_8586.jpg"
            ],
            "is_verified_purchase": 1,
            "order_id": 18177,
            "likes_count": 0,
            "dislikes_count": 0,
            "status": "pending",
            "created_at": "2025-10-15 03:34:36",
            "updated_at": "2025-10-15 03:34:36",
            "is_pinned": 0
        },
        "is_verified_purchase": true
    }
}
Response lỗi (400 - Thiếu thông tin)
// Thiếu product_id
{
    "success": false,
    "message": "Thiếu product_id hoặc product_id không hợp lệ"
}

// Thiếu content
{
    "success": false,
    "message": "Nội dung đánh giá không được để trống"
}

// Rating không hợp lệ
{
    "success": false,
    "message": "Đánh giá phải từ 1 đến 5 sao"
}

// Shop ID không khớp
{
    "success": false,
    "message": "Sản phẩm không thuộc shop này"
}
Response lỗi (401 - Token không hợp lệ)
{
    "success": false,
    "message": "Token không hợp lệ - không có user_id"
}
Response lỗi (404 - Không tìm thấy sản phẩm)
{
    "success": false,
    "message": "Không tìm thấy sản phẩm"
}
Ví dụ JavaScript
// Thêm đánh giá cơ bản
async function addProductReview(productId, content, rating, shopId) {
    try {
        const authToken = localStorage.getItem('auth_token');
        
        if (!authToken) {
            throw new Error('Chưa đăng nhập');
        }
        
        const response = await fetch('https://api.socdo.vn/mini-app/v1/product-reviews', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${authToken}`,
                'Shop-ID': shopId.toString()
            },
            body: JSON.stringify({
                product_id: productId,
                content: content,
                rating: rating,
                shop_id: shopId
            })
        });
        
        const result = await response.json();
        
        if (result.success) {
            console.log('Thêm đánh giá thành công:', result.data.comment);
            console.log('Đã xác minh mua hàng:', result.data.is_verified_purchase);
            return result;
        } else {
            console.error('Lỗi:', result.message);
            return result;
        }
    } catch (error) {
        console.error('Lỗi kết nối:', error);
        return { success: false, message: 'Lỗi kết nối mạng' };
    }
}

// Thêm đánh giá với ảnh và xác minh mua hàng
async function addReviewWithImages(productId, content, rating, images, orderId, variantId, shopId) {
    try {
        const authToken = localStorage.getItem('auth_token');
        
        const requestBody = {
            product_id: productId,
            content: content,
            rating: rating,
            images: images,
            order_id: orderId,
            shop_id: shopId
        };
        
        // Thêm variant_id nếu có (để xác minh chính xác variant trong đơn hàng)
        if (variantId) {
            requestBody.variant_id = variantId;
        }
        
        const response = await fetch('https://api.socdo.vn/mini-app/v1/product-reviews', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${authToken}`,
                'Shop-ID': shopId.toString()
            },
            body: JSON.stringify(requestBody)
        });
        
        const result = await response.json();
        
        if (result.success) {
            console.log('Đánh giá đã được thêm:', result.data.comment);
            if (result.data.is_verified_purchase) {
                console.log('✅ Đánh giá này đã được xác minh mua hàng');
            } else {
                console.log('⚠️ Đánh giá chưa được xác minh mua hàng (kiểm tra order_id, product_id, variant_id)');
            }
            return result;
        }
    } catch (error) {
        console.error('Lỗi:', error);
    }
}

// Trả lời comment
async function replyToComment(productId, parentCommentId, content, shopId) {
    try {
        const authToken = localStorage.getItem('auth_token');
        
        const response = await fetch('https://api.socdo.vn/mini-app/v1/product-reviews', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${authToken}`,
                'Shop-ID': shopId.toString()
            },
            body: JSON.stringify({
                product_id: productId,
                content: content,
                rating: 0, // Reply không cần rating
                parent_id: parentCommentId,
                shop_id: shopId
            })
        });
        
        const result = await response.json();
        
        if (result.success) {
            console.log('Đã trả lời comment:', result.data.comment);
            return result;
        }
    } catch (error) {
        console.error('Lỗi:', error);
    }
}

// Sử dụng: Thêm đánh giá
addProductReview(4215, "Sản phẩm đẹp, chất lượng tốt", 5, 20755).then(result => {
    if (result.success) {
        alert('Thêm đánh giá thành công!');
    }
});

// Sử dụng: Thêm đánh giá với ảnh và xác minh mua hàng
addReviewWithImages(
    4215, 
    "Sản phẩm đẹp, chất lượng tốt, giao hàng nhanh",
    5,
    [
        "/uploads/comments/comment_4215_1760499276_8586.jpg"
    ],
    18177,  // order_id
    6338,   // variant_id (optional, nếu có)
    20755   // shop_id
);

// Sử dụng: Trả lời comment
replyToComment(4215, 1, "Cảm ơn bạn đã đánh giá!", 20755);
cURL Example
# Thêm đánh giá cơ bản
curl -X POST "https://api.socdo.vn/mini-app/v1/product-reviews" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Shop-ID: 20755" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 4215,
    "content": "Sản phẩm đẹp, chất lượng tốt",
    "rating": 5,
    "shop_id": 20755
}'

# Thêm đánh giá với ảnh và xác minh mua hàng
curl -X POST "https://api.socdo.vn/mini-app/v1/product-reviews" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Shop-ID: 20755" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 4215,
    "variant_id": 6338,
    "content": "Sản phẩm đẹp, chất lượng tốt, giao hàng nhanh",
    "rating": 5,
    "images": ["/uploads/comments/comment_4215_1760499276_8586.jpg"],
    "order_id": 18177,
    "shop_id": 20755
}'

# Trả lời comment
curl -X POST "https://api.socdo.vn/mini-app/v1/product-reviews" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Shop-ID: 20755" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 4215,
    "content": "Cảm ơn bạn đã đánh giá!",
    "rating": 0,
    "parent_id": 1,
    "shop_id": 20755
}'
Lưu ý quan trọng
  • User Token Required: API yêu cầu user token từ login (Bearer token trong Authorization header)
  • Status Mặc định: Đánh giá mới sẽ có status = "pending" và cần được admin duyệt trước khi hiển thị
  • Xác minh mua hàng: Nếu cung cấp order_idproduct_id, hệ thống sẽ tự động kiểm tra:
    • Đơn hàng thuộc về user hiện tại và shop hiện tại
    • Đơn hàng có trạng thái >= 3 (đã xác nhận/đang giao/đã giao/hoàn thành)
    • Đơn hàng chứa sản phẩm được đánh giá (product_id khớp)
    • Nếu có variant_id, kiểm tra variant_id cũng khớp với đơn hàng
    • Nếu hợp lệ, is_verified_purchase sẽ được tự động set = 1
  • Rating: Phải từ 1-5 sao. Nếu reply comment (parent_id > 0), có thể set = 0
  • Images: Mảng các URL ảnh. Cần upload ảnh trước và truyền URL vào đây
  • Thống kê tự động: Hệ thống tự động cập nhật product_rating_stats khi thêm đánh giá mới
  • Shop ID: Có thể lấy từ header Shop-ID hoặc từ token, nhưng phải khớp với shop của sản phẩm
  • Reply Comment: Để reply, set parent_id = ID của comment cha. Reply không cần rating
  • Format JSON đơn hàng: Hệ thống parse product từ format "sp_id__variant_id" (ví dụ: "81633__6338") trong đơn hàng. Nếu không có variant, format là "81633__"
Cấu trúc Database

API tự động lưu vào 2 bảng:

  • product_comments: Lưu đánh giá với các trường: product_id, user_id, content, rating, images, is_verified_purchase, status, etc.
  • product_rating_stats: Tự động cập nhật thống kê: total_reviews, average_rating, rating_5, rating_4, rating_3, rating_2, rating_1
API Liên Quan