Đồng bộ hóa giỏ hàng giữa React Native và VTEX Checkout bằng Zustand
Bài viết chia sẻ giải pháp tích hợp thanh toán VTEX vào ứng dụng React Native, đảm bảo trạng thái giỏ hàng đồng bộ hoàn hảo giữa môi trường native và WebView. Bằng cách sử dụng Zustand để quản lý trạng thái toàn cục và API của VTEX, nhà phát triển có thể tạo ra trải nghiệm mua sắm mượt mà và hiệu suất cao.

Gần đây, tôi cần phát triển tính năng tích hợp thanh toán VTEX (checkout) bên trong một ứng dụng React Native. Thách thức lớn nhất là đảm bảo trải nghiệm mua sắm diễn ra mượt mà, giữ cho trạng thái giỏ hàng được đồng bộ hoàn hảo giữa môi trường native của ứng dụng và quá trình thanh toán cuối cùng trên WebView.
Để giải quyết vấn đề này, tôi đã sử dụng Zustand để quản lý trạng thái toàn cục và API Checkout của VTEX để thao tác với orderFormId.
Kiến trúc giải pháp
Ý tưởng trung tâm là: Ứng dụng sẽ quản lý các sản phẩm và số lượng thông qua một store Zustand nhẹ nhàng. Trước khi mở màn hình thanh toán, chúng ta sẽ đồng bộ hóa toàn bộ dữ liệu này với VTEX thông qua API.
1. Quản lý giỏ hàng với Zustand
Store sẽ lưu trữ orderFormId và duy trì dữ liệu để đảm bảo giỏ hàng không bị mất. Tại đây, chúng ta có thể lựa chọn giữa AsyncStorage (mặc định) hoặc MMKV (để đạt hiệu suất cực nhanh).
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { MMKV } from 'react-native-mmkv';
// Lựa chọn với MMKV (Hiệu suất cao)
const storage = new MMKV();
const mmkvStorage = {
setItem: (name, value) => storage.set(name, value),
getItem: (name) => storage.getString(name) ?? null,
removeItem: (name) => storage.delete(name),
};
export const useCartStore = create(
persist(
(set) => ({
orderFormId: null,
items: [],
setOrderFormId: (id) => set({ orderFormId: id }),
addToCart: (item) => set((state) => ({ items: [...state.items, item] })),
clearCart: () => set({ items: [], orderFormId: null }),
}),
{
name: 'cart-storage',
// Thay thế 'mmkvStorage' bằng 'AsyncStorage' nếu bạn muốn dùng mặc định
storage: createJSONStorage(() => mmkvStorage),
}
)
);
Đối với dự án này, tôi sử dụng MMKV vì tốc độ đọc/ghi cực nhanh, nhưng cấu trúc này hoạt động hoàn hảo với AsyncStorage.
2. Đồng bộ hóa với API của VTEX
Trước khi chuyển hướng sang màn hình thanh toán, chúng ta gửi các mục (items) đến orderForm cụ thể. Điều này giúp tránh việc kích hoạt nhiều cuộc gọi mạng không cần thiết trong quá trình điều hướng.
const syncCartWithVtex = async (orderFormId, items) => {
try {
await fetch(`https://{ACCOUNT}.vtexcommercestable.com.br/api/checkout/pub/orderForm/${orderFormId}/items`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
orderItems: items.map(i => ({ id: i.id, quantity: i.quantity, seller: "1" }))
}),
});
} catch (error) {
console.error("Lỗi trong quá trình đồng bộ:", error);
}
};
MẸO: VTEX đôi khi yêu cầu gửi header
vtex-id-client-authtokennếu người dùng đã đăng nhập trong ứng dụng, để đảm bảo giỏ hàng không bị chuyển sang trạng thái "ẩn danh".
3. Thanh toán trong WebView
Bí quyết ở đây là tiêm orderFormId vào URL của WebView. Nhờ đó, trang thanh toán của VTEX sẽ mở ra ngay lập tức với tất cả các sản phẩm mà người dùng đã chọn trong ứng dụng.
import { WebView } from 'react-native-webview';
const VtexCheckout = () => {
const { orderFormId } = useCartStore();
// URL liên kết phiên làm việc với giỏ hàng của App
const checkoutUrl = `https://www.sualoja.com.br/checkout/?orderFormId=${orderFormId}#/cart`;
return (
<WebView
source={{ uri: checkoutUrl }}
sharedCookiesEnabled={true} // ĐỂ GIỮ PHIÊN LÀM VIỆC
startInLoadingState={true}
/>
);
};
Bài học kinh nghiệm
Hiệu suất: Việc đồng bộ hóa trạng thái thông qua API trước khi mở WebView mang lại trải nghiệm "native" (gốc) mượt mà hơn nhiều so với việc cố gắng thao tác trực tiếp trên DOM của trang web đã tải.
Tính bền vững: Sử dụng Zustand kết hợp với middleware persist là giải pháp bất bại để xử lý giỏ hàng trên các thiết bị di động.
Phát triển các giải pháp thương mại điện tử (e-commerce) hiệu suất cao chính là động lực thúc đẩy chúng tôi tại Converte.
Còn bạn, bạn đã bao giờ phải xử lý việc kết nối giữa môi trường native và web trong thương mại điện tử chưa? Hãy cùng trao đổi ý kiến trong phần bình luận nhé!
Bài viết liên quan

Phần mềm
Anthropic ra mắt Claude Opus 4.7: Nâng cấp mạnh mẽ cho lập trình nhưng vẫn thua Mythos Preview
16 tháng 4, 2026

Công nghệ
Qwen3.6-35B-A3B: Quyền năng Lập trình Agentic, Nay Đã Mở Cửa Cho Tất Cả
16 tháng 4, 2026

Công nghệ
Spotify thắng kiện 322 triệu USD từ nhóm pirate Anna's Archive nhưng đối mặt với bài toán thu hồi
16 tháng 4, 2026
