Passar para o conteúdo principal

Sincronização de carrinho entre site e app

b
Escrito por bruno bulso

Nesse artigo você verá:


O que é essa funcionalidade

Com essa integração, o carrinho do seu cliente é o mesmo em qualquer canal: o que ele monta no site aparece no app, e vice-versa, sempre que ele estiver logado. Isso evita retrabalho pro cliente final e reforça a experiência omnichannel da sua marca.

Também conhecido como: carrinho cross-device, sincronização de checkout, cart sync, carrinho abandonado entre canais.

Por trás disso, o app conversa com um middleware publicado na sua conta VTEX, que sincroniza os carrinhos e os guarda no seu Master Data.

Quem faz o quê:

  • Seu time (cliente): desenvolve e publica o middleware na VTEX, e envia os dados de integração pro nosso suporte.

  • Suporte Kobe: configura o app pra consumir esse middleware.


Antes de começar

Pra essa integração funcionar, seu time de desenvolvimento (VTEX) precisa:

  1. Publicar o middleware (app VTEX IO) que persiste os carrinhos no Master Data. Referência de implementação (app da Under Armour): https://developers.vtex.com/docs/apps/[email protected]/abandoned-cart-sync-readme

  2. Implementar 3 endpoints: busca (no login), salvamento (durante a navegação) e conclusão (após a compra).

  3. Seguir as regras técnicas obrigatórias descritas mais abaixo (envelope Base64, formato da resposta da busca e nomes fixos na busca) — esses pontos não são configuráveis, então vale a pena revisar com calma antes de abrir o chamado.

Com o middleware publicado e funcionando, você abre um chamado no nosso portal de suporte com os dados de integração. Use o checklist abaixo pra reunir tudo de uma vez — isso evita idas e vindas no chamado.


Checklist: o que informar ao suporte

  • [ ] URL base do middleware

  • [ ] Caminho dos 3 endpoints (busca, salvamento, conclusão) — podem ser rotas distintas ou um único caminho compartilhado

  • [ ] Identificação do usuário: email, cpf ou document

  • [ ] Método da busca: GET ou POST

  • [ ] Método da conclusão: PATCH ou POST

  • [ ] Formato da resposta da busca: lista ou mapa

  • [ ] Nome do campo do identificador do carrinho na resposta (ex.: orderFormId, cartId)

  • [ ] Se personalizado, nome do campo de identificação do usuário no body do salvamento e conclusão (ex.: userIdentifier)

  • [ ] Se personalizado, campos extras dos itens (name/imageUrl/available) ou renomeações

  • [ ] Se desejar, tag de origem (source)

  • [ ] Itens na conclusão: preenchidos ou lista vazia


Como funciona, passo a passo

1. Busca: recuperar o carrinho remoto (acontece no login)

Quando o cliente final faz login, o app pergunta ao middleware se existe um carrinho salvo pra ele.

  • Pode ser por GET ou POST — você escolhe.

  • GET: o identificador do usuário vai como parâmetro na URL (email, cpf ou document). Qualquer chave diferente dessas é tratada como email. Exemplo: GET https://sua-conta.myvtex.com/cart-sync/[email protected]

  • POST: o corpo da requisição (em Base64) traz o identificador do usuário + orderFormId (o carrinho atual do app).

Exemplo antes do Base64:

{
  "email": "[email protected]",
  "orderFormId": "a1b2c3d4e5f60718293a4b5c6d7e8f90"
}

Enviado dentro do envelope: { "data": "eyJlbWFpbCI6..." }

A resposta da busca precisa ser uma lista ou um mapa (objeto único), nunca envelopada em algo como { "carts": [...] }. Você define o nome do campo do identificador do carrinho (ex.: orderFormId, cartId) — nos informe qual é.

Exemplo em lista:

[
  {
    "orderFormId": "f6e5d4c3b2a10918273645a4b5c6d7e8",
    "email": "[email protected]",
    "items": [
      { "productId": "7763", "skuId": "40184", "quantity": 1, "sellerId": "1" }
    ],
    "completed": false
  }
]

Exemplo em mapa:

{
  "orderFormId": "f6e5d4c3b2a10918273645a4b5c6d7e8",
  "email": "[email protected]",
  "items": [
    { "productId": "7763", "skuId": "40184", "quantity": 1, "sellerId": "1" }
  ]
}

Boas práticas: retorne só carrinhos não concluídos, idealmente dos últimos 7 a 30 dias. Se o formato da lista incluir items, o app prioriza o carrinho que já tem itens.

