Sapo

Hướng dẫn kết nối và đồng bộ dữ liệu hai chiều giữa Evotech và Sapo Omni.

Cập nhật 19/09/2026

1. Tổng quan về hệ thống

Tài liệu này cung cấp mô tả chi tiết về luồng hoạt động và các quy trình đồng bộ hóa dữ liệu hai chiều giữa Hệ thống Evotech và nền tảng Sapo Omni. Việc tích hợp được thực hiện thông qua việc sử dụng Sapo API và cơ chế Webhook, đảm bảo dữ liệu được cập nhật liên tục và chính xác.

Các đối tượng dữ liệu chính được đồng bộ hóa bao gồm:

  • Sản phẩm (Product): Đồng bộ một chiều (từ Sapo sang Hệ thống).

  • Đơn hàng (Order): Đồng bộ hai chiều.

  • Khách hàng (Customer): Đồng bộ hai chiều.

2. Tính năng đồng bộ dữ liệu

Hệ thống sử dụng cơ chế Webhook do Sapo cung cấp để nhận dữ liệu gần như tức thời khi có bất kỳ thay đổi nào trên nền tảng Sapo Omni. Điều này đảm bảo tính cập nhật và nhất quán của dữ liệu giữa hai hệ thống.

Đồng bộ Sản phẩm (Webhook Sapo: products/create, products/update):

  • Hệ thống nhận thông tin sản phẩm từ Sapo. Để đảm bảo tính nhất quán tuyệt đối, hệ thống sẽ tìm tất cả các sản phẩm (và biến thể) hiện có trong cơ sở dữ liệu với ExternalId tương ứng với ID sản phẩm từ Sapo và tiến hành xóa chúng, sau đó tạo lại các bản ghi Items mới dựa trên dữ liệu vừa nhận được.

  • Xử lý biến thể: nếu sản phẩm có nhiều biến thể (variants), mỗi biến thể sẽ được tạo thành một bản ghi Items riêng biệt; tất cả các biến thể của cùng một sản phẩm sẽ có chung một ItemsCode (được lấy từ ID sản phẩm gốc của Sapo). Nếu sản phẩm không có biến thể, một bản ghi Items duy nhất sẽ được tạo.

  • Danh mục (Category): nếu danh mục sản phẩm từ Sapo chưa tồn tại trong hệ thống, một danh mục mới sẽ được tự động tạo.

Xóa sản phẩm (Webhook Sapo: products/delete): hệ thống nhận ID sản phẩm cần xóa từ Sapo, tìm và xóa tất cả các bản ghi Items có ExternalId tương ứng.

Đồng bộ Đơn hàng (Webhook Sapo: orders/create, orders/update):

  • Hệ thống nhận dữ liệu đơn hàng từ Sapo.

  • Xử lý khách hàng: tìm hoặc tạo mới một User trong hệ thống dựa trên thông tin khách hàng (CustomerData) trong đơn hàng.

  • Kiểm tra xem đơn hàng đã tồn tại trong hệ thống hay chưa (dựa vào ExternalId). Nếu đã tồn tại: cập nhật lại thông tin đơn hàng (trạng thái, tổng tiền, danh sách sản phẩm...). Nếu chưa tồn tại: tạo một bản ghi Order mới.

  • Trạng thái đơn hàng của Sapo (status, payment_status, fulfillment_status) sẽ được ánh xạ sang trạng thái nội bộ (TypeOrderStatus).

Xóa đơn hàng (Webhook Sapo: orders/delete): tìm và xóa bản ghi Order có ExternalId tương ứng.

Đồng bộ Khách hàng (Webhook Sapo: customers/create, customers/update — phương thức AddOrUpdateCustomerFromSapoOmniWebhook → ProcessCustomer):

  • Hệ thống nhận dữ liệu khách hàng từ Sapo.

  • Tìm kiếm khách hàng trong hệ thống qua PhoneNumber hoặc Email.

  • Nếu tồn tại: cập nhật thông tin. Nếu chưa tồn tại: tạo một User mới.

3. Chi tiết bảng ánh xạ dữ liệu (Data Mapping)

