VenddorDocumentação API
API atualAPI legada
Guia rápidoReferência completa
Carregando índice…
API atual/Referência completa/Kits, mestres e caixas

Mixes

Lista e abre os mixes liberados para o cliente logado e calcula como o preço fechado de um mix se distribui entre as linhas do carrinho.

Um mix é um conjunto de produtos com preço fechado, montado pela loja ou por um seller para clientes específicos (por exemplo, o sortimento de um cliente B2B). O mix tem componentes, cada um com quantidade, se é obrigatório e, opcionalmente, um grupo de troca (swap_group): quando o mix permite escolha (allow_customer_pick), o cliente pode trocar um componente por outro produto do mesmo grupo.

Os mixes são por cliente: a lista depende de quem está logado, por isso todas as rotas exigem login.

Quem vê qual mix

Só entram mixes com status ativo. Um mix public aparece para todo cliente logado. Um customer-list aparece para clientes ou grupos de clientes atribuídos a ele. Um private aparece somente para clientes atribuídos diretamente (a atribuição por grupo não vale). Se o mix existe mas não é visível para o cliente, o detalhe e a resolução respondem 404, como se não existisse.

GET/api/v1/storefront/mix-productsCliente

Listar mixes visíveis ao cliente

Exige o módulo mix-products ligado e login do cliente. A resposta não é paginada.

Cabeçalhos

Authorizationstringobrigatório
Bearer <token> do cliente.

Exemplo de requisição

bash
curl "$BASE_URL/api/v1/storefront/mix-products" \
  -H "Authorization: Bearer $TOKEN"

Resposta

200Mixes do cliente
json
{
  "mixes": [
    {
      "id": "4b7e2d90-61c3-4f1a-9a0e-2c5d8f3b7a16",
      "vendor_id": "94bd7e9a-fdad-4d01-8fc2-ba9d677d8b36",
      "name": "Kit Reposição Mensal",
      "description": "Os itens de giro do mês.",
      "sku": "MIX-001",
      "status": "A",
      "bundle_price_centavos": 25000,
      "currency": "BRL",
      "visibility": "customer-list",
      "min_components": 1,
      "max_components": 2,
      "allow_customer_pick": true,
      "image_url": "",
      "created_at": "2026-09-01T12:00:00Z",
      "updated_at": "2026-09-10T09:30:00Z",
      "components": [
        {
          "id": "c1d2e3f4-0a1b-4c2d-8e3f-9a0b1c2d3e4f",
          "mix_id": "4b7e2d90-61c3-4f1a-9a0e-2c5d8f3b7a16",
          "product_id": "5e833a7f-1a77-402c-835a-32594350d7a7",
          "quantity": 2,
          "sort_order": 0,
          "is_required": true,
          "allow_swap": true,
          "swap_group": "cafe",
          "product_name": "Café em grãos 1 kg",
          "product_sku": "CAF-001",
          "product_price_centavos": 9000,
          "product_image": "/uploads/exemplo/cafe.png"
        }
      ],
      "component_subtotal_centavos": 18000,
      "savings_centavos": 0
    }
  ]
}

Campos da resposta

mixesarray
Mixes visíveis ao cliente, do mais novo ao mais antigo. Lista vazia quando não há nenhum.
mixes[].iduuid
Id do mix.
mixes[].vendor_iduuid
Seller dono do mix. Ausente em mix da própria loja.
mixes[].namestring
Nome.
mixes[].descriptionstring
Descrição.
mixes[].skustring
SKU do mix.
mixes[].statusstring
Sempre A nesta rota.
mixes[].bundle_price_centavosinteger
Preço fechado do mix inteiro, em centavos. 0 significa mix gratuito.
mixes[].currencystring
Moeda (BRL).
mixes[].visibilitystring
publicprivatecustomer-list
Quem pode ver (veja o quadro acima).
mixes[].min_componentsinteger
Mínimo de componentes escolhidos quando há escolha. 0 sem mínimo.
mixes[].max_componentsinteger
Máximo de componentes escolhidos quando há escolha. 0 sem máximo.
mixes[].allow_customer_pickboolean
true se o cliente escolhe os componentes; false se o mix é levado inteiro.
mixes[].image_urlstring
Imagem do mix, pode ser vazia.
mixes[].created_atstring
Criação (RFC 3339, UTC).
mixes[].updated_atstring
Última alteração (RFC 3339, UTC).
mixes[].componentsarray
Componentes do mix.
mixes[].components[].iduuid
Id do componente (é o que se manda em choices[].component_id).
mixes[].components[].mix_iduuid
Id do mix.
mixes[].components[].product_iduuid
Produto do componente.
mixes[].components[].quantityinteger
Unidades do componente por mix.
mixes[].components[].sort_orderinteger
Posição de exibição.
mixes[].components[].is_requiredboolean
Obrigatório quando há escolha (pode ser trocado por um item do mesmo grupo).
mixes[].components[].allow_swapboolean
Se o componente aceita troca.
mixes[].components[].swap_groupstring
Grupo de troca: só produtos de componentes do mesmo grupo (e allow_swap) podem substituí-lo. Ausente sem grupo.
mixes[].components[].product_namestring
Nome do produto.
mixes[].components[].product_skustring
SKU do produto.
mixes[].components[].product_price_centavosinteger
Preço unitário de tabela do produto, em centavos.
mixes[].components[].product_imagestring
Imagem do produto.
mixes[].component_subtotal_centavosinteger
Soma de preço x quantidade de todos os componentes, em centavos.
mixes[].savings_centavosinteger
Economia em relação ao subtotal: component_subtotal_centavos menos bundle_price_centavos, nunca negativa.

Erros

StatusQuandoCorpo
401Sem login.{"error":"missing authorization header"} (ou invalid authorization format, se o cabeçalho está malformado)
403Módulo mix-products desligado.{"error":"module_disabled","module":"mix-products"}
500Falha interna.{"error":"internal_error","message":"..."}
GET/api/v1/storefront/mix-products/{id}Cliente

Detalhe de um mix

Mesmo formato de um item da lista. Responde 404 se o mix não existe ou não é visível ao cliente.

Parâmetros de caminho

iduuidobrigatório
Id do mix.

Exemplo de requisição (detalhe)

bash
curl "$BASE_URL/api/v1/storefront/mix-products/4b7e2d90-61c3-4f1a-9a0e-2c5d8f3b7a16" \
  -H "Authorization: Bearer $TOKEN"

Resposta (detalhe)

200Mix visível
json
{
  "id": "4b7e2d90-61c3-4f1a-9a0e-2c5d8f3b7a16",
  "name": "Kit Reposição Mensal",
  "sku": "MIX-001",
  "status": "A",
  "bundle_price_centavos": 25000,
  "currency": "BRL",
  "visibility": "customer-list",
  "min_components": 1,
  "max_components": 2,
  "allow_customer_pick": true,
  "components": [
    {
      "id": "c1d2e3f4-0a1b-4c2d-8e3f-9a0b1c2d3e4f",
      "mix_id": "4b7e2d90-61c3-4f1a-9a0e-2c5d8f3b7a16",
      "product_id": "5e833a7f-1a77-402c-835a-32594350d7a7",
      "quantity": 2,
      "is_required": true,
      "allow_swap": true,
      "swap_group": "cafe",
      "product_price_centavos": 9000
    }
  ],
  "component_subtotal_centavos": 18000,
  "savings_centavos": 0
}

Os campos são os do item da lista, com uma diferença: o detalhe pode trazer também assignments (as atribuições do mix a clientes e grupos). É dado de gestão da loja: não o exiba nem dependa dele.

Erros (detalhe)

StatusQuandoCorpo
401Sem login.{"error":"missing authorization header"}
403Módulo desligado.{"error":"module_disabled","module":"mix-products"}
404Mix inexistente ou não visível ao cliente.{"error":"not_found","message":"mix not found or not visible"}
POST/api/v1/storefront/mix-products/{id}/resolveCliente

Resolver a escolha em linhas de carrinho

Recebe a escolha do cliente e calcula as linhas que o mix gera, com o preço fechado distribuído entre elas proporcionalmente ao preço de tabela. Não grava nada: não adiciona ao carrinho nem reserva estoque. O resultado é a base para o carrinho receber as linhas.

Se o mix não permite escolha (allow_customer_pick: false) e choices vem vazio, a plataforma assume todos os componentes.

Parâmetros de caminho

