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à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ỗi tài liệu API sẽ bao gồm:
Để 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ể.
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.
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// 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
});
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: "Đỏ"
}
]
});
const updatedProduct = await client.products.update(123, {
name: "Tên sản phẩm mới",
retailPrice: 200000,
description: "Mô tả mới"
});
// 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");
// 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
}
]);
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
}
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
}
interface ProductUpdateParams extends Partial<ProductCreateParams> {
id: number; // ID sản phẩm cần cập nhật
}
Khi sử dụng phương thức list()
:
pageSize
là 20currentItem
bắt đầu từ 0categoryId
, status
, modifiedFrom
, v.v.Khi tạo sản phẩm:
code
phải là duy nhất trong hệ thốngretailPrice
không được nhỏ hơn basePrice
attributes
là tùy chọn nhưng nên tuân theo cấu trúc chuẩnQuản lý tồn kho:
getInventoryLevels()
để lấy thông tin tồn kho theo chi nhánhbranchIds
để lấy tồn kho của một số chi nhánh cụ thể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// 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
});
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
});
// 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
});
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
}
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
}
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
}
Khi tạo khách hàng:
name
là bắt buộccode
sẽ được tự động tạo nếu không cung cấpcontactNumber
hoặc email
để dễ dàng tìm kiếm sau nàyKhi tìm kiếm:
Nhóm khách hàng:
groupIds
khi tạo/cập nhật để quản lý nhómgetByGroup()
Phân trang và sắp xếp:
pageSize
là 20currentItem
bắt đầu từ 0list(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àngconst 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"
}
});
const updatedOrder = await client.orders.update(123, {
discount: 20000,
description: "Ghi chú mới",
orderDetails: [
{
productId: 1,
quantity: 3,
price: 100000
}
]
});
// 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
});
// 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");
// 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
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
}
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
}
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
}
enum OrderStatus {
Draft = 1, // Nháp
Processing = 2, // Đang xử lý
Completed = 3, // Hoàn thành
Cancelled = 4, // Đã hủy
}
Khi tạo đơn hàng:
branchId
và orderDetails
là bắt buộccustomerId
, hệ thống sẽ lấy thông tin khách hàng tự độngcustomer
Thanh toán và giao hàng:
orderDelivery
để thêm thông tin giao hàngpayments
usingCod
)Trạng thái đơn hàng:
Draft
khi tạo mớiDraft
hoặc Processing
OrderStatus
để biết các trạng thái có thểPhân trang và sắp xếp:
pageSize
là 20currentItem
bắt đầu từ 0list(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ấpconst 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"
}
]
});
// 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 }
);
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
}
]
});
await client.purchaseOrders.cancel(123, "Nhà cung cấp hế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
}
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
}[];
}
enum PurchaseOrderStatus {
Draft = 1, // Nháp
Processing = 2, // Đang xử lý
Completed = 3, // Hoàn thành
Cancelled = 4 // Đã hủy
}
Khi tạo đơn hàng:
branchId
và purchaseOrderDetails
là bắt buộcsupplier
Quản lý lô hàng:
receivedQuantity
Thanh toán:
payments
Tìm kiếm và lọ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// 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
});
// 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
});
const updatedCategory = await client.categories.update(123, {
categoryName: "Tên danh mục mới",
description: "Mô tả mới",
rank: 2
});
await client.categories.delete(123);
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
}
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
}
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
}
Cấu trúc phân cấp:
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:
rank
để sắp xếp danh mụcrank
để thay đổi thứ tựXóa danh mục:
includeRemoveIds: true
Phân trang và sắp xếp:
pageSize
là 20currentItem
bắt đầu từ 0categoryName
, createdDate
, modifiedDate
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ã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"
}
});
// 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 }
);
// 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");
// 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);
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
}
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
}
enum InvoiceStatus {
Draft = 1, // Nháp
Processing = 2, // Đang xử lý
Completed = 3, // Hoàn thành
Cancelled = 4 // Đã hủy
}
Khi tạo hóa đơn:
branchId
, totalPayment
và invoiceDetails
là bắt buộccustomer
Thanh toán:
usingCod
Giao hàng:
partnerDelivery
Phân trang và tìm kiếm:
pageSize
là 20currentItem
bắt đầu từ 0list(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// 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"
});
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
});
const updatedBranch = await client.branches.update(123, {
name: "Chi nhánh ABC (Mới)",
address: "456 Đường XYZ",
phoneNumber: "028.9876543",
isActive: false
});
await client.branches.delete(123);
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
}
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
}
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
}
Phân cấp chi nhánh:
parentId
để xác định mối quan hệlevel
chỉ định cấp độ trong hệ thống phân cấpChi nhánh chính:
isMain: true
)Vị trí địa lý:
latLng
(định dạng "latitude,longitude")locationId
và locationName
Phân trang và tìm kiếm:
pageSize
là 20currentItem
bắt đầu từ 0list(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ã// 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
});
// Theo ID
const supplier = await client.suppliers.getById(123);
// Theo mã
const supplier = await client.suppliers.getByCode("NCC001");
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
}
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
}
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
}
Quản lý nhà cung cấp:
Tìm kiếm và lọc:
Thông tin bổ sung:
Phân trang và hiệu suất:
pageSize
là 20currentItem
bắt đầu từ 0includeTotal
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ịchlist(params)
- Lấy danh sách voucherget(id)
- Lấy thông tin voucher theo IDgetByCode(code)
- Lấy voucher theo mã// 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);
// 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);
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
}
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
}
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
}
enum VoucherDiscountType {
FixedAmount = 1, // Giảm số tiền cố định
Percentage = 2 // Giảm theo phần trăm
}
Chiến dịch voucher:
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 đamaxDiscountValue
Quản lý số lượng:
isUnlimited
Tìm kiếm và lọc:
pageSize
và currentItem
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// 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
});
// 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
});
// Lấy theo ID
const user = await client.users.getById(123);
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
}
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
}
Tìm kiếm người dùng:
Phân quyền:
getByBranch()
để lấy danh sách người dùng theo chi nhánhgetActive()
Thông tin chi tiết:
Phân trang và sắp xếp:
pageSize
là 20currentItem
bắt đầu từ 0list(params)
- Lấy danh sách dòng tiềnprocessPayment(data)
- Xử lý thanh toán cho hóa đơ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"
});
// 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
});
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ú
}
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
}
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ừ
}
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
}
Phương thức thanh toán:
accountId
Báo cáo tài chính:
usedForFinancialReporting
để đánh dấu giao dịch cho báo cáocashFlowGroupId
Tìm kiếm và lọc:
pageSize
và currentItem
Thông tin bổ sung:
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ụ thuconst 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
});
// 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"
});
const updatedSurcharge = await client.surcharges.update(123, {
value: 35000,
description: "Phí vận chuyển mới",
isActive: true
});
await client.surcharges.delete(123);
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
}
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
}
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
}
Loại phụ thu:
isAutoAdd
)Áp dụng phụ thu:
isRequired
) không thể bỏ qua khi tạo đơn hàngisActive
Tìm kiếm và lọc:
lastModifiedFrom
Phân trang và hiệu suất:
pageSize
là 20currentItem
bắt đầu từ 0list(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 webhookconst 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
});
// 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
});
// Kích hoạt webhook
await client.webhooks.enable(123);
// Vô hiệu hóa webhook
await client.webhooks.disable(123);
// Middleware để lấy raw body cho việc tạo chữ ký
app.use(bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf;
}
}));
// Xử lý webhook trong Express.js
app.post('/webhook', (req, res) => {
const signature = req.headers['x-hub-signature'];
const payload = req.rawBody.toString();
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) {
// ===== CUSTOMER EVENTS =====
case WebhookEvent.CustomerUpdated:
// Xử lý cập nhật khách hàng
const customerData = webhookData.data as CustomerUpdateWebhookPayload;
// Truy cập dữ liệu khách hàng đã cập nhật
for (const notification of customerData.Notifications) {
for (const customer of notification.Data) {
console.log(`Khách hàng cập nhật: ${customer.Name} (${customer.Code})`);
// Xử lý cập nhật khách hàng
}
}
break;
case WebhookEvent.CustomerDeleted:
const customerDeleteData = webhookData.data as { RemoveId: number[] };
console.log('ID khách hàng bị xóa:', customerDeleteData.RemoveId);
break;
// ===== PRODUCT EVENTS =====
case WebhookEvent.ProductUpdated:
const productData = webhookData.data as ProductUpdateWebhookPayload;
// Xử lý cập nhật sản phẩm
break;
case WebhookEvent.ProductDeleted:
const productDeleteData = webhookData.data as { RemoveId: number[] };
console.log('ID sản phẩm bị xóa:', productDeleteData.RemoveId);
break;
// ===== ORDER EVENTS =====
case WebhookEvent.OrderCreated:
case WebhookEvent.OrderUpdated:
const orderData = webhookData.data as OrderUpdateWebhookPayload;
// Xử lý đơn hàng
break;
// ===== INVOICE EVENTS =====
case WebhookEvent.InvoiceUpdated:
const invoiceData = webhookData.data as InvoiceUpdateWebhookPayload;
// Xử lý hóa đơn
break;
// ===== STOCK EVENTS =====
case WebhookEvent.StockUpdated:
const stockData = webhookData.data as StockUpdateWebhookPayload;
// Xử lý cập nhật tồn kho
break;
// ===== PRICEBOOK EVENTS =====
case WebhookEvent.PriceBookUpdated:
case WebhookEvent.PriceBookDetailUpdated:
// Xử lý cập nhật bảng giá
break;
}
res.sendStatus(200);
} catch (error) {
console.error('Lỗi webhook:', error);
res.sendStatus(400);
}
});
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ẻ
}
enum WebhookEvent {
// Sự kiện sản phẩm (Product)
ProductCreated = 'product.created',
ProductUpdated = 'product.updated',
ProductDeleted = 'product.deleted',
// Sự kiện danh mục (Category)
CategoryCreated = 'category.created',
CategoryUpdated = 'category.updated',
CategoryDeleted = 'category.deleted',
// Sự kiện khách hàng (Customer)
CustomerCreated = 'customer.created',
CustomerUpdated = 'customer.updated',
CustomerDeleted = 'customer.deleted',
// Sự kiện đơn hàng (Order)
OrderCreated = 'order.created',
OrderUpdated = 'order.updated',
OrderDeleted = 'order.deleted',
// Sự kiện hóa đơn (Invoice)
InvoiceCreated = 'invoice.created',
InvoiceUpdated = 'invoice.updated',
InvoiceDeleted = 'invoice.deleted',
// Sự kiện tồn kho (Stock)
StockUpdated = 'stock.update',
// Sự kiện bảng giá (PriceBook)
PriceBookUpdated = 'pricebook.update',
PriceBookDeleted = 'pricebook.delete',
PriceBookDetailUpdated = 'pricebookdetail.update',
PriceBookDetailDeleted = 'pricebookdetail.delete',
// Sự kiện chi nhánh (Branch)
BranchUpdated = 'branch.update',
BranchDeleted = 'branch.delete'
}
SDK cung cấp các interface để giúp bạn xử lý dữ liệu webhook một cách dễ dàng với TypeScript. Dưới đây là các cấu trúc dữ liệu chính:
export 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ý
}
// Cấu trúc chung cho các webhook sự kiện update
export interface GenericUpdateWebhookPayload<T> {
Id: string; // ID của webhook
Attempt: number; // Số lần thử gửi
Notifications: [{
Action: string; // Hành động (customer.update, product.update, ...)
Data: T[]; // Mảng dữ liệu
}]
}
// Cấu trúc chung cho các webhook sự kiện delete
export interface GenericDeleteWebhookPayload {
RemoveId: number[]; // Mảng ID các mục bị xóa
}
// Kiểu dữ liệu cho webhook customer.update
export interface CustomerUpdateWebhookPayload extends GenericUpdateWebhookPayload<CustomerWebhookData> {}
export interface CustomerWebhookData {
Id: number; // ID khách hàng
Code: string; // Mã khách hàng
Name: string; // Tên khách hàng
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
Email?: string; // Email
ModifiedDate: string; // Ngày cập nhật
Type?: number; // Loại khách hàng
Organization?: string; // Tổ chức
TaxCode?: string; // Mã số thuế
Comments?: string; // Ghi chú
}
Bảo mật:
secret
)Xử lý sự kiện:
Độ tin cậy:
Quản lý:
get()
- Lấy thông tin cài đặt hiện tại// 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
}
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
}
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 khoCà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êngTính năng này chỉ hỗ trợ đọc cài đặt:
Ảnh hưởng đến quy trình bán hàng: