Package Exports
- kiotviet-client-sdk
- kiotviet-client-sdk/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (kiotviet-client-sdk) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
KiotViet Retail SDK
Một SDK được viết bằng TypeScript/JavaScript dùng để tương tác với nền tảng Public API của KiotViet. SDK này cung cấp giao diện dễ sử dụng để quản lý khách hàng, sản phẩm, đơn hàng và các tài nguyên khác trong cửa hàng bán lẻ của bạn trên hệ thống KiotViet.
Tính năng nổi bật
- 🔐 Quản lý token tự động với cơ chế xác thực bằng thông tin khách hàng (client credentials)
- 📦 Hỗ trợ đầy đủ TypeScript với định nghĩa kiểu dữ liệu chi tiết
- 🚀 API bất đồng bộ dựa trên Promise
- 🛡️ Xử lý lỗi tích hợp với các loại lỗi cụ thể
- 📝 Tài liệu đầy đủ và có ví dụ minh họa
Tài liệu API KiotViet SDK
Tài liệu này cung cấp hướng dẫn chi tiết về cách sử dụng các API có sẵn trong KiotViet Client SDK.
Mục lục
- Sản phẩm (Products)
- Khách hàng (Customers)
- Đơn hàng (Orders)
- Đơn đặt hàng (Purchase Orders)
- Danh mục (Categories)
- Hóa đơn (Invoices)
- Chi nhánh (Branches)
- Nhà cung cấp (Suppliers)
- Vouchers
- Người dùng (Users)
- Báo cáo dòng tiền (Cash Flow)
- Phụ thu (Surcharges)
- Webhooks
- Cài đặt (Settings)
Mỗi tài liệu API sẽ bao gồm:
- Danh sách đầy đủ các phương thức có sẵn
- Ví dụ chi tiết về cách sử dụng
- Cấu trúc dữ liệu và các tham số
- Ghi chú và lưu ý quan trọng
Cách sử dụng
Để bắt đầu sử dụng SDK, trước tiên bạn cần khởi tạo client:
import { KiotVietClient } from "kiotviet-client-sdk";
const client = new KiotVietClient({
clientId: "your_client_id",
clientSecret: "your_client_secret",
retailerName: "your_retailer_name"
});
Sau đó bạn có thể truy cập các API tương ứng thông qua client này. Xem chi tiết trong từng tài liệu API cụ thể.
Xác thực
SDK này sử dụng chuẩn OAuth 2.0 để xác thực. Bạn cần cung cấp clientId
, clientSecret
và retailerName
khi khởi tạo đối tượng client.
retailerName
là tên cửa hàng của bạn trên hệ thống KiotViet.clientId
vàclientSecret
được lấy từ cổng dành cho nhà phát triển (developer portal) của KiotViet.
SDK sẽ tự động xử lý việc lấy và lưu trữ access token cho bạn.
Access token được lưu trong bộ nhớ và sẽ được sử dụng cho tất cả các yêu cầu API.
- Token có hiệu lực trong vòng 1 giờ và SDK sẽ tự động làm mới khi token hết hạn.
- Nếu không thể làm mới token, SDK sẽ phát sinh lỗi và bạn cần xử lý tình huống này trong ứng dụng của mình.
Sản phẩm (Products)
API Sản phẩm (Products)
Danh sách các phương thức
list(params)
- Lấy danh sách sản phẩmgetById(productId)
- Lấy thông tin sản phẩm theo IDcreate(productData)
- Tạo sản phẩm mớiupdate(productId, productData)
- Cập nhật sản phẩmdelete(productId)
- Xóa sản phẩmgetByCategory(categoryId, params)
- Lấy sản phẩm theo danh mụcsearch(query, params)
- Tìm kiếm sản phẩmgetByCode(code)
- Lấy sản phẩm theo mãgetByBarcode(barcode)
- Lấy sản phẩm theo mã vạchgetAttributes()
- Lấy tất cả thuộc tính sản phẩmbulkCreate(products)
- Tạo nhiều sản phẩm cùng lúcbulkUpdate(products)
- Cập nhật nhiều sản phẩm cùng lúcgetInventoryLevels(params)
- Lấy thông tin tồn kho
Chi tiết sử dụng
1. Lấy danh sách sản phẩm
// Lấy danh sách với phân trang
const products = await client.products.list({
pageSize: 20,
currentItem: 0,
includeInventory: true
});
// Lấy sản phẩm có lọc theo danh mục
const products = await client.products.list({
categoryId: 123,
pageSize: 20
});
// Lọc theo trạng thái
const products = await client.products.list({
status: "Active",
pageSize: 20
});
2. Tạo sản phẩm mới
const newProduct = await client.products.create({
code: "SP001",
name: "Tên sản phẩm",
categoryId: 1,
basePrice: 100000,
retailPrice: 150000,
weight: 1.5,
unit: "Cái",
allowsSale: true,
description: "Mô tả sản phẩm",
attributes: [
{
attributeName: "Màu sắc",
attributeValue: "Đỏ"
}
]
});
3. Cập nhật sản phẩm
const updatedProduct = await client.products.update(123, {
name: "Tên sản phẩm mới",
retailPrice: 200000,
description: "Mô tả mới"
});
4. Tìm kiếm sản phẩm
// Tìm theo tên hoặc mã
const searchResults = await client.products.search("keyword", {
pageSize: 20
});
// Tìm theo mã vạch
const product = await client.products.getByBarcode("8938505040059");
// Tìm theo mã sản phẩm
const product = await client.products.getByCode("SP001");
5. Quản lý hàng loạt
// Tạo nhiều sản phẩm
await client.products.bulkCreate([
{
code: "SP001",
name: "Sản phẩm 1",
retailPrice: 100000
},
{
code: "SP002",
name: "Sản phẩm 2",
retailPrice: 200000
}
]);
// Cập nhật nhiều sản phẩm
await client.products.bulkUpdate([
{
id: 1,
retailPrice: 150000
},
{
id: 2,
retailPrice: 250000
}
]);
Cấu trúc dữ liệu
Product (Sản phẩm)
interface Product {
id: number; // ID sản phẩm
code: string; // Mã sản phẩm
name: string; // Tên sản phẩm
categoryId: number; // ID danh mục
basePrice: number; // Giá gốc
retailPrice: number; // Giá bán lẻ
weight?: number; // Khối lượng
unit?: string; // Đơn vị tính
allowsSale: boolean; // Cho phép bán
status: "Active" | "Inactive"; // Trạng thái
description?: string; // Mô tả
attributes?: ProductAttribute[]; // Thuộc tính
inventories?: ProductInventory[]; // Thông tin tồn kho
modifiedDate: string; // Ngày cập nhật
createdDate: string; // Ngày tạo
}
interface ProductAttribute {
attributeName: string; // Tên thuộc tính
attributeValue: string; // Giá trị thuộc tính
}
interface ProductInventory {
branchId: number; // ID chi nhánh
branchName: string; // Tên chi nhánh
onHand: number; // Tồn kho thực tế
reserved: number; // Số lượng đã đặt
available: number; // Số lượng có thể bán
}
ProductCreateParams (Tham số tạo sản phẩm)
interface ProductCreateParams {
code: string; // Mã sản phẩm (bắt buộc)
name: string; // Tên sản phẩm (bắt buộc)
categoryId: number; // ID danh mục (bắt buộc)
basePrice?: number; // Giá gốc
retailPrice: number; // Giá bán lẻ (bắt buộc)
weight?: number; // Khối lượng
unit?: string; // Đơn vị tính
allowsSale?: boolean; // Cho phép bán
description?: string; // Mô tả
attributes?: ProductAttribute[]; // Thuộc tính
}
ProductUpdateParams (Tham số cập nhật sản phẩm)
interface ProductUpdateParams extends Partial<ProductCreateParams> {
id: number; // ID sản phẩm cần cập nhật
}
Ghi chú
Khi sử dụng phương thức
list()
:- Mặc định
pageSize
là 20 currentItem
bắt đầu từ 0- Có thể bổ sung các tham số lọc khác như
categoryId
,status
,modifiedFrom
, v.v.
- Mặc định
Khi tạo sản phẩm:
code
phải là duy nhất trong hệ thốngretailPrice
không được nhỏ hơnbasePrice
attributes
là tùy chọn nhưng nên tuân theo cấu trúc chuẩn
Quản lý tồn kho:
- Sử dụng
getInventoryLevels()
để lấy thông tin tồn kho theo chi nhánh - Thông tin tồn kho tự động cập nhật khi có giao dịch
- Có thể lọc theo
branchIds
để lấy tồn kho của một số chi nhánh cụ thể
- Sử dụng
Khách hàng (Customers)
API Khách hàng (Customers)
Danh sách các phương thức
list(params)
- Lấy danh sách khách hànggetById(customerId)
- Lấy thông tin khách hàng theo IDcreate(customerData)
- Tạo khách hàng mớisearch(query, params)
- Tìm kiếm khách hànggetByGroup(groupId, params)
- Lấy khách hàng theo nhómgetByContactNumber(contactNumber)
- Tìm khách hàng theo số điện thoại
Chi tiết sử dụng
1. Lấy danh sách khách hàng
// Lấy danh sách với phân trang
const customers = await client.customers.list({
pageSize: 20,
currentItem: 0,
includeCustomerGroup: true
});
// Lọc theo thời gian cập nhật
const customers = await client.customers.list({
lastModifiedFrom: "2024-01-01",
pageSize: 20
});
// Sắp xếp kết quả
const customers = await client.customers.list({
orderBy: "name",
orderDirection: "ASC",
pageSize: 20
});
2. Tạo khách hàng mới
const newCustomer = await client.customers.create({
name: "Nguyễn Văn A", // Bắt buộc
contactNumber: "0901234567",
email: "nguyenvana@email.com",
gender: true, // true: Nam, false: Nữ
birthDate: "1990-01-01",
address: "123 Đường ABC",
locationName: "Phường XYZ",
wardName: "Quận 1",
organization: "Công ty ABC",
taxCode: "0123456789",
groupIds: [1, 2] // ID các nhóm khách hàng
});
3. Tìm kiếm khách hàng
// Tìm theo từ khóa (tên, số điện thoại, mã)
const searchResults = await client.customers.search("0901234567", {
pageSize: 20
});
// Tìm theo số điện thoại chính xác
const customer = await client.customers.getByContactNumber("0901234567");
// Tìm theo nhóm khách hàng
const groupCustomers = await client.customers.getByGroup(1, {
pageSize: 20
});
Cấu trúc dữ liệu
Customer (Khách hàng)
interface Customer {
id: number; // ID khách hàng
code: string; // Mã khách hàng
name: string; // Tên khách hàng
type?: number; // Loại khách hàng (0: Cá nhân, 1: Doanh nghiệp)
gender?: boolean; // Giới tính (true: Nam, false: Nữ)
birthDate?: string; // Ngày sinh
contactNumber?: string; // Số điện thoại
address?: string; // Địa chỉ
locationName?: string; // Tên địa điểm (phường/xã)
wardName?: string; // Tên quận/huyện
email?: string; // Email
organization?: string; // Tên tổ chức/công ty
comments?: string; // Ghi chú
taxCode?: string; // Mã số thuế
debt: number; // Công nợ
totalInvoiced?: number; // Tổng số hóa đơn
totalPoint?: number; // Tổng điểm tích lũy
totalRevenue?: number; // Tổng doanh thu
retailerId: number; // ID nhà bán lẻ
modifiedDate?: string; // Ngày cập nhật
createdDate: string; // Ngày tạo
rewardPoint?: number; // Điểm thưởng
psidFacebook?: number; // ID Facebook
groups?: string; // Chuỗi nhóm khách hàng
branchId?: number; // ID chi nhánh
createdBy?: string; // Người tạo
isActive?: boolean; // Trạng thái hoạt động
customerGroupDetails?: CustomerGroupDetails[]; // Chi tiết nhóm khách hàng
}
interface CustomerGroupDetails {
id: number; // ID chi tiết nhóm
customerId: number; // ID khách hàng
groupId: number; // ID nhóm
}
CustomerCreateParams (Tham số tạo khách hàng)
interface CustomerCreateParams {
code?: string; // Mã khách hàng (tự động nếu không nhập)
name: string; // Tên khách hàng (bắt buộc)
gender?: boolean; // Giới tính
birthDate?: string; // Ngày sinh
contactNumber?: string; // Số điện thoại
address?: string; // Địa chỉ
locationName?: string; // Tên địa điểm
wardName?: string; // Tên quận/huyện
email?: string; // Email
comments?: string; // Ghi chú
organization?: string; // Tên tổ chức
taxCode?: string; // Mã số thuế
groupIds?: number[]; // Danh sách ID nhóm
branchId?: number; // ID chi nhánh
}
CustomerListParams (Tham số lấy danh sách)
interface CustomerListParams {
code?: string; // Lọc theo mã
name?: string; // Lọc theo tên
contactNumber?: string; // Lọc theo SĐT
lastModifiedFrom?: string; // Từ ngày cập nhật
pageSize?: number; // Số lượng trên trang
currentItem?: number; // Vị trí bắt đầu
orderBy?: string; // Sắp xếp theo trường
orderDirection?: 'ASC' | 'DESC'; // Hướng sắp xếp
includeRemoveIds?: boolean; // Bao gồm đã xóa
includeTotal?: boolean; // Bao gồm tổng số
includeCustomerGroup?: boolean; // Bao gồm nhóm
birthDate?: string; // Lọc theo ngày sinh
groupId?: number; // Lọc theo nhóm
includeCustomerSocial?: boolean; // Bao gồm MXH
}
Ghi chú
Khi tạo khách hàng:
- Trường
name
là bắt buộc code
sẽ được tự động tạo nếu không cung cấp- Nên cung cấp
contactNumber
hoặcemail
để dễ dàng tìm kiếm sau này
- Trường
Khi tìm kiếm:
- Có thể tìm theo tên, số điện thoại, mã khách hàng
- Tìm kiếm không phân biệt chữ hoa/thường
- Hỗ trợ tìm kiếm một phần của từ khóa
Nhóm khách hàng:
- Một khách hàng có thể thuộc nhiều nhóm
- Sử dụng
groupIds
khi tạo/cập nhật để quản lý nhóm - Có thể lấy danh sách theo nhóm với
getByGroup()
Phân trang và sắp xếp:
- Mặc định
pageSize
là 20 currentItem
bắt đầu từ 0- Có thể sắp xếp theo nhiều trường khác nhau
- Hướng sắp xếp: 'ASC' (tăng dần) hoặc 'DESC' (giảm dần)
- Mặc định
Đơn hàng (Orders)
API Đơn hàng (Orders)
Danh sách các phương thức
list(params)
- Lấy danh sách đơn hànggetById(orderId)
- Lấy thông tin đơn hàng theo IDcreate(orderData)
- Tạo đơn hàng mớiupdate(orderId, orderData)
- Cập nhật đơn hàngcancel(orderId, reason)
- Hủy đơn hànggetByCode(code)
- Lấy đơn hàng theo mãdelete(orderId, isVoidPayment)
- Xóa đơn hànggetByDateRange(fromDate, toDate, params)
- Lấy đơn hàng theo khoảng thời giangetByCustomer(customerIdentifier, params)
- Lấy đơn hàng theo khách hàng
Chi tiết sử dụng
1. Tạo đơn hàng mới
const newOrder = await client.orders.create({
branchId: 1, // ID chi nhánh (bắt buộc)
customerId: 123, // ID khách hàng (tùy chọn)
purchaseDate: "2024-04-05", // Ngày mua hàng
discount: 10000, // Giảm giá
makeInvoice: true, // Tạo hóa đơn
description: "Ghi chú đơn hàng",
orderDetails: [ // Chi tiết đơn hàng (bắt buộc)
{
productId: 1,
productCode: "SP001",
productName: "Sản phẩm 1",
quantity: 2,
price: 100000,
discount: 5000,
isMaster: true
}
],
orderDelivery: { // Thông tin giao hàng (tùy chọn)
receiver: "Nguyễn Văn A",
contactNumber: "0901234567",
address: "123 Đường ABC",
locationName: "Phường XYZ",
wardName: "Quận 1"
}
});
2. Cập nhật đơn hàng
const updatedOrder = await client.orders.update(123, {
discount: 20000,
description: "Ghi chú mới",
orderDetails: [
{
productId: 1,
quantity: 3,
price: 100000
}
]
});
3. Lấy danh sách đơn hàng
// Lấy danh sách với phân trang
const orders = await client.orders.list({
pageSize: 20,
currentItem: 0,
includePayment: true,
includeOrderDelivery: true
});
// Lọc theo trạng thái
const orders = await client.orders.list({
status: [OrderStatus.Processing, OrderStatus.Completed],
pageSize: 20
});
// Lọc theo chi nhánh
const orders = await client.orders.list({
branchIds: [1, 2],
pageSize: 20
});
4. Tìm kiếm đơn hàng
// Theo khoảng thời gian
const orders = await client.orders.getByDateRange(
"2024-01-01",
"2024-01-31",
{ pageSize: 20 }
);
// Theo khách hàng
const orders = await client.orders.getByCustomer(
"0901234567", // Có thể là số điện thoại hoặc mã khách hàng
{ pageSize: 20 }
);
// Theo mã đơn hàng
const order = await client.orders.getByCode("DH001");
5. Hủy và xóa đơn hàng
// Hủy đơn hàng
await client.orders.cancel(123, "Lý do hủy đơn");
// Xóa đơn hàng
await client.orders.delete(123, true); // true: hủy thanh toán liên quan
Cấu trúc dữ liệu
Order (Đơn hàng)
interface Order {
id: number; // ID đơn hàng
code: string; // Mã đơn hàng
purchaseDate: string; // Ngày mua hàng
branchId: number; // ID chi nhánh
branchName: string; // Tên chi nhánh
customerId?: number; // ID khách hàng
customerCode?: string; // Mã khách hàng
customerName?: string; // Tên khách hàng
total: number; // Tổng tiền
totalPayment: number; // Tổng thanh toán
discount?: number; // Giảm giá
discountRatio?: number; // Tỷ lệ giảm giá
description?: string; // Ghi chú
status: number; // Mã trạng thái
statusValue: string; // Tên trạng thái
usingCod: boolean; // Sử dụng COD
orderDetails: OrderProduct[]; // Chi tiết đơn hàng
orderDelivery?: OrderDelivery; // Thông tin giao hàng
payments?: OrderPayment[]; // Thông tin thanh toán
createdDate: string; // Ngày tạo
modifiedDate?: string; // Ngày cập nhật
}
OrderProduct (Chi tiết sản phẩm)
interface OrderProduct {
productId: number; // ID sản phẩm
productCode: string; // Mã sản phẩm
productName: string; // Tên sản phẩm
quantity: number; // Số lượng
price: number; // Giá
discount?: number; // Giảm giá
discountRatio?: number; // Tỷ lệ giảm giá
note?: string; // Ghi chú
isMaster: boolean; // Là sản phẩm chính
}
OrderListParams (Tham số lấy danh sách)
interface OrderListParams {
branchIds?: number[]; // Lọc theo chi nhánh
customerIds?: number[]; // Lọc theo khách hàng
customerCode?: string; // Lọc theo mã khách hàng
status?: number[]; // Lọc theo trạng thái
includePayment?: boolean; // Bao gồm thông tin thanh toán
includeOrderDelivery?: boolean; // Bao gồm thông tin giao hàng
lastModifiedFrom?: string; // Từ ngày cập nhật
pageSize?: number; // Số lượng trên trang
currentItem?: number; // Vị trí bắt đầu
orderBy?: string; // Sắp xếp theo trường
orderDirection?: 'ASC' | 'DESC'; // Hướng sắp xếp
saleChannelId?: number; // ID kênh bán hàng
}
Trạng thái đơn hàng
enum OrderStatus {
Draft = 1, // Nháp
Processing = 2, // Đang xử lý
Completed = 3, // Hoàn thành
Cancelled = 4, // Đã hủy
}
Ghi chú
Khi tạo đơn hàng:
branchId
vàorderDetails
là bắt buộc- Nếu có
customerId
, hệ thống sẽ lấy thông tin khách hàng tự động - Có thể tạo khách hàng mới đồng thời với đơn hàng bằng cách cung cấp
customer
Thanh toán và giao hàng:
- Sử dụng
orderDelivery
để thêm thông tin giao hàng - Có thể kiểm tra thông tin thanh toán qua
payments
- Hỗ trợ thanh toán COD (
usingCod
)
- Sử dụng
Trạng thái đơn hàng:
- Mặc định là
Draft
khi tạo mới - Chỉ có thể hủy đơn hàng ở trạng thái
Draft
hoặcProcessing
- Xem
OrderStatus
để biết các trạng thái có thể
- Mặc định là
Phân trang và sắp xếp:
- Mặc định
pageSize
là 20 currentItem
bắt đầu từ 0- Có thể sắp xếp theo nhiều trường khác nhau
- Mặc định
Đơn đặt hàng (Purchase Orders)
API Đơn đặt hàng (Purchase Orders)
Danh sách các phương thức
list(params)
- Lấy danh sách đơn đặt hànggetById(purchaseOrderId)
- Lấy thông tin đơn đặt hàng theo IDcreate(purchaseOrderData)
- Tạo đơn đặt hàng mớiupdate(purchaseOrderId, purchaseOrderData)
- Cập nhật đơn đặt hàngcancel(purchaseOrderId, reason)
- Hủy đơn đặt hànggetByDateRange(fromDate, toDate, params)
- Lấy đơn đặt hàng theo khoảng thời giangetBySupplier(supplierCode, params)
- Lấy đơn đặt hàng theo nhà cung cấp
Chi tiết sử dụng
1. Tạo đơn đặt hàng mới
const newPurchaseOrder = await client.purchaseOrders.create({
branchId: 1, // ID chi nhánh (bắt buộc)
supplierId: 123, // ID nhà cung cấp
purchaseDate: "2024-04-05", // Ngày đặt hàng
expectedDeliveryDate: "2024-04-10", // Ngày dự kiến nhận
description: "Đơn hàng tháng 4",
discount: 50000, // Giảm giá
purchaseOrderDetails: [ // Chi tiết đơn hàng (bắt buộc)
{
productId: 1,
productCode: "SP001",
quantity: 10,
price: 100000,
discount: 5000,
note: "Hàng mới",
batches: [ // Thông tin lô hàng
{
batchName: "L001",
quantity: 5,
expiredDate: "2024-12-31"
}
]
}
],
supplier: { // Thông tin nhà cung cấp mới (nếu chưa có)
name: "Nhà cung cấp ABC",
contactNumber: "0901234567",
email: "abc@supplier.com"
},
payments: [ // Thanh toán
{
amount: 950000,
method: "Cash"
}
]
});
2. Lấy danh sách đơn đặt hàng
// Lấy danh sách với phân trang
const orders = await client.purchaseOrders.list({
pageSize: 20,
currentItem: 0,
includePayment: true
});
// Lọc theo chi nhánh và trạng thái
const orders = await client.purchaseOrders.list({
branchIds: [1, 2],
status: [PurchaseOrderStatus.Processing],
pageSize: 20
});
// Lọc theo khoảng thời gian
const orders = await client.purchaseOrders.getByDateRange(
"2024-01-01",
"2024-01-31",
{ pageSize: 20 }
);
// Lọc theo nhà cung cấp
const orders = await client.purchaseOrders.getBySupplier(
"NCC001",
{ pageSize: 20 }
);
3. Cập nhật đơn đặt hàng
const updatedOrder = await client.purchaseOrders.update(123, {
expectedDeliveryDate: "2024-04-15",
description: "Cập nhật ngày giao",
purchaseOrderDetails: [
{
productId: 1,
quantity: 15,
price: 100000
}
]
});
4. Hủy đơn đặt hàng
await client.purchaseOrders.cancel(123, "Nhà cung cấp hết hàng");
Cấu trúc dữ liệu
PurchaseOrder (Đơn đặt hàng)
interface PurchaseOrder {
id: number; // ID đơn hàng
code: string; // Mã đơn hàng
documentCode?: string; // Mã chứng từ
purchaseDate: string; // Ngày đặt hàng
expectedDeliveryDate?: string; // Ngày dự kiến nhận
deliveryDate?: string; // Ngày nhận thực tế
branchId: number; // ID chi nhánh
branchName: string; // Tên chi nhánh
supplierId?: number; // ID nhà cung cấp
supplierCode?: string; // Mã nhà cung cấp
supplierName?: string; // Tên nhà cung cấp
total: number; // Tổng tiền
totalPayment: number; // Tổng thanh toán
discount?: number; // Giảm giá
discountRatio?: number; // Tỷ lệ giảm
description?: string; // Ghi chú
status: number; // Mã trạng thái
statusValue: string; // Tên trạng thái
purchaseOrderDetails: PurchaseOrderProduct[]; // Chi tiết đơn hàng
payments?: PaymentDetail[]; // Thanh toán
createdDate: string; // Ngày tạo
modifiedDate?: string; // Ngày cập nhật
}
PurchaseOrderProduct (Chi tiết sản phẩm)
interface PurchaseOrderProduct {
productId: number; // ID sản phẩm
productCode: string; // Mã sản phẩm
productName: string; // Tên sản phẩm
quantity: number; // Số lượng
price: number; // Giá
discount?: number; // Giảm giá
discountRatio?: number; // Tỷ lệ giảm
note?: string; // Ghi chú
receivedQuantity?: number; // Số lượng đã nhận
serialNumbers?: string[]; // Số serial
batches?: { // Thông tin lô
batchName: string; // Tên lô
quantity: number; // Số lượng
expiredDate: string; // Ngày hết hạn
}[];
}
Trạng thái đơn hàng
enum PurchaseOrderStatus {
Draft = 1, // Nháp
Processing = 2, // Đang xử lý
Completed = 3, // Hoàn thành
Cancelled = 4 // Đã hủy
}
Ghi chú
Khi tạo đơn hàng:
branchId
vàpurchaseOrderDetails
là bắt buộc- Có thể tạo nhà cung cấp mới đồng thời bằng cách cung cấp thông tin trong
supplier
- Hỗ trợ quản lý lô hàng và số serial cho sản phẩm
Quản lý lô hàng:
- Mỗi sản phẩm có thể có nhiều lô khác nhau
- Mỗi lô có thể có số lượng và ngày hết hạn riêng
- Theo dõi số lượng đã nhận qua
receivedQuantity
Thanh toán:
- Hỗ trợ nhiều phương thức thanh toán
- Có thể thanh toán một phần hoặc toàn bộ
- Theo dõi lịch sử thanh toán qua
payments
Tìm kiếm và lọc:
- Hỗ trợ tìm kiếm theo nhiều tiêu chí
- Lọc theo trạng thái, chi nhánh, nhà cung cấp
- Tìm kiếm theo khoảng thời gian
Danh mục (Categories)
API Danh mục (Categories)
Danh sách các phương thức
list(params)
- Lấy danh sách danh mụcgetById(categoryId)
- Lấy thông tin danh mục theo IDcreate(categoryData)
- Tạo danh mục mớiupdate(categoryId, categoryData)
- Cập nhật danh mụcdelete(categoryId)
- Xóa danh mụcgetHierarchical(params)
- Lấy cấu trúc danh mục dạng cây
Chi tiết sử dụng
1. Lấy danh sách danh mục
// Lấy danh sách với phân trang
const categories = await client.categories.list({
pageSize: 20,
currentItem: 0
});
// Sắp xếp kết quả
const categories = await client.categories.list({
orderBy: "categoryName",
orderDirection: "ASC"
});
// Lấy cấu trúc danh mục dạng cây
const hierarchicalCategories = await client.categories.getHierarchical({
pageSize: 100
});
2. Tạo danh mục mới
// Tạo danh mục gốc
const newCategory = await client.categories.create({
categoryName: "Điện thoại di động",
description: "Danh mục các loại điện thoại di động",
rank: 1
});
// Tạo danh mục con
const newSubCategory = await client.categories.create({
categoryName: "iPhone",
parentId: 1, // ID của danh mục cha
description: "Danh mục điện thoại iPhone",
rank: 1
});
3. Cập nhật danh mục
const updatedCategory = await client.categories.update(123, {
categoryName: "Tên danh mục mới",
description: "Mô tả mới",
rank: 2
});
4. Xóa danh mục
await client.categories.delete(123);
Cấu trúc dữ liệu
Category (Danh mục)
interface Category {
categoryId: number; // ID danh mục
categoryName: string; // Tên danh mục
parentId: number | null; // ID danh mục cha (null nếu là danh mục gốc)
hasChild?: boolean; // Có danh mục con hay không
description?: string; // Mô tả
retailerId: number; // ID nhà bán lẻ
rank?: number; // Thứ tự sắp xếp
isDeleted?: boolean; // Đã xóa chưa
modifiedDate: string; // Ngày cập nhật
createdDate: string; // Ngày tạo
}
CategoryCreateParams (Tham số tạo danh mục)
interface CategoryCreateParams {
categoryName: string; // Tên danh mục (bắt buộc)
parentId?: number; // ID danh mục cha
description?: string; // Mô tả
rank?: number; // Thứ tự sắp xếp
}
CategoryListParams (Tham số lấy danh sách)
interface CategoryListParams {
lastModifiedFrom?: string; // Từ ngày cập nhật
pageSize?: number; // Số lượng trên trang
currentItem?: number; // Vị trí bắt đầu
orderBy?: string; // Sắp xếp theo trường
orderDirection?: 'ASC' | 'DESC'; // Hướng sắp xếp
hierarchicalData?: boolean; // Lấy dạng cây
includeRemoveIds?: boolean; // Bao gồm đã xóa
}
Ghi chú
Cấu trúc phân cấp:
- Danh mục có thể được tổ chức theo cấu trúc cha-con
- Sử dụng
parentId
để xác định mối quan hệ getHierarchical()
trả về cấu trúc dạng cây đầy đủ
Thứ tự sắp xếp:
- Sử dụng trường
rank
để sắp xếp danh mục - Giá trị càng nhỏ thì hiển thị càng cao
- Có thể cập nhật
rank
để thay đổi thứ tự
- Sử dụng trường
Xóa danh mục:
- Khi xóa danh mục, tất cả sản phẩm trong danh mục sẽ không hiển thị
- Nên đảm bảo không có sản phẩm trong danh mục trước khi xóa
- Có thể lấy danh mục đã xóa bằng
includeRemoveIds: true
Phân trang và sắp xếp:
- Mặc định
pageSize
là 20 currentItem
bắt đầu từ 0- Có thể sắp xếp theo
categoryName
,createdDate
,modifiedDate
- Mặc định
Hóa đơn (Invoices)
API Hóa đơn (Invoices)
Danh sách các phương thức
list(params)
- Lấy danh sách hóa đơngetById(invoiceId)
- Lấy thông tin hóa đơn theo IDcreate(invoiceData)
- Tạo hóa đơn mớiupdate(invoiceId, invoiceData)
- Cập nhật hóa đơncancel(invoiceId, reason)
- Hủy hóa đơndelete(invoiceId, isVoidPayment)
- Xóa/hủy bỏ hóa đơngetByDateRange(fromDate, toDate, params)
- Lấy hóa đơn theo khoảng thời giangetByCustomer(customerIdentifier, params)
- Lấy hóa đơn theo khách hànggetByOrder(orderId, params)
- Lấy hóa đơn theo đơn hànggetByCode(code)
- Lấy hóa đơn theo mã
Chi tiết sử dụng
1. Tạo hóa đơn mới
const newInvoice = await client.invoices.create({
branchId: 1, // ID chi nhánh (bắt buộc)
purchaseDate: "2024-04-05", // Ngày mua hàng
customerId: 123, // ID khách hàng
discount: 10000, // Giảm giá
totalPayment: 990000, // Tổng thanh toán (bắt buộc)
method: "Cash", // Phương thức thanh toán
usingCod: false, // Sử dụng COD
invoiceDetails: [ // Chi tiết hóa đơn (bắt buộc)
{
productId: 1,
productCode: "SP001",
productName: "Sản phẩm 1",
quantity: 2,
price: 500000,
discount: 5000
}
],
deliveryDetail: { // Thông tin giao hàng (tùy chọn)
receiver: "Nguyễn Văn A",
contactNumber: "0901234567",
address: "123 Đường ABC",
locationName: "Phường XYZ",
wardName: "Quận 1"
}
});
2. Lấy danh sách hóa đơn
// Lấy danh sách với phân trang
const invoices = await client.invoices.list({
pageSize: 20,
currentItem: 0,
includePayment: true,
includeInvoiceDelivery: true
});
// Lọc theo chi nhánh và trạng thái
const invoices = await client.invoices.list({
branchIds: [1, 2],
status: [InvoiceStatus.Completed],
pageSize: 20
});
// Lọc theo khoảng thời gian
const invoices = await client.invoices.getByDateRange(
"2024-01-01",
"2024-01-31",
{ pageSize: 20 }
);
3. Tìm kiếm hóa đơn
// Theo khách hàng
const invoices = await client.invoices.getByCustomer(
"0901234567", // Số điện thoại hoặc mã khách hàng
{ pageSize: 20 }
);
// Theo đơn hàng
const invoices = await client.invoices.getByOrder(123);
// Theo mã hóa đơn
const invoice = await client.invoices.getByCode("HD001");
4. Hủy và xóa hóa đơn
// Hủy hóa đơn
await client.invoices.cancel(123, "Lý do hủy hóa đơn");
// Xóa hóa đơn và hủy thanh toán liên quan
await client.invoices.delete(123, true);
Cấu trúc dữ liệu
Invoice (Hóa đơn)
interface Invoice {
id: number; // ID hóa đơn
code: string; // Mã hóa đơn
orderCode?: string; // Mã đơn hàng
purchaseDate: string; // Ngày mua
branchId: number; // ID chi nhánh
branchName: string; // Tên chi nhánh
customerId?: number; // ID khách hàng
customerCode?: string; // Mã khách hàng
customerName?: string; // Tên khách hàng
total: number; // Tổng tiền
totalPayment: number; // Tổng thanh toán
discount?: number; // Giảm giá
discountRatio?: number; // Tỷ lệ giảm
description?: string; // Ghi chú
status: number; // Mã trạng thái
statusValue: string; // Tên trạng thái
usingCod: boolean; // Sử dụng COD
invoiceDetails: InvoiceDetail[]; // Chi tiết hóa đơn
payments: InvoicePayment[]; // Thanh toán
invoiceDelivery?: InvoiceDelivery; // Thông tin giao hàng
createdDate: string; // Ngày tạo
modifiedDate?: string; // Ngày cập nhật
}
Phương thức thanh toán
enum PaymentMethod {
Cash = 1, // Tiền mặt
Card = 2, // Thẻ
BankTransfer = 3, // Chuyển khoản
MobilePayment = 4, // Thanh toán di động
Mixed = 5 // Kết hợp
}
Trạng thái hóa đơn
enum InvoiceStatus {
Draft = 1, // Nháp
Processing = 2, // Đang xử lý
Completed = 3, // Hoàn thành
Cancelled = 4 // Đã hủy
}
Ghi chú
Khi tạo hóa đơn:
branchId
,totalPayment
vàinvoiceDetails
là bắt buộc- Có thể tạo khách hàng mới đồng thời bằng cách cung cấp thông tin trong
customer
- Tổng tiền được tính tự động dựa trên chi tiết hóa đơn
Thanh toán:
- Hỗ trợ nhiều phương thức thanh toán
- Có thể thanh toán một phần hoặc toàn bộ
- Thanh toán COD được quản lý riêng qua
usingCod
Giao hàng:
- Thông tin giao hàng là tùy chọn
- Hỗ trợ tích hợp với đối tác giao hàng qua
partnerDelivery
- Có thể theo dõi trạng thái giao hàng
Phân trang và tìm kiếm:
- Mặc định
pageSize
là 20 currentItem
bắt đầu từ 0- Hỗ trợ nhiều tiêu chí tìm kiếm và lọc
- Có thể sắp xếp theo nhiều trường khác nhau
- Mặc định
Chi nhánh (Branches)
API Chi nhánh (Branches)
Danh sách các phương thức
list(params)
- Lấy danh sách chi nhánhgetById(branchId)
- Lấy thông tin chi nhánh theo IDcreate(branchData)
- Tạo chi nhánh mớiupdate(branchId, branchData)
- Cập nhật chi nhánhdelete(branchId)
- Xóa chi nhánh
Chi tiết sử dụng
1. Lấy danh sách chi nhánh
// Lấy danh sách với phân trang
const branches = await client.branches.list({
pageSize: 20,
currentItem: 0
});
// Lọc theo trạng thái
const activeBranches = await client.branches.list({
isActive: true,
pageSize: 20
});
// Lọc chi nhánh chính
const mainBranches = await client.branches.list({
isMain: true,
pageSize: 20
});
// Tìm kiếm theo tên hoặc mã
const searchBranches = await client.branches.list({
code: "CN001",
name: "Chi nhánh"
});
2. Tạo chi nhánh mới
const newBranch = await client.branches.create({
name: "Chi nhánh ABC", // Tên chi nhánh (bắt buộc)
address: "123 Đường XYZ", // Địa chỉ (bắt buộc)
code: "CN001", // Mã chi nhánh
wardName: "Phường 1", // Phường/Xã
districtName: "Quận 1", // Quận/Huyện
cityName: "TP.HCM", // Tỉnh/Thành phố
phoneNumber: "028.1234567", // Số điện thoại cố định
contactNumber: "0901234567", // Số điện thoại di động
email: "chinhanh@email.com", // Email
isActive: true, // Trạng thái hoạt động
locationName: "Khu vực Nam", // Tên khu vực
latLng: "10.7756587,106.7004238", // Tọa độ
parentId: 1, // ID chi nhánh cha
level: 1 // Cấp độ phân cấp
});
3. Cập nhật chi nhánh
const updatedBranch = await client.branches.update(123, {
name: "Chi nhánh ABC (Mới)",
address: "456 Đường XYZ",
phoneNumber: "028.9876543",
isActive: false
});
4. Xóa chi nhánh
await client.branches.delete(123);
Cấu trúc dữ liệu
Branch (Chi nhánh)
interface Branch {
id: number; // ID chi nhánh
branchId: string; // Mã định danh
name: string; // Tên chi nhánh
address: string; // Địa chỉ
wardName?: string; // Phường/Xã
districtName?: string; // Quận/Huyện
cityName?: string; // Tỉnh/Thành phố
phoneNumber?: string; // Số điện thoại cố định
email?: string; // Email
isActive: boolean; // Trạng thái hoạt động
isMain: boolean; // Là chi nhánh chính
retailerId: number; // ID nhà bán lẻ
locationId?: number; // ID khu vực
locationName?: string; // Tên khu vực
contactNumber?: string; // Số điện thoại di động
latLng?: string; // Tọa độ địa lý
code?: string; // Mã chi nhánh
parentId?: number; // ID chi nhánh cha
level?: number; // Cấp độ phân cấp
hasChild?: boolean; // Có chi nhánh con
createdBy?: string; // Người tạo
createdDate: string; // Ngày tạo
modifiedDate?: string; // Ngày cập nhật
}
BranchCreateParams (Tham số tạo chi nhánh)
interface BranchCreateParams {
name: string; // Tên chi nhánh (bắt buộc)
address: string; // Địa chỉ (bắt buộc)
code?: string; // Mã chi nhánh
branchId?: string; // Mã định danh
wardName?: string; // Phường/Xã
districtName?: string; // Quận/Huyện
cityName?: string; // Tỉnh/Thành phố
phoneNumber?: string; // Số điện thoại cố định
contactNumber?: string; // Số điện thoại di động
email?: string; // Email
isActive?: boolean; // Trạng thái hoạt động
locationId?: number; // ID khu vực
locationName?: string; // Tên khu vực
latLng?: string; // Tọa độ địa lý
parentId?: number; // ID chi nhánh cha
level?: number; // Cấp độ phân cấp
}
BranchListParams (Tham số lấy danh sách)
interface BranchListParams {
pageSize?: number; // Số lượng trên trang
currentItem?: number; // Vị trí bắt đầu
lastModifiedFrom?: string; // Từ ngày cập nhật
orderBy?: string; // Sắp xếp theo trường
orderDirection?: 'ASC' | 'DESC'; // Hướng sắp xếp
isActive?: boolean; // Lọc theo trạng thái
isMain?: boolean; // Lọc chi nhánh chính
code?: string; // Lọc theo mã
name?: string; // Lọc theo tên
parentId?: number; // Lọc theo chi nhánh cha
level?: number; // Lọc theo cấp độ
includeRemoveIds?: boolean; // Bao gồm đã xóa
}
Ghi chú
Phân cấp chi nhánh:
- Chi nhánh có thể được tổ chức theo cấu trúc cha-con
- Sử dụng
parentId
để xác định mối quan hệ level
chỉ định cấp độ trong hệ thống phân cấp
Chi nhánh chính:
- Mỗi cửa hàng có một chi nhánh chính (
isMain: true
) - Chi nhánh chính thường được sử dụng làm mặc định cho các hoạt động
- Mỗi cửa hàng có một chi nhánh chính (
Vị trí địa lý:
- Có thể lưu tọa độ trong
latLng
(định dạng "latitude,longitude") - Hỗ trợ phân chia theo khu vực địa lý qua
locationId
vàlocationName
- Có thể lưu tọa độ trong
Phân trang và tìm kiếm:
- Mặc định
pageSize
là 20 currentItem
bắt đầu từ 0- Hỗ trợ tìm kiếm theo tên và mã chi nhánh
- Có thể lọc theo trạng thái hoạt động và loại chi nhánh
- Mặc định
Nhà cung cấp (Suppliers)
API Nhà cung cấp (Suppliers)
Danh sách các phương thức
list(params)
- Lấy danh sách nhà cung cấpgetById(id)
- Lấy thông tin nhà cung cấp theo IDgetByCode(code)
- Lấy nhà cung cấp theo mã
Chi tiết sử dụng
1. Lấy danh sách nhà cung cấp
// Lấy danh sách với phân trang
const suppliers = await client.suppliers.list({
pageSize: 20,
currentItem: 0
});
// Lọc theo trạng thái và nhóm
const suppliers = await client.suppliers.list({
isActive: true,
supplierGroupId: 1,
includeSupplierGroup: true
});
// Tìm kiếm theo tên hoặc mã
const suppliers = await client.suppliers.list({
code: "NCC001",
name: "Công ty",
contactNumber: "0901234567"
});
// Sắp xếp kết quả
const suppliers = await client.suppliers.list({
orderBy: "name",
orderDirection: "ASC",
pageSize: 20
});
2. Tìm kiếm nhà cung cấp
// Theo ID
const supplier = await client.suppliers.getById(123);
// Theo mã
const supplier = await client.suppliers.getByCode("NCC001");
Cấu trúc dữ liệu
Supplier (Nhà cung cấp)
interface Supplier {
id: number; // ID nhà cung cấp
code: string; // Mã nhà cung cấp
name: string; // Tên nhà cung cấp
contactNumber?: string; // Số điện thoại
email?: string; // Email
address?: string; // Địa chỉ
locationName?: string; // Tên địa điểm
wardName?: string; // Phường/Xã
organization?: string; // Tên tổ chức
taxCode?: string; // Mã số thuế
comments?: string; // Ghi chú
description?: string; // Mô tả
isActive: boolean; // Trạng thái hoạt động
retailerId: number; // ID nhà bán lẻ
branchId?: number; // ID chi nhánh
debt?: number; // Công nợ
totalInvoiced?: number; // Tổng hóa đơn
totalInvoicedWithoutReturn?: number; // Tổng hóa đơn (không tính trả hàng)
supplierGroupId?: number; // ID nhóm nhà cung cấp
supplierGroupIds?: number[]; // Danh sách ID nhóm
supplierGroup?: { // Thông tin nhóm
id: number; // ID nhóm
name: string; // Tên nhóm
description?: string; // Mô tả nhóm
retailerId: number; // ID nhà bán lẻ
isActive: boolean; // Trạng thái nhóm
};
createdBy?: string; // Người tạo
createdDate: string; // Ngày tạo
modifiedDate?: string; // Ngày cập nhật
}
SupplierListParams (Tham số lấy danh sách)
interface SupplierListParams {
pageSize?: number; // Số lượng trên trang
currentItem?: number; // Vị trí bắt đầu
orderBy?: string; // Sắp xếp theo trường
orderDirection?: 'ASC' | 'DESC'; // Hướng sắp xếp
code?: string; // Lọc theo mã
name?: string; // Lọc theo tên
contactNumber?: string; // Lọc theo SĐT
lastModifiedFrom?: string; // Từ ngày cập nhật
includeRemoveIds?: boolean; // Bao gồm đã xóa
includeTotal?: boolean; // Bao gồm tổng số
includeSupplierGroup?: boolean; // Bao gồm thông tin nhóm
isActive?: boolean; // Lọc theo trạng thái
supplierGroupId?: number; // Lọc theo nhóm
}
SupplierCreateParams (Tham số tạo nhà cung cấp)
interface SupplierCreateParams {
code?: string; // Mã nhà cung cấp
name: string; // Tên nhà cung cấp (bắt buộc)
contactNumber?: string; // Số điện thoại
email?: string; // Email
address?: string; // Địa chỉ
locationName?: string; // Tên địa điểm
wardName?: string; // Phường/Xã
organization?: string; // Tên tổ chức
taxCode?: string; // Mã số thuế
comments?: string; // Ghi chú
description?: string; // Mô tả
isActive?: boolean; // Trạng thái hoạt động
branchId?: number; // ID chi nhánh
supplierGroupIds?: number[]; // Danh sách ID nhóm
}
Ghi chú
Quản lý nhà cung cấp:
- Có thể phân nhóm nhà cung cấp để dễ quản lý
- Theo dõi công nợ và tổng giá trị hóa đơn
- Hỗ trợ ghi chú và mô tả chi tiết
Tìm kiếm và lọc:
- Hỗ trợ tìm kiếm theo mã, tên, số điện thoại
- Lọc theo trạng thái hoạt động và nhóm
- Có thể sắp xếp theo nhiều tiêu chí
Thông tin bổ sung:
- Có thể bao gồm thông tin nhóm nhà cung cấp
- Theo dõi người tạo và thời gian cập nhật
- Lưu trữ thông tin địa chỉ và thuế
Phân trang và hiệu suất:
- Mặc định
pageSize
là 20 currentItem
bắt đầu từ 0- Hỗ trợ lấy tổng số bản ghi với
includeTotal
- Mặc định
Vouchers
API Voucher (Vouchers)
Danh sách các phương thức
Quản lý chiến dịch voucher
listCampaigns(params)
- Lấy danh sách chiến dịch vouchergetCampaign(id)
- Lấy thông tin chiến dịch theo IDcreateCampaign(data)
- Tạo chiến dịch mớiupdateCampaign(data)
- Cập nhật chiến dịchdeleteCampaign(id)
- Xóa chiến dịch
Quản lý voucher
list(params)
- Lấy danh sách voucherget(id)
- Lấy thông tin voucher theo IDgetByCode(code)
- Lấy voucher theo mã
Chi tiết sử dụng
1. Quản lý chiến dịch voucher
// Tạo chiến dịch voucher mới
const newCampaign = await client.vouchers.createCampaign({
code: "SUMMER2024", // Mã chiến dịch (bắt buộc)
name: "Khuyến mãi hè 2024", // Tên chiến dịch (bắt buộc)
description: "Giảm giá hè 2024", // Mô tả
startDate: "2024-06-01", // Ngày bắt đầu (bắt buộc)
endDate: "2024-08-31", // Ngày kết thúc (bắt buộc)
branchId: 1, // ID chi nhánh (bắt buộc)
branchIds: [1, 2, 3], // Danh sách chi nhánh áp dụng
customerGroupIds: [1, 2], // Nhóm khách hàng được áp dụng
discountType: VoucherDiscountType.Percentage, // Loại giảm giá
discountValue: 10, // Giá trị giảm (10%)
minOrderValue: 1000000, // Giá trị đơn hàng tối thiểu
maxDiscountValue: 200000, // Giảm giá tối đa
quantity: 1000, // Số lượng voucher
isAutoGenerate: true, // Tự động tạo mã
isUnlimited: false // Không giới hạn số lượng
});
// Lấy danh sách chiến dịch
const campaigns = await client.vouchers.listCampaigns({
status: [VoucherStatus.Active],
fromDate: "2024-01-01",
toDate: "2024-12-31",
pageSize: 20
});
// Cập nhật chiến dịch
const updatedCampaign = await client.vouchers.updateCampaign({
id: 123,
endDate: "2024-09-30",
maxDiscountValue: 300000
});
// Xóa chiến dịch
await client.vouchers.deleteCampaign(123);
2. Quản lý voucher
// Lấy danh sách voucher của một chiến dịch
const vouchers = await client.vouchers.list({
campaignId: 123,
status: [VoucherStatus.Active],
pageSize: 20
});
// Tìm voucher theo mã
const voucher = await client.vouchers.getByCode("SUMMER2024ABC");
// Lấy thông tin voucher
const voucher = await client.vouchers.get(456);
Cấu trúc dữ liệu
VoucherCampaign (Chiến dịch voucher)
interface VoucherCampaign {
id: number; // ID chiến dịch
code: string; // Mã chiến dịch
name: string; // Tên chiến dịch
description?: string; // Mô tả
startDate: string; // Ngày bắt đầu
endDate: string; // Ngày kết thúc
status: number; // Mã trạng thái
statusValue: string; // Tên trạng thái
isActive: boolean; // Đang hoạt động
branchId: number; // ID chi nhánh
branchIds?: number[]; // Danh sách chi nhánh
customerGroupIds?: number[]; // Nhóm khách hàng
discountType: number; // Loại giảm giá
discountValue: number; // Giá trị giảm
minOrderValue?: number; // Đơn hàng tối thiểu
maxDiscountValue?: number; // Giảm tối đa
quantity: number; // Số lượng
usedQuantity: number; // Đã sử dụng
remainingQuantity: number; // Còn lại
isAutoGenerate: boolean; // Tự động tạo mã
isUnlimited: boolean; // Không giới hạn
voucherProducts?: VoucherProduct[]; // Sản phẩm áp dụng
}
Voucher
interface Voucher {
id: number; // ID voucher
code: string; // Mã voucher
campaignId: number; // ID chiến dịch
campaignCode: string; // Mã chiến dịch
campaignName: string; // Tên chiến dịch
startDate: string; // Ngày bắt đầu
endDate: string; // Ngày kết thúc
status: number; // Mã trạng thái
statusValue: string; // Tên trạng thái
isUsed: boolean; // Đã sử dụng
usedDate?: string; // Ngày sử dụng
customerId?: number; // ID khách hàng
customerCode?: string; // Mã khách hàng
customerName?: string; // Tên khách hàng
orderId?: number; // ID đơn hàng
orderCode?: string; // Mã đơn hàng
discountValue: number; // Giá trị giảm
}
Trạng thái voucher
enum VoucherStatus {
Active = 1, // Đang hoạt động
Inactive = 0, // Không hoạt động
Used = 2, // Đã sử dụng
Expired = 3 // Hết hạn
}
Loại giảm giá
enum VoucherDiscountType {
FixedAmount = 1, // Giảm số tiền cố định
Percentage = 2 // Giảm theo phần trăm
}
Ghi chú
Chiến dịch voucher:
- Có thể giới hạn theo chi nhánh và nhóm khách hàng
- Hỗ trợ hai loại giảm giá: cố định và phần trăm
- Có thể tự động tạo mã voucher hoặc nhập thủ công
Giới hạn giảm giá:
minOrderValue
: Giá trị đơn hàng tối thiểu để áp dụngmaxDiscountValue
: Giới hạn số tiền giảm tối đa- Đối với giảm giá theo phần trăm, luôn kiểm tra
maxDiscountValue
Quản lý số lượng:
- Theo dõi số lượng đã sử dụng và còn lại
- Có thể tạo không giới hạn số lượng với
isUnlimited
- Hệ thống tự động cập nhật số lượng khi voucher được sử dụng
Tìm kiếm và lọc:
- Hỗ trợ tìm kiếm theo từ khóa (mã, tên)
- Lọc theo trạng thái và khoảng thời gian
- Phân trang với
pageSize
vàcurrentItem
Người dùng (Users)
API Người dùng (Users)
Danh sách các phương thức
list(params)
- Lấy danh sách người dùnggetById(userId)
- Lấy thông tin người dùng theo IDgetActive(params)
- Lấy danh sách người dùng đang hoạt độnggetByBranch(branchId, params)
- Lấy người dùng theo chi nhánhsearch(query, params)
- Tìm kiếm người dùng
Chi tiết sử dụng
1. Lấy danh sách người dùng
// Lấy danh sách với phân trang
const users = await client.users.list({
pageSize: 20,
currentItem: 0
});
// Sắp xếp kết quả
const users = await client.users.list({
orderBy: "userName",
orderDirection: "ASC"
});
// Lấy người dùng đang hoạt động
const activeUsers = await client.users.getActive({
pageSize: 20
});
2. Tìm kiếm người dùng
// Tìm theo tên hoặc mã
const searchResults = await client.users.search("John", {
pageSize: 20
});
// Tìm theo chi nhánh
const branchUsers = await client.users.getByBranch(1, {
pageSize: 20
});
3. Lấy thông tin chi tiết
// Lấy theo ID
const user = await client.users.getById(123);
Cấu trúc dữ liệu
User (Người dùng)
interface User {
id: number; // ID người dùng
userName: string; // Tên đăng nhập
givenName: string; // Tên hiển thị
address?: string; // Địa chỉ
mobilePhone?: string; // Số điện thoại
email?: string; // Email
description?: string; // Mô tả
retailerId: number; // ID nhà bán lẻ
birthDate?: string; // Ngày sinh
createdDate: string; // Ngày tạo
modifiedDate?: string; // Ngày cập nhật
}
UserListParams (Tham số lấy danh sách)
interface UserListParams {
lastModifiedFrom?: string; // Từ ngày cập nhật
pageSize?: number; // Số lượng trên trang
currentItem?: number; // Vị trí bắt đầu
orderBy?: string; // Sắp xếp theo trường
orderDirection?: 'ASC' | 'DESC'; // Hướng sắp xếp
includeRemoveIds?: boolean; // Bao gồm đã xóa
}
Ghi chú
Tìm kiếm người dùng:
- Hỗ trợ tìm kiếm theo tên hoặc mã người dùng
- Tìm kiếm không phân biệt chữ hoa/thường
- API sẽ tự động tìm kiếm cả trong tên đăng nhập và tên hiển thị
Phân quyền:
- Người dùng có thể được gán cho một hoặc nhiều chi nhánh
- Sử dụng
getByBranch()
để lấy danh sách người dùng theo chi nhánh - Quản lý trạng thái hoạt động thông qua
getActive()
Thông tin chi tiết:
- Mỗi người dùng có một tên đăng nhập duy nhất
- Có thể quản lý thông tin cá nhân như địa chỉ, số điện thoại, email
- Theo dõi thời gian tạo và cập nhật thông tin
Phân trang và sắp xếp:
- Mặc định
pageSize
là 20 currentItem
bắt đầu từ 0- Có thể sắp xếp theo nhiều trường khác nhau
- Hướng sắp xếp: 'ASC' (tăng dần) hoặc 'DESC' (giảm dần)
- Mặc định
Báo cáo dòng tiền (Cash Flow)
API Dòng tiền (Cash Flow)
Danh sách các phương thức
list(params)
- Lấy danh sách dòng tiềnprocessPayment(data)
- Xử lý thanh toán cho hóa đơn
Chi tiết sử dụng
1. Lấy danh sách dòng tiền
// Lấy danh sách với phân trang
const cashFlows = await client.cashFlow.list({
pageSize: 20,
currentItem: 0
});
// Lọc theo chi nhánh và thời gian
const cashFlows = await client.cashFlow.list({
branchIds: [1, 2],
startDate: "2024-01-01",
endDate: "2024-01-31"
});
// Lọc theo phương thức thanh toán
const cashFlows = await client.cashFlow.list({
method: ["Cash", "Card", "Transfer"],
includeAccount: true
});
// Tìm kiếm theo đối tác
const cashFlows = await client.cashFlow.list({
partnerName: "Công ty ABC",
contactNumber: "0901234567"
});
2. Xử lý thanh toán
// Thanh toán tiền mặt
const payment = await client.cashFlow.processPayment({
invoiceId: 123,
amount: 1000000,
method: "Cash"
});
// Thanh toán qua thẻ/chuyển khoản
const payment = await client.cashFlow.processPayment({
invoiceId: 123,
amount: 1000000,
method: "Card",
accountId: 1 // ID tài khoản ngân hàng
});
Cấu trúc dữ liệu
CashFlow (Dòng tiền)
interface CashFlow {
id: number; // ID dòng tiền
code: string; // Mã dòng tiền
branchId: number; // ID chi nhánh
address?: string; // Địa chỉ
wardName?: string; // Phường/Xã
contactNumber?: string; // Số điện thoại
createdBy: number; // Người tạo
usedForFinancialReporting: number; // Dùng cho báo cáo tài chính
cashFlowGroupId?: number; // ID nhóm dòng tiền
method: string; // Phương thức thanh toán
partnerType: string; // Loại đối tác
partnerId?: number; // ID đối tác
status: number; // Mã trạng thái
statusValue: string; // Tên trạng thái
transDate: string; // Ngày giao dịch
amount: number; // Số tiền
partnerName: string; // Tên đối tác
user: string; // Người dùng
accountId?: number; // ID tài khoản
description?: string; // Ghi chú
}
PaymentRequest (Yêu cầu thanh toán)
interface PaymentRequest {
amount: number; // Số tiền thanh toán
method: string; // Phương thức (Cash, Card, Transfer)
accountId?: number; // ID tài khoản (bắt buộc với Card/Transfer)
invoiceId: number; // ID hóa đơn
}
PaymentResponse (Kết quả thanh toán)
interface PaymentResponse {
paymentId: number; // ID thanh toán
paymentCode: string; // Mã thanh toán
amount: number; // Số tiền
method: string; // Phương thức
accountId?: number; // ID tài khoản
invoiceId: number; // ID hóa đơn
documentCode: number; // Mã chứng từ
}
CashFlowListParams (Tham số lấy danh sách)
interface CashFlowListParams {
branchIds?: number[]; // Lọc theo chi nhánh
code?: string[]; // Lọc theo mã
userId?: number; // Lọc theo người dùng
accountId?: number; // Lọc theo tài khoản
partnerType?: string; // Lọc theo loại đối tác
method?: string[]; // Lọc theo phương thức
cashFlowGroupId?: number[]; // Lọc theo nhóm
usedForFinancialReporting?: number; // Dùng cho báo cáo
partnerName?: string; // Tìm theo tên đối tác
contactNumber?: string; // Tìm theo SĐT
isReceipt?: boolean; // Là phiếu thu
includeAccount?: boolean; // Bao gồm thông tin tài khoản
includeBranch?: boolean; // Bao gồm thông tin chi nhánh
includeUser?: boolean; // Bao gồm thông tin người dùng
startDate?: string; // Từ ngày
endDate?: string; // Đến ngày
status?: number; // Lọc theo trạng thái
pageSize?: number; // Số lượng trên trang
currentItem?: number; // Vị trí bắt đầu
}
Ghi chú
Phương thức thanh toán:
- Hỗ trợ nhiều phương thức: Tiền mặt (Cash), Thẻ (Card), Chuyển khoản (Transfer)
- Với thanh toán qua thẻ hoặc chuyển khoản, bắt buộc cung cấp
accountId
- Mỗi giao dịch được ghi nhận với mã duy nhất
Báo cáo tài chính:
- Dùng trường
usedForFinancialReporting
để đánh dấu giao dịch cho báo cáo - Có thể nhóm các giao dịch theo
cashFlowGroupId
- Hỗ trợ xuất báo cáo theo nhiều tiêu chí
- Dùng trường
Tìm kiếm và lọc:
- Có thể lọc theo nhiều tiêu chí: chi nhánh, thời gian, phương thức, đối tác
- Hỗ trợ tìm kiếm theo tên đối tác và số điện thoại
- Phân trang với
pageSize
vàcurrentItem
Thông tin bổ sung:
- Có thể bao gồm thông tin tài khoản, chi nhánh, người dùng
- Mỗi giao dịch đều có thông tin đối tác và người thực hiện
- Ghi chú có thể được thêm vào để theo dõi chi tiết
Phụ thu (Surcharges)
API Phụ thu (Surcharges)
Danh sách các phương thức
list(params)
- Lấy danh sách phụ thugetById(surchargeId)
- Lấy thông tin phụ thu theo IDcreate(surchargeData)
- Tạo phụ thu mớiupdate(surchargeId, surchargeData)
- Cập nhật phụ thudelete(surchargeId)
- Xóa phụ thu
Chi tiết sử dụng
1. Tạo phụ thu mới
const newSurcharge = await client.surcharges.create({
name: "Phí vận chuyển", // Tên phụ thu (bắt buộc)
code: "SHIP", // Mã phụ thu
value: 30000, // Giá trị phụ thu (bắt buộc)
isPercent: false, // Tính theo phần trăm (bắt buộc)
isAutoAdd: true, // Tự động thêm vào đơn hàng
isRequired: false, // Bắt buộc áp dụng
description: "Phí giao hàng", // Mô tả
branchIds: [1, 2], // Áp dụng cho chi nhánh
isActive: true // Trạng thái hoạt động
});
// Tạo phụ thu theo phần trăm
const percentSurcharge = await client.surcharges.create({
name: "Phí dịch vụ",
code: "SERVICE",
value: 10, // 10%
isPercent: true,
isAutoAdd: true,
isRequired: true
});
2. Lấy danh sách phụ thu
// Lấy danh sách với phân trang
const surcharges = await client.surcharges.list({
pageSize: 20,
currentItem: 0
});
// Lọc theo chi nhánh và trạng thái
const surcharges = await client.surcharges.list({
branchId: 1,
isActive: true
});
// Tìm kiếm theo tên hoặc mã
const surcharges = await client.surcharges.list({
code: "SHIP",
name: "vận chuyển"
});
3. Cập nhật phụ thu
const updatedSurcharge = await client.surcharges.update(123, {
value: 35000,
description: "Phí vận chuyển mới",
isActive: true
});
4. Xóa phụ thu
await client.surcharges.delete(123);
Cấu trúc dữ liệu
Surcharge (Phụ thu)
interface Surcharge {
id: number; // ID phụ thu
code: string; // Mã phụ thu
name: string; // Tên phụ thu
value: number; // Giá trị phụ thu
isPercent: boolean; // Tính theo phần trăm
isAutoAdd: boolean; // Tự động thêm
isRequired: boolean; // Bắt buộc áp dụng
description?: string; // Mô tả
isActive: boolean; // Trạng thái hoạt động
retailerId: number; // ID nhà bán lẻ
branchId?: number; // ID chi nhánh
branchIds?: number[]; // Danh sách chi nhánh
createdBy?: string; // Người tạo
createdDate: string; // Ngày tạo
modifiedDate?: string; // Ngày cập nhật
}
SurchargeCreateParams (Tham số tạo phụ thu)
interface SurchargeCreateParams {
code?: string; // Mã phụ thu
name: string; // Tên phụ thu (bắt buộc)
value: number; // Giá trị phụ thu (bắt buộc)
isPercent: boolean; // Tính theo phần trăm (bắt buộc)
isAutoAdd?: boolean; // Tự động thêm
isRequired?: boolean; // Bắt buộc áp dụng
description?: string; // Mô tả
branchIds?: number[]; // Danh sách chi nhánh
isActive?: boolean; // Trạng thái hoạt động
}
SurchargeListParams (Tham số lấy danh sách)
interface SurchargeListParams {
pageSize?: number; // Số lượng trên trang
currentItem?: number; // Vị trí bắt đầu
lastModifiedFrom?: string; // Từ ngày cập nhật
orderBy?: string; // Sắp xếp theo trường
orderDirection?: 'ASC' | 'DESC'; // Hướng sắp xếp
isActive?: boolean; // Lọc theo trạng thái
branchId?: number; // Lọc theo chi nhánh
includeRemoveIds?: boolean; // Bao gồm đã xóa
code?: string; // Lọc theo mã
name?: string; // Lọc theo tên
}
Ghi chú
Loại phụ thu:
- Có thể tính theo số tiền cố định hoặc phần trăm
- Phụ thu theo phần trăm sẽ được tính dựa trên tổng giá trị đơn hàng
- Có thể thiết lập tự động thêm vào đơn hàng (
isAutoAdd
)
Áp dụng phụ thu:
- Có thể áp dụng cho toàn bộ cửa hàng hoặc chỉ một số chi nhánh
- Phụ thu bắt buộc (
isRequired
) không thể bỏ qua khi tạo đơn hàng - Có thể tắt/bật phụ thu thông qua trạng thái
isActive
Tìm kiếm và lọc:
- Hỗ trợ tìm kiếm theo mã và tên phụ thu
- Có thể lọc theo chi nhánh và trạng thái
- Theo dõi thời gian cập nhật qua
lastModifiedFrom
Phân trang và hiệu suất:
- Mặc định
pageSize
là 20 currentItem
bắt đầu từ 0- Hỗ trợ sắp xếp theo nhiều tiêu chí
- Mặc định
Webhooks
API Webhook (Webhooks)
Danh sách các phương thức
list(params)
- Lấy danh sách webhookgetById(webhookId)
- Lấy thông tin webhook theo IDcreate(webhookData)
- Tạo webhook mớiupdate(webhookId, webhookData)
- Cập nhật webhookdelete(webhookId)
- Xóa webhookenable(webhookId)
- Kích hoạt webhookdisable(webhookId)
- Vô hiệu hóa webhookverifySignature(payload, signature, secret)
- Xác thực chữ ký webhookparseWebhookPayload(payload, signature, secret)
- Phân tích và xác thực dữ liệu webhook
Chi tiết sử dụng
1. Tạo webhook mới
const newWebhook = await client.webhooks.create({
url: "https://your-domain.com/webhook", // URL nhận webhook (bắt buộc)
secret: "your-secret-key", // Khóa bí mật (bắt buộc)
events: [ // Danh sách sự kiện (bắt buộc)
WebhookEvent.OrderCreated,
WebhookEvent.OrderUpdated
],
isActive: true // Trạng thái kích hoạt
});
2. Lấy danh sách webhook
// Lấy tất cả webhook
const webhooks = await client.webhooks.list({
pageSize: 20,
currentItem: 0
});
// Lọc theo trạng thái
const activeWebhooks = await client.webhooks.list({
isActive: true
});
3. Quản lý trạng thái
// Kích hoạt webhook
await client.webhooks.enable(123);
// Vô hiệu hóa webhook
await client.webhooks.disable(123);
4. Xử lý webhook payload
// Xử lý webhook trong Express.js
app.post('/webhook', (req, res) => {
const signature = req.headers['x-kiotviet-signature'];
const payload = JSON.stringify(req.body);
const secret = 'your-webhook-secret';
try {
// Xác thực và phân tích payload
const webhookData = client.webhooks.parseWebhookPayload(
payload,
signature,
secret
);
// Xử lý dữ liệu dựa trên loại sự kiện
switch (webhookData.event) {
case WebhookEvent.OrderCreated:
// Xử lý đơn hàng mới
break;
case WebhookEvent.ProductUpdated:
// Xử lý cập nhật sản phẩm
break;
}
res.sendStatus(200);
} catch (error) {
console.error('Webhook error:', error);
res.sendStatus(400);
}
});
Cấu trúc dữ liệu
Webhook
interface Webhook {
id: number; // ID webhook
url: string; // URL nhận webhook
secret: string; // Khóa bí mật
events: WebhookEvent[]; // Danh sách sự kiện
isActive: boolean; // Trạng thái kích hoạt
createdDate: string; // Ngày tạo
modifiedDate: string; // Ngày cập nhật
retailerId: number; // ID nhà bán lẻ
}
Sự kiện webhook
enum WebhookEvent {
// Sự kiện sản phẩm
ProductCreated = 'product.created',
ProductUpdated = 'product.updated',
ProductDeleted = 'product.deleted',
// Sự kiện danh mục
CategoryCreated = 'category.created',
CategoryUpdated = 'category.updated',
CategoryDeleted = 'category.deleted',
// Sự kiện khách hàng
CustomerCreated = 'customer.created',
CustomerUpdated = 'customer.updated',
CustomerDeleted = 'customer.deleted',
// Sự kiện đơn hàng
OrderCreated = 'order.created',
OrderUpdated = 'order.updated',
OrderDeleted = 'order.deleted',
// Sự kiện hóa đơn
InvoiceCreated = 'invoice.created',
InvoiceUpdated = 'invoice.updated',
InvoiceDeleted = 'invoice.deleted'
}
WebhookPayload (Dữ liệu webhook)
interface WebhookPayload<T = any> {
event: WebhookEvent; // Loại sự kiện
data: T; // Dữ liệu sự kiện
timestamp: string; // Thời gian xảy ra
retailerId: number; // ID nhà bán lẻ
signature: string; // Chữ ký
}
Ghi chú
Bảo mật:
- Mỗi webhook có một khóa bí mật riêng (
secret
) - Sử dụng chữ ký HMAC SHA-256 để xác thực payload
- Luôn xác thực chữ ký trước khi xử lý dữ liệu
- Mỗi webhook có một khóa bí mật riêng (
Xử lý sự kiện:
- Webhook được gửi bất đồng bộ
- Nên xử lý nhanh và trả về response ngay
- Đưa xử lý phức tạp vào hàng đợi hoặc worker
Độ tin cậy:
- KiotViet sẽ thử gửi lại webhook nếu không nhận được phản hồi 2xx
- Xử lý webhook phải bảo đảm idempotent (có thể thực hiện nhiều lần)
- Lưu ID sự kiện để tránh xử lý trùng lặp
Quản lý:
- Có thể kích hoạt/vô hiệu hóa webhook bất kỳ lúc nào
- Một webhook có thể đăng ký nhiều loại sự kiện
- Nên giám sát webhook để đảm bảo hoạt động ổn định
Cài đặt (Settings)
API Cài đặt (Settings)
Danh sách các phương thức
get()
- Lấy thông tin cài đặt hiện tại
Chi tiết sử dụng
Lấy thông tin cài đặt
// Lấy cài đặt hiện tại
const settings = await client.settings.get();
// Kiểm tra các cài đặt cụ thể
if (settings.allowSellWhenOutStock) {
// Cho phép bán khi hết hàng
}
if (settings.managerCustomerByBranch) {
// Quản lý khách hàng theo chi nhánh
}
Cấu trúc dữ liệu
Setting (Cài đặt)
interface Setting {
managerCustomerByBranch: boolean; // Quản lý khách hàng theo chi nhánh
allowOrderWhenOutStock: boolean; // Cho phép đặt hàng khi hết hàng
allowSellWhenOrderOutStock: boolean; // Cho phép bán khi đơn đặt hàng hết hàng
allowSellWhenOutStock: boolean; // Cho phép bán khi hết hàng tồn kho
}
Ghi chú
Cài đặt quản lý tồn kho:
allowSellWhenOutStock
: Cho phép bán hàng khi sản phẩm hết tồn khoallowOrderWhenOutStock
: Cho phép đặt hàng khi sản phẩm hết tồn khoallowSellWhenOrderOutStock
: Cho phép bán khi đơn đặt hàng vượt quá số lượng tồn kho
Cài đặt quản lý khách hàng:
managerCustomerByBranch
: Khi bật tính năng này, mỗi chi nhánh sẽ quản lý danh sách khách hàng riêng- Ảnh hưởng đến việc hiển thị và tìm kiếm khách hàng trong từng chi nhánh
Tính năng này chỉ hỗ trợ đọc cài đặt:
- Không thể thay đổi cài đặt thông qua API
- Các thay đổi cài đặt phải được thực hiện trên giao diện KiotViet
Ảnh hưởng đến quy trình bán hàng:
- Các cài đặt này ảnh hưởng trực tiếp đến logic xử lý đơn hàng và tồn kho
- Nên kiểm tra các cài đặt này trước khi thực hiện các thao tác liên quan đến bán hàng và đặt hàng
- Điều chỉnh logic ứng dụng dựa trên các cài đặt này để đảm bảo tuân thủ quy tắc kinh doanh