Tài Liệu API Shop

URL Cơ Sở

https://shop-api.unicode.vn

Xác Thực

Nhiều endpoint yêu cầu xác thực JWT. Thêm token vào header Authorization:

Authorization: Bearer <jwt_token_của_bạn>

Các Endpoint

Xác Thực (Authentication)

Đăng Ký

POST /auth/register

Tạo tài khoản người dùng mới.

Body của Request:

{ "fullName": "string", "email": "string", "password": "string", "phone": "string" }

Quy Tắc Kiểm Tra:

Response:

{ "accessToken": "string", "refreshToken": "string", "user": { "id": "string", "fullName": "string", "email": "string", "phone": "string" } }

Đăng Nhập

POST /auth/login

Đăng nhập với tài khoản đã có.

Body của Request:

{ "email": "string", "password": "string" }

Response:

{ "accessToken": "string", "refreshToken": "string", "user": { "id": "string", "fullName": "string", "email": "string", "phone": "string" } }

Làm Mới Token

POST /auth/refresh

Làm mới token khi access token hết hạn.

Body của Request:

{ "refreshToken": "string" }

Response:

{ "accessToken": "string", "refreshToken": "string", "user": { "id": "string", "fullName": "string", "email": "string", "phone": "string" } }

Response khi token không hợp lệ hoặc đã bị thu hồi:

{ "message": "Token không hợp lệ" }

Đăng nhập với Google

1. Lấy URL đăng nhập Google
GET /auth/google/url

Trả về URL để frontend redirect user đến trang đăng nhập Google.

Response:

{ "url": "https://accounts.google.com/o/oauth2/v2/auth?..." }
2. Xử lý callback từ Google
GET /auth/google/callback?code=...

Backend xử lý xác thực Google, tạo user nếu chưa có, sinh accessToken và refreshToken (JWT của hệ thống). Sau đó backend sẽ redirect về frontend với các token này qua URL:

/auth/google/success?accessToken=...&refreshToken=...
3. Lấy thông tin user sau khi đăng nhập Google
GET /auth/google/success?accessToken=...&refreshToken=...

Frontend gọi endpoint này để lấy thông tin user và xác thực token.

Response:

{ "user": { "id": "string", "fullName": "string", "email": "string", "phone": "string" }, "accessToken": "string", "refreshToken": "string" }

Lưu ý:

Đăng Xuất

POST /auth/logout

Đăng xuất và vô hiệu hóa token hiện tại.

Yêu Cầu Xác Thực:

Response:

{ "message": "Đăng xuất thành công" }

Response khi token không hợp lệ:

{ "message": "Token không hợp lệ" }

Quản Lý Mật Khẩu

Đổi Mật Khẩu

PATCH /profile/change-password

Thay đổi mật khẩu của người dùng hiện tại.

Yêu Cầu Xác Thực:

Body của Request:

{ "currentPassword": "string", "newPassword": "string", "confirmPassword": "string" }

Quy Tắc Kiểm Tra:

Response khi thành công:

{ "message": "Đổi mật khẩu thành công" }

Response khi sai mật khẩu hiện tại:

{ "message": "Lỗi kiểm tra dữ liệu", "errors": { "currentPassword": "Mật khẩu hiện tại không đúng" } }

Quản Lý Quốc Gia

Lấy Danh Sách Quốc Gia

GET /countries

Lấy danh sách tất cả các quốc gia có sẵn.

Yêu Cầu Xác Thực: Không

Response:

{ "countries": [ { "name": "string", "code": "string" } ] }

Lấy Chi Tiết Quốc Gia

GET /countries/:code

Lấy thông tin chi tiết của một quốc gia, bao gồm danh sách các tỉnh/thành phố.

Yêu Cầu Xác Thực: Không

Response:

{ "country": { "name": "string", "code": "string", "states": ["string"] } }

Quản Lý Địa Chỉ

Lấy Danh Sách Địa Chỉ

GET /addresses