Đây là luồng dữ liệu khi Webhook từ Sapo được kích hoạt và đẩy dữ liệu vào hệ thống Evotech.

Sản phẩm (Sapo SapoOmniProductDto → Items):

  • product.Id → Items.ExternalId — lưu ID gốc của sản phẩm từ Sapo.

  • product.Code → Items.ItemsCode — ID sản phẩm Sapo được dùng làm mã chung (ItemsCode) để nhóm tất cả các biến thể lại với nhau.

  • product.Name → Items.ItemsName — tên sản phẩm.

  • product.Description → Items.ItemsInfo — mô tả chi tiết sản phẩm.

  • product.Status → Items.IsShow, Items.TypePublish — nếu status là "active" thì IsShow = true và TypePublish = Publish, ngược lại là false và UnPublish.

  • product.Tags → Items.SeoTags — chuỗi tags phân tách bằng dấu phẩy sẽ được chuyển thành danh sách các đối tượng SeoTag.

  • product.Images → Items.Images — danh sách ảnh của sản phẩm được chuyển thành danh sách MediaInfo.

  • product.Variants (số lượng > 1) → Items.IsVariant = true.

  • variant.Price / variant.Prices → Items.Price, Items.PriceReal, Items.PriceCapital — giá được lấy từ bảng giá của biến thể, ưu tiên Price (giá bán lẻ), sau đó đến các giá khác như "BANLE", "BANBUON", "GIANHAP".

  • variant.InventoryQuantity → Items.Quantity — số lượng tồn kho của biến thể.

  • variant.WeightValue → Items.ItemsWeight — khối lượng của biến thể.

  • product.Opt1/Opt2/Opt3, variant.Opt1/Opt2/Opt3 → Items.VariantNameOne/Two/Three, Items.VariantValueOne/Two/Three — tên và giá trị của thuộc tính biến thể.

  • product.ProductType → Items.CategoryIds — tên danh mục sản phẩm từ Sapo; hệ thống sẽ tìm hoặc tạo mới một Category tương ứng và gán CategoryId vào sản phẩm.

Đơn hàng (Sapo SapoOmniOrderDto → Order):

  • order.Id → Order.ExternalId — lưu ID gốc của đơn hàng từ Sapo.

  • order.Code → Order.OrderCode — mã đơn hàng.

  • order.TotalPrice → Order.TotalPrice — tổng giá trị đơn hàng.

  • order.LineItems → Order.ListItems — danh sách sản phẩm trong đơn hàng được ánh xạ sang List<ItemsOrder>.

  • order.ShippingAddress → Order.ShippingAddress — thông tin địa chỉ giao hàng được ánh xạ sang đối tượng ShippingAddress.

  • order.Customer → Order.UserId, Order.CustomerName, Order.CustomerPhone — thông tin khách hàng được dùng để tìm hoặc tạo User mới; ID, tên và SĐT của User này được lưu vào đơn hàng.

  • order.Status, order.FulfillmentStatus, order.FinancialStatus → Order.Status — ba trạng thái từ Sapo được kết hợp để quyết định một TypeOrderStatus duy nhất trong hệ thống (ví dụ: Delivered, Cancelled, Processing...).

Khách hàng (Sapo SapoOmniCustomerDto → User):

  • customer.Id → User.ExternalId — lưu ID gốc của khách hàng từ Sapo.

  • customer.FirstName, customer.LastName → User.FullName — họ và tên được ghép lại.

  • customer.PhoneNumber → User.PhoneNumber — số điện thoại chính.

  • customer.Email → User.Email — địa chỉ email.

  • customer.Ward → User.WardName — phường xã.

  • customer.District → User.District — quận huyện.

  • customer.Province → User.Province — tỉnh thành phố.

  • customer.Addresses → User.Address — địa chỉ mặc định của khách hàng được lấy từ danh sách địa chỉ.

Bảng ánh xạ chi tiết trạng thái đơn hàng

