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:
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
Implementar 3 endpoints: busca (no login), salvamento (durante a navegação) e conclusão (após a compra).
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
Portal de suporte: https://kobesoftware.atlassian.net/servicedesk/customer/portal/68
[ ] 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 arrayitems. Opcionalmente, uma tag de origem (source) eupdatedAt.Cada item traz
productId,skuId,quantityesellerId— 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
itemschegam 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:
Envelope Base64: toda requisição com corpo (salvamento, conclusão, e busca por POST) envia o payload como JSON em Base64, dentro de
{ "data": "" }, comContent-Type: application/json. A busca por GET é a exceção — usa query string, sem Base64.Resposta da busca sem envelope: precisa ser lista ou objeto no nível raiz, nunca dentro de outro campo.
Nomes fixos na busca: a identificação chega como
email/cpf/documente o carrinho comoorderFormId. 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