Client-Side API

Cài đặt

Thêm một trong các đoạn mã sau vào trang web của đối tác. Đoạn mã với polyfill hỗ trợ các trình duyệt cũ hơn trong khi đoạn mã với đuôi .min.js đã được nén lại dành cho môi trường production.

TIP

Trong trường hợp bạn không chắc chắn, hãy sử dụng đoạn mã đầu tiên.

<script src="https://api.sandbox.etop.vn/dist/ecom/ecom-polyfill.js"></script>

<!-- without polyfill -->
<script src="https://api.sandbox.etop.vn/dist/ecom/ecom.js"></script>

<!-- minified and polyfill -->
<script src="https://api.sandbox.etop.vn/dist/ecom/ecom-polyfill.min.js"></script>

<!-- minified without polyfill -->
<script src="https://api.sandbox.etop.vn/dist/ecom/ecom.min.js"></script>

Ví dụ

var order = {
  "customer_address": {
    "full_name": "Khách hàng TEST",
    "phone": "0123456789",
    "province": "Hồ Chí Minh",
    "district": "Quận 2",
    "ward": "Phường An Phú",
    "address1": "Địa chỉ TEST của khách hàng"
  },
  "shipping_address": {
    "full_name": "Khách hàng TEST",
    "phone": "0123456789",
    "province": "Hồ Chí Minh",
    "district": "Quận 2",
    "ward": "Phường An Phú",
    "address1": "Địa chỉ TEST của khách hàng"
  },
  "lines": [
    {
      "product_name": "Sản phẩm mẫu",
      "quantity": 10,
      "list_price": 1200000,
      "retail_price": 1000000,
      "payment_price": 1000000,
      "attributes": [
        {"name": "Màu", "value": "xanh"},
        {"name": "Size", "value": "30cm"}
      ]
    }
  ],
  "total_items": 10,
  "basket_value": 10000000,
  "order_discount": 10000,
  "total_discount": 10000,
  "total_amount": 10070000,
  "total_fee": 80000,
  "order_note": "Ghi chú đơn hàng",
  "fee_lines": [
    {"type": "shipping", "amount": 80000}
  ],
  "shipping": {
    "chargeable_weight": 3000,
    "cod_amount": 290000,
    "carrier": "ghtk",
    "shipping_service_code": "8JSG1RAN",
    "shipping_service_fee": 133000,
    "shipping_note": "Đơn hàng TEST, xin huỷ giúp",
    "include_insurance": true,
    "try_on": "open",
    "pickup_address": {
      "full_name": "Người dùng TEST",
      "phone": "0123459876",
      "province": "Đà Nẵng",
      "district": "Quận Liên Chiểu",
      "ward": "Hòa Khánh Nam",
      "address1": "Địa chỉ TEST lấy hàng"
    }
  }
}

var etopComponent = etop.init({
  elem: "etop-component",
  auth_token: auth_token,
  customize: {
    fromAddress: false,
    toAddress: false,
    orderFees: false,
    transportFees: true,
    submitButton: false,
  }
}).onAccessGranted(data => {
    console.log("Access granted", data);
    if (data.data) {
      localStorage.setItem("shop_id", data.shop_id);
    }
  })
  .onError((data) => {
    if (data.event !== "hello") {
      console.error(data.error.message, data.event);
    }
  })
  .onReady(() => {
    etopComponent.newOrder(order);
  });

Khởi tạo

Tạo một thẻ <div> cho eTop component trên trang web:

<body>
  <div id="etop-component"></div>
</body>

Và sử dụng đoạn mã sau để khởi tạo component:

var etopComponent = etop.init({
  elem: 'etop-component',
  auth_token: '<token của shop được cung cấp bởi server>',
  customize: {
    fromAddress: false,
    toAddress: false,
    orderFees: false,
    transportFees: true,
    submitButton: false
  }
})
  .onReady(() => console.log('Đã sẵn sàng để tạo đơn hàng'))
  .onAccessGranted((data) => console.log('Lưu shop_id vào server', data.shop_id))
  .onError((error) => console.log('Lỗi', error))

Lưu ý

Sử dụng auth_token do server cung cấp. Xin đừng nhầm lẫn với api_key, là thông tin cần được giữ bí mật và không bao giờ gửi cho client.

etop.init()

  • init(options) -> instance