Trạng thái thanh toán (financial_status → StatusPay):

  • paid → TypePayStatus.Paid — đã thanh toán đầy đủ.

  • refunded → TypePayStatus.Refund — đã hoàn lại tiền đầy đủ.

  • partially_refunded → TypePayStatus.Refund — đã hoàn lại một phần tiền.

  • pending → TypePayStatus.NotPaid — chờ thanh toán.

  • partially_paid → TypePayStatus.NotPaid — đã thanh toán một phần.

  • voided → TypePayStatus.NotPaid — thanh toán đã bị hủy.

  • (các giá trị khác / mặc định) → TypePayStatus.NotPaid — mặc định là chưa thanh toán.

Trạng thái vận chuyển (fulfillment_status → StatusTransport):

  • fulfilled → TypeTransportStatus.Success — đã hoàn thành giao hàng.

  • shipped → TypeTransportStatus.Transporting — đã giao cho đơn vị vận chuyển.

  • partially_fulfilled → TypeTransportStatus.Delivering — đang giao một phần của đơn hàng.

  • returned → TypeTransportStatus.Refunded — khách đã hoàn trả hàng.

  • unshipped / not_fulfilled → TypeTransportStatus.WaitingForDelivery — chưa giao hàng.

  • (các giá trị khác / mặc định) → TypeTransportStatus.WaitingForDelivery — mặc định là chờ giao hàng.

Trạng thái tổng thể đơn hàng (status → StatusOrder):

  • cancelled → TypeOrderStatus.Failed — đơn hàng đã bị hủy (StatusTransport cũng được đặt thành Cancel).

  • closed → TypeOrderStatus.Success — đơn hàng đã đóng (hoàn tất và lưu trữ).

  • draft → TypeOrderStatus.Pending — đây là đơn hàng nháp.

  • open / finalized, StatusPay là Paid → TypeOrderStatus.Paid — đơn hàng đang mở và đã được thanh toán.

  • open / finalized, StatusPay là NotPaid hoặc Refund → TypeOrderStatus.Pending — đơn hàng đang mở nhưng chưa thanh toán xong.

4. Hướng dẫn kết nối

Để tích hợp Hệ thống với Sapo Omni, bạn có thể lựa chọn một trong hai phương thức kết nối sau: Access Token hoặc OAuth (Client ID).

Kết nối bằng Access Token — phương thức này phù hợp nếu cửa hàng Sapo của bạn đã được cấp sẵn Access Token. Các bước thực hiện:

  • Nhập tên cửa hàng Sapo: điền địa chỉ mà Sapo Omni cung cấp qua URL, ví dụ: {domain sapo cung cấp}.mysapogo.com (VD: http://moitruongtest.mysapogo.com).

  • Nhập Access Token: điền Access Token mà kỹ thuật Sapo đã cung cấp cho bạn.

  • Tiến hành kết nối: nhấn nút "KẾT NỐI".

  • Sau khi kết nối thành công, hệ thống sẽ hiển thị trạng thái "Đã kết nối".

Kết nối bằng OAuth (Client ID) — phương thức này yêu cầu bạn có Client ID và Client Secret được Sapo cung cấp. Các bước thực hiện:

  • Nhập tên cửa hàng Sapo: điền địa chỉ mà Sapo Omni cung cấp qua URL, ví dụ: {domain sapo cung cấp}.mysapo.net (VD: moitruongtest.mysapo.net).

  • Nhập Client ID: điền API key (có trong email Sapo gửi).

  • Nhập Client Secret: điền secret (có trong email Sapo gửi).

  • Tiến hành kết nối: nhấn nút "KẾT NỐI".

  • Sau khi kết nối thành công, hệ thống sẽ hiển thị trạng thái "Đã kết nối".

5. Hướng dẫn ngắt kết nối

Để ngắt kết nối giữa Hệ thống và Sapo Omni, bạn có thể thực hiện theo các bước sau:

  • Truy cập vào giao diện chi tiết kết nối Sapo (như hình minh họa sau khi đã kết nối thành công).

  • Nhấn nút "NGỪNG KẾT NỐI".

Sau khi ngắt kết nối, dữ liệu sẽ không còn được đồng bộ giữa hai hệ thống.