2. Salvamento: guardar o carrinho (acontece durante a navegação)

Toda vez que o carrinho muda no app, ele avisa o middleware pra persistir a atualização.

  • Sempre por POST.

  • O corpo traz: identificador do usuário (padrão: email/cpf/document, mas pode ter nome próprio, ex.: userIdentifier), identificador do carrinho (padrão: orderFormId, personalizável), e o array items. Opcionalmente, uma tag de origem (source) e updatedAt.

  • Cada item traz productId, skuId, quantity e sellerId — você pode pedir campos extras (name, imageUrl, available) ou renomear pra casar com seu schema.

Exemplo padrão:

{
  "email": "[email protected]",
  "orderFormId": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "items": [
    { "productId": "7763", "skuId": "40184", "quantity": 1, "sellerId": "1" }
  ]
}

Exemplo personalizado:

{
  "userIdentifier": "12345678900",
  "cartId": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "source": "app",
  "updatedAt": "2026-07-10T14:32:00.000Z",
  "items": [
    {
      "productId": "7763",
      "skuId": "40184",
      "quantity": 1,
      "sellerId": "1",
      "name": "Tênis Wave Rider",
      "imageUrl": "https://sua-conta.vteximg.com.br/arquivos/ids/40184.jpg",
      "available": true
    }
  ]
}

3. Conclusão: encerrar o carrinho (acontece após a compra)

Depois de uma compra concluída, o app avisa o middleware pra encerrar aquele carrinho e não oferecê-lo de novo.

  • Por PATCH ou POST — você define.

  • Mesma estrutura do salvamento (identificador do usuário + identificador do carrinho + items).

  • Você escolhe se os items chegam preenchidos (pra abater do carrinho abandonado) ou vazios (só marca como concluído).

Exemplo com itens preenchidos:

{
  "email": "[email protected]",
  "orderFormId": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "items": [
    { "productId": "7763", "skuId": "40184", "quantity": 2, "sellerId": "1" }
  ]
}

Exemplo com lista vazia:

{
  "email": "[email protected]",
  "orderFormId": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
  "items": []
}


Erros comuns

Carrinho não aparece no app: confirme que a resposta da busca não está envelopada (ex.: sem { "carts": [...] }) e que o campo do identificador do carrinho foi informado corretamente ao suporte.

Erro ao interpretar o payload no salvamento/conclusão: verifique se o middleware está decodificando o Base64 antes de ler o JSON.

Usuário identificado errado na busca por GET: lembre que qualquer chave que não seja cpf ou document é tratada como email.

Carrinho antigo sendo oferecido de novo: confirme se o endpoint de busca está filtrando carrinhos já concluídos e respeitando a janela de tempo definida.


Regras técnicas obrigatórias (referência)

Essas regras valem para as três etapas e não são configuráveis:

  1. Envelope Base64: toda requisição com corpo (salvamento, conclusão, e busca por POST) envia o payload como JSON em Base64, dentro de { "data": "" }, com Content-Type: application/json. A busca por GET é a exceção — usa query string, sem Base64.

  2. Resposta da busca sem envelope: precisa ser lista ou objeto no nível raiz, nunca dentro de outro campo.

  3. Nomes fixos na busca: a identificação chega como email/cpf/document e o carrinho como orderFormId. Renomeações só valem no salvamento e na conclusão.


Perguntas frequentes sobre a sincronização entre site e aplicativo

Por que meu carrinho não aparece no app? Normalmente é uma configuração pendente no middleware do seu time de desenvolvimento — a resposta da busca pode estar num formato que o app não reconhece, ou o campo do identificador do carrinho não foi informado ao suporte. Veja a seção "Erros comuns" mais abaixo, ou abra um chamado com o checklist técnico.

O carrinho do site não sincroniza com o app (ou vice-versa)? Confirme com seu time de dev se o middleware VTEX IO está publicado e funcionando. Sem ele publicado, não existe sincronização — essa é uma etapa que fica sob responsabilidade do seu time, não da Kobe.

Um carrinho antigo/já comprado continua aparecendo? É provável que o endpoint de conclusão não esteja sendo chamado corretamente após a compra, ou que a busca não esteja filtrando carrinhos já concluídos.

Quem eu acionamos pra configurar isso, meu time ou a Kobe? Os dois: seu time publica e mantém o middleware; o suporte Kobe configura o app pra consumir esse middleware, uma vez que os dados de integração forem enviados.


Precisa abrir um chamado? Acesse o portal de suporte: https://kobesoftware.atlassian.net/servicedesk/customer/portal/68

Respondeu à sua pergunta?