Tham số:

  • options Object
    • elem String | HTMLDivElement Vị trí component sẽ được thêm vào trang web
    • auth_token String Mã được cung cấp bởi server
    • customize Object Bật tắt các field nhập trên giao diện của component. Xem ComponentOption
  • instance Object Cung cấp các API để điều khiển component và tạo đơn hàng. Xem Component API

Component API

TIP

Các hàm dùng để giao tiếp với component hỗ trợ cả mô hình callback và mô hình promise giúp bạn có thể lựa chọn cách sử dụng phù hợp.

.newOrder()

  • newOrder(callback)
  • newOrder() -> Promise<>
  • newOrder(inputData, callback)
  • newOrder(inputData) -> Promise<>

Tham số:

  • inputData Object Xem Order
  • callback Function
    • err Error
  • Promise<> Promise

Chuẩn bị đơn hàng mới. Xoá các nội dung cũ đã nhập.

etopComponent.newOrder();

Chuẩn bị đơn hàng mới đồng thời nhập nội dung

var order = {
  "customer_address": {
    "full_name": "Khách hàng TEST",
    "phone": "0123456789",
    "province": "Hồ Chí Minh",
    "district": "Quận 2",
    "ward": "Phường An Phú",
    "address1": "Địa chỉ TEST của khách hàng"
  },
  "shipping_address": {
    "full_name": "Khách hàng TEST",
    "phone": "0123456789",
    "province": "Hồ Chí Minh",
    "district": "Quận 2",
    "ward": "Phường An Phú",
    "address1": "Địa chỉ TEST của khách hàng"
  },
  "lines": [
    {
      "product_name": "Sản phẩm mẫu",
      "quantity": 10,
      "list_price": 1200000,
      "retail_price": 1000000,
      "payment_price": 1000000,
      "attributes": [
        {"name": "Màu", "value": "xanh"},
        {"name": "Size", "value": "30cm"}
      ]
    }
  ],
  "total_items": 10,
  "basket_value": 10000000,
  "order_discount": 10000,
  "total_discount": 10000,
  "total_amount": 10070000,
  "total_fee": 80000,
  "order_note": "Ghi chú đơn hàng",
  "fee_lines": [
    {"type": "shipping", "amount": 80000}
  ],
  "shipping": {
    "chargeable_weight": 3000,
    "cod_amount": 290000,
    "carrier": "ghtk",
    "shipping_service_code": "8JSG1RAN",
    "shipping_service_fee": 133000,
    "shipping_note": "Đơn hàng TEST, xin huỷ giúp",
    "include_insurance": true,
    "try_on": "open",
    "pickup_address": {
      "full_name": "Người dùng TEST",
      "phone": "0123459876",
      "province": "Đà Nẵng",
      "district": "Quận Liên Chiểu",
      "ward": "Hòa Khánh Nam",
      "address1": "Địa chỉ TEST lấy hàng"
    }
  }
}

etopComponent.newOrder(order);

.updateOrder()

  • updateOrder(inputData, callback)
  • updateOrder(inputData) -> Promise<order>

Tham số:

  • inputData Object Xem Order
  • callback Function
    • err Error
    • order Object Xem Order
  • Promise<order> Promise

Sửa giá trị hiện tại của đơn hàng. Chỉ cần truyền các mục cần sửa. Các mục để trống sẽ được giữ nguyên.

TIP

Chỉ có thể gọi sau newOrder() và trước khi submitOrder() thành công. Nếu submitOrder() không thành công, bạn có thể gọi updateOrder() để sửa nội dung trước khi submitOrder() lại.

// Sửa giá trị mục 'shipping.pickup_address'
etopComponent.updateOrder({
  'shipping': {
    'pickup_address': {
      'province': 'Ho chi minh',
      'district': 'Quan 10'
    }
  }
}, (err, order) => console.log('Updated order', order, err));

.getOrderData()

  • getOrderData(callback)
  • getOrderData() -> Promise

Lấy dữ liệu hiện tại.

etopComponent.getOrderData((error, order) => console.log('Form data', order, error));

.getShippingServices()

  • getShippingServices(callback)
  • getShippingServices() -> Promise

Lấy thông tin các gói giao hàng hiện tại.

etopComponent.getShippingServices((error, services) => console.log('Shipping services', services, error));

.submitOrder()

  • submitOrder(callback)
  • submitOrder() -> Promise

Xác nhận đơn hàng.

etopComponent.submitOrder((err, order) => console.log('Created order successfully', order, err));

Thuộc tính

.initialized

  • .initialized Boolean

Trạng thái component đã khởi tạo (nhưng có thể chưa sẵn sàng).

.ready

  • .ready Boolean

Trạng thái component đã sẵn sàng để tạo đơn hàng. Bạn có thể gọi .newOrder() để bắt đầu tạo đơn hàng.

Event

.onReady()

Trạng thái component đã sẵn sàng để tạo đơn hàng. Bạn có thể gọi .newOrder() để bắt đầu tạo đơn hàng.

etopComponent.onReady(() => {
  etopComponent.newOrder();
});

.onAccessGranted()

Quyền được cấp sau khi đăng nhập. Bạn cần lưu trữ shop_id vào server để sử dụng trong những lần truy cập tiếp theo.

etopComponent.onAccessGranted((data) => {
  console.log('Access granted', data.shop_id);
})

.onOrderCreated()

Một đơn hàng vừa được tạo.

etopComponent.onOrderCreated(order => {
  console.log('Order created', order);
});

.onError()

Nhận lỗi báo ra từ component.

etopComponent.onError((error) => console.error('error', error));

Cấu trúc dữ liệu

ComponentOption

Field Name Type Default Notes
fromAddress boolean false Khi bật, field pickup_address của Order sẽ được nhập trên giao diện (và không nhập được bằng api).
toAddress boolean false Khi bật, field customer_address của Order sẽ được nhập trên giao diện (và không nhập được bằng api).
orderFees boolean false Bật/tắt các field thông tin đơn hàng.
transportFees boolean true Bật/tắt các field thông tin vận chuyển.
submitButton boolean false Bật/tắt nút Tạo đơn hàng trên form.

Order

Field Name Type Ghi chú
external_id string ID đơn hàng của bạn. Xem thêm
external_code string Mã đơn hàng của bạn. Xem thêm
external_url string Địa chỉ URL đơn hàng trên hệ thống của bạn
customer_address Address Địa chỉ khách hàng
shipping_address Address Địa chỉ giao hàng
lines Array<OrderLine> Danh sách sản phẩm trong đơn hàng
total_items int Tổng số lượng sản phẩm trong đơn hàng

=SUMlines(quantity)
basket_value int Giá trị đơn hàng (chưa bao gồm phí và giảm giá), dùng để tính mức phí bảo hiểm

=SUMlines(quantity * retail_price)
order_discount int Giảm giá trên đơn hàng (chưa bao gồm giảm giá trên sản phẩm)
total_discount int Giảm giá trên đơn hàng (đã bao gồm giảm giá trên sản phẩm)

=SUMlines(quantity * (retail_price - payment_price)) + order_discount
total_fee int Tổng phí trên đơn hàng

=SUMfee_lines(amount)
fee_lines Array<OrderFeeLine> Danh sách phí trên đơn hàng
total_amount int Tổng giá trị đơn hàng (đã bao gồm phí và giảm giá)

=basket_value - total_discount + total_fee
order_note string Ghi chú đơn hàng
shipping OrderShipping Nội dung giao hàng

Phân biệt external_idexternal_code

Các mục external_idexternal_code là không bắt buộc khi tạo đơn hàng. Nếu được cung cấp, các mã này sẽ được hiển thị trên giao diện của người dùng (ưu tiên hiển thị external_code). Ràng buộc:

  • external_id cần là duy nhất trên hệ thống của bạn.
  • external_code cần là duy nhất trong phạm vi một shop trên hệ thống của bạn.

Thông báo lỗi trả về khi mã được cung cấp không thoả mãn ràng buộc là Mã đơn hàng external_id đã tồn tại. Vui lòng kiểm tra lại.

TIP

Nếu bạn chỉ có một loại mã và mã đó là duy nhất trên toàn hệ thống của bạn, hãy sử dụng external_id.

OrderShipping

Field Name Type Ghi chú
pickup_address Address Địa chỉ lấy hàng
return_address Address Địa chỉ trả hàng (nếu để trống sẽ sử dụng địa chỉ lấy hàng)
shipping_service_name string Tên gói cước giao hàng. Xem danh sách
shipping_service_code string Mã gói cước giao hàng. Xem danh sách
shipping_service_fee int Phí dịch vụ giao hàng (đây là số tiền shop cần trả). Xem danh sách
carrier string Đơn vị vận chuyển
include_insurance boolean Bao gồm bảo hiểm trên đơn hàng (mặc định: true)
try_on string<TryOn> Ghi chú xem hàng. Bao gồm try, open, none.
shipping_note string Ghi chú giao hàng
cod_amount int Số tiền thu hộ shop cần thu của khách (COD)
chargeable_weight int (g) Khối lượng tính phí của đơn hàng
gross_weight int (g) Khối lượng thực của đơn hàng
length int (cm) Kích thước đơn hàng (chiều dài), dùng để quy đổi khối lượng khi tính phí.
width int (cm) Kích thước đơn hàng (chiều rộng), dùng để quy đổi khối lượng khi tính phí.
height int (cm) Kích thước đơn hàng (chiều cao), dùng để quy đổi khối lượng khi tính phí.

