xforge · tài liệu FE

FE: module cart — giỏ khách vãng lai (ADR-0073) #

Phần chung (khởi tạo client, lỗi, danh sách, ngôn ngữ) ở tài liệu FE của Core: docs/fe/common.md (bản đọc: xforge-documentation, ADR-0102 của xforge-core). Sửa file này CÙNG PR khi đổi hành vi FE thấy được của module.

Khách chưa đăng nhập vẫn có giỏ:

  1. Lần đầu thêm hàng (addMyCartItem) không kèm token giỏ → response có cartToken (CHỈ lần này). Cất nó (localStorage của storefront) — server chỉ giữ SHA-256, mất token = mất giỏ.
  2. Mọi lời gọi giỏ sau đó gửi header x-cart-token: <cartToken> (SDK: option headers() của client storefront). Token sai / không còn giỏ bị BỎ QUA: lần tạo kế tiếp trả cartToken mới — luôn thay token đang cất khi response có cartToken khác null.
  3. Sau khi khách đăng nhập: mergeMyCart({ body: { cartToken } }) rồi xoá token đã cất. Chốt đơn (confirmMyCheckout) vẫn cần đăng nhập.
  4. Giỏ vãng lai không chạm 30 ngày bị dọn; giỏ RỖNG (không dòng, không mã) sau 1 ngày.
  5. Store có trần số giỏ vãng lai MỚI mỗi giờ (cấu hình cart.guest_carts, mặc định 2000). Vượt trần → 429 cart_guest_limit, chờ details.retryAfter giây (header Retry-After) ở lần TẠO giỏ (gọi không kèm token còn hiệu lực). Mời khách đăng nhập (khách đăng nhập không bị tính) hoặc thử lại sau; giỏ đã có token vẫn dùng bình thường.
  6. Mã (setMyCartCodes): mã không module nào nhận → 400 price_code_not_recognized; module của mã từ chối thì báo lỗi của nó (vd mã giảm giá: 409 coupon_not_applicable kèm details.reason, xem trang module coupon) — mã KHÔNG được lưu.
    • Giỏ chưa có dòng báo giá được (chưa có giỏ, giỏ trống, mọi dòng nằm trong unavailable) → 409 cart_empty: ẩn ô nhập mã tới khi giỏ có hàng bán được.
    • Mỗi mã MỚI (chưa có trong codes của giỏ) là một lần đoán; mã có thật mà chưa đủ điều kiện (vd min_subtotal_not_met) cũng tính. Sai quá nhiều lần (theo khách / giỏ, và theo IP, trong store) → 429 too_many_attempts: khoá ô nhập mã, đếm ngược details.retryAfter giây. Nhập ĐÚNG không xoá số lần sai — hết thời gian chờ mới nhập lại được.
    • Còn ít lượt hơn số mã MỚI trong lần gửi → cũng 429 too_many_attempts, details.retryAfter tới hết cửa sổ: gửi ít mã mới hơn có thể qua ngay — chỉ khoá hẳn ô nhập khi một mã mới cũng bị 429.
    • BỎ mã (gửi một phần của codes đã lưu, kể cả []) không bị đếm, không bị chặn. Thêm mã: gửi codes hiện có TRỪ rejectedCodes, cộng mã mới.
    • Hiếm: 409 cart_code_rejected (details.code) — mã không dùng được với giỏ hiện tại; xử lý như mã sai (cũng tính một lần đoán).
    • Mã đã lưu mà về sau không dùng được nữa (hết hạn, hết lượt…) nằm trong rejectedCodes của giỏ, không tính vào giá.

Đổi ở cart 2.1.0 (chặn dò mã): trước đây giỏ trống vẫn nhận mã (lưu chưa kiểm) và setMyCartCodes không kèm token tạo giỏ mới. Nay mã chỉ nhận khi giỏ có hàng bán được (409 cart_empty), mã chưa kiểm trên giỏ trống cũ bị bỏ khi nâng cấp; chỉ codes: [] không kèm token còn tạo giỏ. Trang khuyến mãi kiểu ?coupon=… phải cất mã phía FE và gửi sau khi khách thêm hàng.

Nhân viên gỡ khách khỏi store (unlinkCustomer của Core) thì giỏ của khách ở store đó bị xoá (đơn giữ nguyên).

Đổi ở cart 2.1.1: thiếu lượt cho số mã mới trong lần gửi → 429 với retryAfter tới hết cửa sổ (trước đây vài giây kiểu "đang đông").

Đổi ở cart 3.0.0: HTTP không đổi (trừ mã lỗi hiếm cart_code_rejected); major vì API TS CartService.setCodes trả giỏ đã báo giá.

Đổi ở cart 3.0.1: khi nâng cấp, mã của MỌI giỏ đang mở bị bỏ (trước chỉ giỏ trống) — mã lưu chưa kiểm ở bản cũ không còn lộ qua rejectedCodes. Khách nhập lại mã một lần; giỏ đã thành đơn không đổi.