VOOZH about

URL: https://dev.to/carlosorioli/desafio-headless-checkout-shopify-em-app-react-native-com-zustand-h19

⇱ Desafio Headless: Checkout Shopify em App React Native com Zustand - DEV Community


O grande desafio no ecossistema Shopify é garantir que a transição entre a seleção de produtos nativa e o pagamento na WebView seja invisível para o usuário, mantendo a persistência do carrinho via Storefront API.

Para isso, utilizei o Zustand para o gerenciamento de estado global e o MMKV para garantir uma persistência de dados ultra-rápida, superior ao AsyncStorage tradicional. Confira o passo a passo dessa implementação:


1. Store com Zustand e MMKV

A store armazena o checkoutId e a webUrl. O uso do MMKV é o "game changer" aqui: ele é cerca de 30x mais rápido que o AsyncStorage, garantindo que o carrinho carregue instantaneamente.

import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import { MMKV } from 'react-native-mmkv';

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 useShopifyStore = create(
 persist(
 (set) => ({
 checkoutId: null,
 webUrl: null,
 setCheckout: (id, url) => set({ checkoutId: id, webUrl: url }),
 }),
 { name: 'shopify-storage', storage: createJSONStorage(() => mmkvStorage) }
 )
);

2. Sincronização via Storefront API (GraphQL)

Antes de levar o usuário para o checkout, sincronizamos os itens locais com a Shopify para gerar (ou atualizar) a URL final de pagamento.

const syncCheckout = async (checkoutId, lineItems) => {
 const query = `
 mutation checkoutLineItemsReplace($checkoutId: ID!, $lineItems: [CheckoutLineItemInput!]!) {
 checkoutLineItemsReplace(checkoutId: $checkoutId, lineItems: $lineItems) {
 checkout { id, webUrl }
 }
 }
 `;

 const response = await fetch('https://SUA-LOJA.myshopify.com/api/2024-01/graphql.json', {
 method: 'POST',
 headers: {
 'Content-Type': 'application/json',
 'X-Shopify-Storefront-Access-Token': 'SEU_TOKEN',
 },
 body: JSON.stringify({ query, variables: { checkoutId, lineItems } }),
 });
 return await response.json();
};

3. O Checkout na WebView

Utilizamos a webUrl retornada pela API para abrir o checkout já preenchido, mantendo todas as regras de negócio da loja ativas.

import { WebView } from 'react-native-webview';

const ShopifyCheckout = () => {
 const { webUrl } = useShopifyStore();

 return (
 <WebView 
 source={{ uri: webUrl }} 
 sharedCookiesEnabled={true}
 startInLoadingState={true}
 />
 );
};

O que aprendi?

  1. Arquitetura Agnostica: Validar a lógica na VTEX e replicar no Shopify mostra que um bom padrão de projeto sobrevive a qualquer stack.
  2. Performance: No e-commerce de alto nível que entregamos na Converte, milissegundos salvos com MMKV convertem em vendas.