Lấy danh sách địa chỉ của người dùng hiện tại.

Yêu Cầu Xác Thực:

Response:

{ "addresses": [ { "id": "string", "name": "string", "country": "string", "address": "string", "mobileNumber": "string", "alternativeMobileNumber": "string", "pincode": "string", "city": "string", "state": "string", "isDefault": boolean } ] }

Thêm Địa Chỉ Mới

POST /addresses

Thêm một địa chỉ mới cho người dùng.

Yêu Cầu Xác Thực:

Body của Request:

{ "name": "string", "country": "string", "address": "string", "mobileNumber": "string", "alternativeMobileNumber": "string", // không bắt buộc "pincode": "string", "city": "string", "state": "string", "isDefault": boolean // không bắt buộc }

Quy Tắc Kiểm Tra:

Response:

{ "address": { "id": "string", "name": "string", "country": "string", "address": "string", "mobileNumber": "string", "alternativeMobileNumber": "string", "pincode": "string", "city": "string", "state": "string", "isDefault": boolean } }

Cập Nhật Địa Chỉ

PUT /addresses/:addressId

Cập nhật thông tin của một địa chỉ.

Yêu Cầu Xác Thực:

Body của Request: Giống như khi thêm địa chỉ mới

Response: Giống như khi thêm địa chỉ mới

Xóa Địa Chỉ

DELETE /addresses/:addressId

Xóa một địa chỉ.

Yêu Cầu Xác Thực:

Response:

{ "message": "Đã xóa địa chỉ thành công" }

Đặt Làm Địa Chỉ Mặc Định

PATCH /addresses/:addressId/default

Đặt một địa chỉ làm địa chỉ mặc định.

Yêu Cầu Xác Thực:

Response:

{ "address": { "id": "string", "name": "string", "country": "string", "address": "string", "mobileNumber": "string", "alternativeMobileNumber": "string", "pincode": "string", "city": "string", "state": "string", "isDefault": true } }

Quản Lý Hồ Sơ (Profile)

Xem Thông Tin Cá Nhân

GET /profile

Lấy thông tin hồ sơ của người dùng hiện tại.

Yêu Cầu Xác Thực:

Response:

{ "user": { "id": "string", "fullName": "string", "email": "string", "phone": "string", "birthDate": "string (YYYY-MM-DD)" } }

Cập Nhật Thông Tin Cá Nhân

PATCH /profile

Cập nhật thông tin hồ sơ của người dùng hiện tại.

Yêu Cầu Xác Thực:

Body của Request:

{ "fullName": "string", // không bắt buộc "phone": "string", // không bắt buộc "birthDate": "string" // không bắt buộc, định dạng: YYYY-MM-DD }

Quy Tắc Kiểm Tra:

Response:

{ "user": { "id": "string", "fullName": "string", "email": "string", "phone": "string", "birthDate": "string (YYYY-MM-DD)" } }

Quản Lý Giỏ Hàng - Hành Động

Lấy thông tin giỏ hàng

GET /shopping-cart

Yêu cầu xác thực. Trả về danh sách sản phẩm trong giỏ hàng của user hiện tại.

Response:

{ "items": [ { "productId": "string", "name": "string", "image": "string", "avgRating": 4.5, "reviewCount": 12, "priceDiscount": 90000, "price": 100000, "brand": "string", "warranty": "2 năm", "shippingFee": 15000, "quantity": 2, "total": 180000 } ], "total": 180000 }

Thêm sản phẩm vào giỏ hàng

POST /shopping-cart

Yêu cầu xác thực. Thêm sản phẩm vào giỏ hàng của user hiện tại.

Body của Request:

{ "productId": "string", "quantity": 2 }

Response khi thành công:

{ "message": "Đã thêm vào giỏ hàng" }

Xóa toàn bộ giỏ hàng

DELETE /shopping-cart

Yêu cầu xác thực. Xóa toàn bộ sản phẩm trong giỏ hàng của user.

Response:

{ "message": "Đã xóa toàn bộ giỏ hàng" }

Xóa một sản phẩm khỏi giỏ hàng

DELETE /shopping-cart/:productId

Yêu cầu xác thực. Xóa một sản phẩm khỏi giỏ hàng theo productId.

Response:

{ "message": "Đã xóa sản phẩm khỏi giỏ hàng" }

Cập nhật số lượng sản phẩm trong giỏ hàng

PATCH /shopping-cart/:productId

Yêu cầu xác thực. Cập nhật số lượng sản phẩm trong giỏ hàng theo productId.

Body:

{ "quantity": 2 }

Response:

{ "message": "Đã cập nhật số lượng sản phẩm" }

Gợi Ý Sản Phẩm Cho Giỏ Hàng

Sản phẩm liên quan đến giỏ hàng (You might also like)

GET /cart-suggest/you-might-also-like

Yêu cầu xác thực. Trả về danh sách sản phẩm liên quan đến các sản phẩm trong giỏ hàng (cùng danh mục hoặc thương hiệu, loại trừ sản phẩm đã có trong giỏ).

Response:

{ "products": [ { "_id": "string", "name": "string", "image": "string", "price": 100000, "priceDiscount": 90000, "brand": "string", "warranty": "2 năm", "shippingFee": 15000, "avgRating": 4.5, "reviewCount": 12, "category": "categoryId" } ] }
GET /cart-suggest/recommended

Trả về danh sách sản phẩm nổi bật, bán chạy, đánh giá cao nhất hệ thống.

Response:

{ "products": [ { "_id": "string", "name": "string", "image": "string", "price": 100000, "priceDiscount": 90000, "brand": "string", "warranty": "2 năm", "shippingFee": 15000, "avgRating": 4.8, "reviewCount": 120, "category": "categoryId" } ] }

Quản Lý Đơn Hàng

Đặt hàng

POST /orders

Yêu cầu xác thực. Đặt hàng từ giỏ hàng hiện tại của user.

Body của Request:

{ "addressId": "id địa chỉ nhận hàng (tùy chọn)" }

Lưu ý:

Response khi thành công:

{ "message": "Đặt hàng thành công", "order": { "_id": "string", "userId": "string", "items": [ { "productId": "string", "name": "string", "image": "string", "price": 100000, "priceDiscount": 90000, "quantity": 2 } ], "total": 180000, "address": "Địa chỉ nhận hàng (theo addressId hoặc địa chỉ mặc định)", "status": "pending", "createdAt": "2025-10-26T12:00:00.000Z" } }

Danh sách đơn hàng

GET /orders

Yêu cầu xác thực. Trả về danh sách đơn hàng của user hiện tại.

Response:

{ "orders": [ { "_id": "string", "userId": "string", "items": [ ... ], "total": 180000, "address": "Địa chỉ nhận hàng", "status": "pending", "createdAt": "2025-10-26T12:00:00.000Z" } ] }

Chi tiết đơn hàng

GET /orders/:id

Yêu cầu xác thực. Trả về chi tiết một đơn hàng theo id.

Response:

{ "order": { "_id": "string", "userId": "string", "items": [ ... ], "total": 180000, "address": "Địa chỉ nhận hàng", "status": "pending", "createdAt": "2025-10-26T12:00:00.000Z", "trackingId": "TRKABC12345" }, "trackingId": "TRKABC12345" }

Tra cứu đơn hàng theo trackingId

GET /orders/tracking/:trackingId

Yêu cầu xác thực. Trả về đơn hàng của user theo mã trackingId.

Response:

{ "order": { "_id": "string", "trackingId": "TRKABC12345", "status": "pending" // ... các trường khác của đơn hàng } }

Hủy đơn hàng

DELETE /orders/:id

Yêu cầu xác thực. Chỉ hủy được đơn hàng của chính user khi trạng thái là 'pending'.

Response:

{ "message": "Đã hủy đơn hàng", "order": { "_id": "string", "status": "cancelled" // ... các trường khác của đơn hàng } }

Quản Lý Sản Phẩm

Lấy danh sách đánh giá sản phẩm

GET /products/:id/reviews

Trả về danh sách review, đánh giá trung bình, tổng số lượt đánh giá, chi tiết tỉ lệ từng mức sao (1-5).

Response:

{ "reviews": [ { "rating": 5, "title": "Sản phẩm tuyệt vời!", "content": "Chất lượng tốt, giao hàng nhanh.", "user": { "userId": "abc123", "email": "[email protected]" } } ], "avgRating": 4.7, "total": 10, "ratingStats": [ { "star": 1, "count": 0, "percent": 0 }, { "star": 2, "count": 1, "percent": 10 }, { "star": 3, "count": 2, "percent": 20 }, { "star": 4, "count": 2, "percent": 20 }, { "star": 5, "count": 5, "percent": 50 } ] }

Đánh giá sản phẩm

POST /products/:id/reviews

Thêm đánh giá cho sản phẩm, bao gồm đánh giá sao, tiêu đề và nội dung.

Body của Request:

{ "rating": 5, "title": "Sản phẩm tuyệt vời!", "content": "Chất lượng tốt, giao hàng nhanh. Sẽ mua lại." }

Response khi thành công:

{ "message": "Đánh giá đã được thêm", "review": { "rating": 5, "title": "Sản phẩm tuyệt vời!", "content": "Chất lượng tốt, giao hàng nhanh. Sẽ mua lại." } }

Lấy sản phẩm liên quan

GET /products/:id/related

Trả về danh sách sản phẩm liên quan cùng chuyên mục, loại trừ sản phẩm hiện tại. Mỗi sản phẩm gồm:

Response:

{ "products": [ { "name": "string", "image": "string", "price": 100000, "priceDiscount": 90000, "brand": "string", "warranty": "2 năm", "shippingFee": "miễn phí", "avgRating": 4.5, "reviewCount": 12, "code": "SP1234" } ] }

Lấy chi tiết sản phẩm

GET /products/:id

Trả về thông tin chi tiết của một sản phẩm, bao gồm:

Response:

{ "product": { "name": "string", "image": "string", "gallery": ["string", "string"], "code": "SP123456", "description": "Chi tiết sản phẩm...", "price": 100000, "priceDiscount": 90000, "brand": "string", "warranty": "2 năm", "shippingFee": "miễn phí", "avgRating": 4.5, "reviewCount": 12, "category": "categoryId", "dealToday": false, "createdAt": "2025-10-26T12:00:00.000Z" } }

Lấy danh sách sản phẩm

GET /products

Trả về danh sách sản phẩm với các trường:

Bộ lọc (query params):

Phân trang (query params):

Sắp xếp (query param sort):

Response:

{ "products": [ { "name": "string", "image": "string", "price": 100000, "priceDiscount": 90000, "brand": "string", "warranty": "2 năm", "shippingFee": "miễn phí", "avgRating": 4.5, "reviewCount": 12 } ], "pagination": { "total": 100, "page": 1, "limit": 20, "totalPages": 5 } }

Quản Lý Danh Mục Sản Phẩm

Lấy danh sách tên danh mục

GET /categories/names

Lấy danh sách tên các danh mục sản phẩm.

Yêu Cầu Xác Thực: Không

Response:

{ "categories": ["string", "string", ...] }

Các Response Lỗi

Lỗi Kiểm Tra Dữ Liệu

{ "message": "Lỗi kiểm tra dữ liệu", "errors": { "tênTrường": "Thông báo lỗi cho trường này" } }

Lỗi Xác Thực

{ "message": "Yêu cầu xác thực" }

Lỗi Không Tìm Thấy

{ "message": "Không tìm thấy người dùng" }

Lỗi Máy Chủ

{ "message": "Thông báo mô tả lỗi" }

Mã Trạng Thái

API sử dụng các mã trạng thái sau: