xStore.cart

Giỏ hàng: đọc, thêm, sửa, xoá dòng hàng, báo giá kèm mã giảm giá và gộp giỏ khách vãng lai.

Phương thức

Phương thức Cú pháp Mô tả Từ phiên bản
get xStore.cart.get(): Promise<Cart> Lấy giỏ hàng hiện tại; tự tạo giỏ mới nếu chưa có. 1.0
addItem xStore.cart.addItem({ variant_id, quantity }): Promise<Cart> Thêm một phiên bản sản phẩm vào giỏ. Dùng variant.id, không phải product.id. 1.0
updateItem xStore.cart.updateItem({ variant_id, quantity }): Promise<Cart> Đặt lại số lượng của một dòng trong giỏ. 1.0
removeItem xStore.cart.removeItem(variantId): Promise<Cart> Xoá một dòng khỏi giỏ. 1.0
quote xStore.cart.quote({ couponCode }): Promise<CartQuoteRead> Báo giá giỏ hàng: từng dòng, các khoản giảm, thuế và tổng cuối. Mã giảm giá áp theo TỪNG YÊU CẦU, không lưu trên giỏ — truyền couponCode ở đây, hoặc đặt một lần bằng applyPromo() rồi mọi lần quote() sau đều gửi kèm. Số tiền trả về là CHUỖI thập phân, hãy Number() trước khi tính. 2.1
applyPromo không dùng nữa xStore.cart.applyPromo(code): { promo_code: string | null } KHÔNG DÙNG NỮA — hãy dùng xStore.cart.quote({ couponCode }). Backend chưa từng có route PATCH /cart/promo, nên bản cũ của phương thức này luôn trả 404 kể từ ngày phát hành. Bản hiện tại chạy CỤC BỘ và ĐỒNG BỘ: chỉ ghi nhớ mã trên client để quote() gửi kèm. Truyền null để gỡ mã. 1.0
merge xStore.cart.merge(guestToken): Promise<void> Gộp giỏ khách vãng lai vào giỏ tài khoản. Thư viện tự gọi khi đăng nhập. 1.0
getToken xStore.cart.getToken(): string | null Mã định danh giỏ đang lưu ở trình duyệt. Chỉ để đọc/chẩn đoán. 1.0

Ví dụ đầy đủ

<script>
  // Giỏ hàng làm việc theo PHIÊN BẢN: truyền variant_id, không phải product.id
  // và cũng không phải product.slug. Mã định danh luôn là chuỗi 10 ký tự.
  const btn = document.getElementById('add-to-cart');

  btn.addEventListener('click', async () => {
    const variantId = document.getElementById('variant-select').value;
    const quantity  = Number(document.getElementById('quantity').value) || 1;

    // Khoá nút trong lúc chờ, nếu không khách bấm nhiều lần sẽ tạo dòng trùng.
    btn.disabled = true;
    try {
      const cart = await xStore.cart.addItem({ variant_id: variantId, quantity });
      document.getElementById('cart-count').textContent = cart.item_count;
    } catch (err) {
      alert(err.message);
    } finally {
      btn.disabled = false;
    }
  });

  // Sửa số lượng và xoá dòng hàng đều trả về giỏ mới.
  async function setQuantity(variantId, quantity) {
    const cart = quantity > 0
      ? await xStore.cart.updateItem({ variant_id: variantId, quantity })
      : await xStore.cart.removeItem(variantId);

    document.getElementById('cart-count').textContent = cart.item_count;
  }

  // Áp mã giảm giá. applyPromo() chạy cục bộ và trả kết quả NGAY —
  // nó chỉ GHI NHỚ mã trên client, không gọi máy chủ. Máy chủ chỉ biết
  // tới mã khi quote() gửi kèm, nên hãy gọi quote() ngay sau đó để biết
  // mã có hợp lệ hay không.
  document.getElementById('promo-form').addEventListener('submit', async (e) => {
    e.preventDefault();
    xStore.cart.applyPromo(e.currentTarget.code.value);

    try {
      const bao = await xStore.cart.quote();
      document.getElementById('total').textContent =
        xStore.utils.formatCurrency(Number(bao.total));
    } catch (err) {
      alert('Mã không hợp lệ: ' + err.message);
    }
  });
</script>

Thư viện gọi tới /api/... trên chính tên miền cửa hàng, nên không cần khai báo địa chỉ máy chủ ở bất kỳ đâu.

Xem thêm Sự kiện để giao diện tự cập nhật sau mỗi thao tác.