iduuidobrigatório
Id do mix.

Cabeçalhos

Authorizationstringobrigatório
Bearer <token> do cliente.
Content-Typestringobrigatório
application/json.

Corpo da requisição

choicesarray
Componentes escolhidos. Obrigatório quando o mix permite escolha. Sem escolha, o mix precisa ter allow_customer_pick: false.
choices[].component_iduuidobrigatório
Id do componente (components[].id).
choices[].product_iduuidobrigatório
Produto escolhido. Igual ao product_id do componente, ou outro produto de um componente do mesmo swap_group quando o componente aceita troca.

Exemplo de requisição (resolver)

bash
curl -X POST "$BASE_URL/api/v1/storefront/mix-products/4b7e2d90-61c3-4f1a-9a0e-2c5d8f3b7a16/resolve" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"choices":[{"component_id":"c1d2e3f4-0a1b-4c2d-8e3f-9a0b1c2d3e4f","product_id":"5e833a7f-1a77-402c-835a-32594350d7a7"}]}'

Resposta (resolver)

200Linhas do carrinho geradas
json
{
  "mix_id": "4b7e2d90-61c3-4f1a-9a0e-2c5d8f3b7a16",
  "bundle_price_centavos": 25000,
  "component_subtotal_centavos": 18000,
  "savings_centavos": 0,
  "lines": [
    {
      "product_id": "5e833a7f-1a77-402c-835a-32594350d7a7",
      "product_name": "Café em grãos 1 kg",
      "product_sku": "CAF-001",
      "quantity": 2,
      "unit_price_centavos": 12500,
      "line_total_centavos": 25000,
      "mix_id": "4b7e2d90-61c3-4f1a-9a0e-2c5d8f3b7a16",
      "component_id": "c1d2e3f4-0a1b-4c2d-8e3f-9a0b1c2d3e4f"
    }
  ]
}

Campos da resposta

mix_iduuid
Mix resolvido.
bundle_price_centavosinteger
Preço fechado do mix, em centavos.
component_subtotal_centavosinteger
Soma dos preços de tabela dos componentes escolhidos, em centavos.
savings_centavosinteger
Economia (subtotal menos preço fechado), nunca negativa.
linesarray
Uma linha por componente escolhido.
lines[].product_iduuid
Produto da linha (o escolhido, que pode ser a troca).
lines[].product_namestring
Nome do produto.
lines[].product_skustring
SKU do produto.
lines[].quantityinteger
Quantidade da linha (a do componente).
lines[].unit_price_centavosinteger
Preço unitário rateado, arredondado para baixo. Use line_total_centavos como valor oficial da linha.
lines[].line_total_centavosinteger
Total da linha em centavos. A soma das linhas é igual ao preço fechado (a última linha absorve o arredondamento).
lines[].mix_iduuid
Mix de origem, para marcar a linha no carrinho.
lines[].component_iduuid
Componente de origem.

Erros (resolver)

StatusQuandoCorpo
400Corpo não é JSON válido.{"error":"invalid_body","message":"<erro de leitura>"}
400Escolha inválida: componente de outro mix, troca não permitida ou fora do grupo, falta de componente obrigatório, menos que min_components ou mais que max_components, ou mix sem escolha com choices diferente de todos os componentes.{"error":"invalid_input","message":"mix-products: invalid input: minimum 1 components required, got 0"}
401Sem login.{"error":"missing authorization header"}
403Módulo desligado.{"error":"module_disabled","module":"mix-products"}
404Mix inexistente ou não visível ao cliente.{"error":"not_found","message":"mix not found or not visible"}
Resolver não verifica estoque nem disponibilidade

A rota só aplica as regras do mix e rateia o preço. Estoque, status do produto e preço de cada linha são verificados quando as linhas entram no carrinho e no fechamento da compra.

Veja também

  • Kits
  • Caixas de produto
  • Kits e conjuntos: visão geral
Anterior
Modo catálogo
Próxima
Caixas de produto
Nesta página
  • Exemplo de requisição
  • Resposta
  • Erros
  • Exemplo de requisição (detalhe)
  • Resposta (detalhe)
  • Erros (detalhe)
  • Exemplo de requisição (resolver)
  • Resposta (resolver)
  • Erros (resolver)
  • Veja também