Khối lượng tính phí của đơn hàng:

  • chargeable_weight = MAX(gross_weight, volumetric_weight)

Trong đó:

  • Khối lượng thực của đơn hàng: gross_weight(g)
  • Khối lượng thể tích: volumetric_weight(g) = length(cm) * width(cm) * height(cm) / 5 (cm³/g)

OrderFeeLine

Field Name Type Ghi chú
type string<OrderFeeType> Loại phí. Bao gồm: shipping, tax, other.
name string Tên phí
code string Mã phí (nhập tuỳ ý)
desc string Mô tả
amount int Số tiền

OrderFeeType

Type Ghi chú
shipping Số tiền phí giao hàng shop thu của khách
tax Thuế trên đơn hàng
other Phí khác

OrderLine

Mô tả một dòng trong đơn hàng

Field Name Type Ghi chú
product_name string Tên sản phẩm
quantity int Số lượng sản phẩm trong đơn hàng
list_price int Giá trên bao bì (không bắt buộc)
retail_price int Giá bán lẻ của sản phẩm (trước giảm giá, sử dụng để tính bảo hiểm cho đơn hàng)
payment_price int Giá phải trả của sản phẩm trong đơn hàng (sau giảm giá)
image_url string Hình ảnh sản phẩm (không bắt buộc)
attributes Array<Attribute> Danh sách thuộc tính của sản phẩm

Ví dụ một đơn hàng với các phiên bản sản phẩm:

  • Giày cao gót - xanh 30cm, số lượng 2
  • Giày cao gót - đỏ 32cm, số lượng 3

Khi đó các dòng sản phẩm có thể được mô tả như sau: (cùng một sản phẩm với các phiên bản khác nhau cần được biểu diễn bằng các dòng riêng biệt)

[
  {
    "product_name": "Giày cao gót",
    "quantity": 2,
    "list_price": 500000,
    "retail_price": 450000,
    "payment_price": 300000,
    "attributes": [
      {"name": "Màu", "value": "xanh"},
      {"name": "Size", "value": "30cm"}
    ]
  },
  {
    "product_name": "Giày cao gót",
    "quantity": 3,
    "list_price": 550000,
    "retail_price": 490000,
    "payment_price": 340000,
    "attributes": [
      {"name": "Màu", "value": "đỏ"},
      {"name": "Size", "value": "32cm"}
    ]
  }
]

Attribute

Thuộc tính sản phẩm (còn gọi là variant)

Field Name Ghi chú
name Tên thuộc tính
value Giá trị thuộc tính

Ví dụ một sản phẩm như Giày cao gót có thể có các phiên bản:

  • Màu xanh, size 30cm
  • Màu xanh, size 32cm
  • Màu đỏ, size 30cm
  • Màu đỏ, size 32cm

Khi đó thuộc tính của phiên bản đầu tiên (màu xanh, size 30cm) có thể được mô tả như sau:

[
  {"name": "Màu", "value": "xanh"},
  {"name": "Size", "value": "30cm"}
]

Address

Field Name Type Ghi chú
full_name string Tên
phone string Số điện thoại
email string Địa chỉ email
province string Tên tỉnh/thành phố. Xem thêm
district string Tên quận/huyện. Xem thêm
ward string Tên phường/xã. Xem thêm
address1 string Địa chỉ (dòng 1)
address2 string Địa chỉ (dòng 2)

Nhập địa chỉ

Khi nhập thông tin cho các mục province, districtward, bạn có thể gửi tên khu vực một cách linh hoạt như sau:

  • Hà Nội, Thành phố Hà Nội, TP. Hà Nội, ha noi, tp ha noi
  • P10, Phường 10, Q3, Quận 3

Xem danh sách khu vực

TryOn

Ghi chú xem hàng

Type Ghi chú
none Không cho xem hàng
open Cho xem hàng, không thử
try Cho thử hàng