> ## Documentation Index
> Fetch the complete documentation index at: https://docs.centralcart.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Visão geral da Storefront API

> A API pública que serve a vitrine da sua loja, no storefront da CentralCart ou em uma vitrine própria.

A **Storefront API** é a camada pública da CentralCart. É ela que alimenta a vitrine:
catálogo, categorias, carrinho, cupons, upsells, criação de pedido, conta do comprador e
programa de afiliados.

Ela existe em dois cenários:

<CardGroup cols={2}>
  <Card title="No storefront da CentralCart" icon="store">
    Os templates Liquid já consomem estes endpoints. Você os chama diretamente do
    navegador quando escreve JavaScript no editor de códigos.
  </Card>

  <Card title="Em uma vitrine própria (headless)" icon="code">
    Você constrói o front no seu framework (Next.js, Nuxt, Astro) e usa a CentralCart
    apenas como backend de catálogo e pagamento.
  </Card>
</CardGroup>

## Base URL

```
https://api.centralcart.io/v1
```

## Identificando a loja

Todo endpoint da Storefront API exige o header `x-store-domain` com o domínio da loja.
É ele que diz à API de qual loja você está falando. Não há chave de API envolvida.

```bash theme={null}
curl https://api.centralcart.io/v1/webstore \
  -H "x-store-domain: sualoja.centralcart.ai"
```

Vale tanto o subdomínio da CentralCart (`sualoja.centralcart.ai`) quanto qualquer
domínio próprio já ativo na loja (`loja.meusite.com`). Se o domínio não resolver para
nenhuma loja, a API responde `404`.

<Note>
  O valor é o domínio **da loja na CentralCart**, não o domínio onde o seu front está
  hospedado. Um app Next.js rodando em `minhaloja.vercel.app` continua enviando
  `x-store-domain: sualoja.centralcart.ai`.
</Note>

## Autenticação

A API se divide em dois grupos.

**Sem sessão.** Loja, catálogo, carrinho, upsells, cupom, checkout e acompanhamento do
pedido. Qualquer visitante pode chamá-los: basta o `x-store-domain`.

**Com sessão do comprador.** Conta, histórico de pedidos e programa de afiliados. Aqui
entra um `access_token` obtido pelo login por código de e-mail, enviado em
`Authorization: Bearer`. Veja
[Autenticação do cliente](/api-reference/storefront/autenticacao-do-cliente).

<Warning>
  A sessão do comprador não tem nada a ver com a chave privada da loja (a de
  [Autenticação](/api-reference/authentication)). Nunca use a chave privada em código que
  roda no navegador: ela dá acesso de escrita a pedidos, produtos e estoque. No front,
  apenas a Storefront API.
</Warning>

## Um fluxo de checkout completo

Os endpoints se encaixam nesta ordem:

<Steps>
  <Step title="Carregue a loja e o catálogo">
    [`GET /webstore`](/api-reference/loja/store-info) traz nome, moeda, tema e quais
    dados do comprador a loja exige.
    [`GET /webstore/category`](/api-reference/catalogo/list-categories) e
    [`GET /webstore/package`](/api-reference/catalogo/list-packages) montam a vitrine.
  </Step>

  <Step title="Resolva o carrinho no servidor">
    [`POST /webstore/cart`](/api-reference/checkout/resolve-cart) devolve os preços
    autorizados. O carrinho vive no navegador, então o preço guardado lá não é
    confiável. Sempre exiba o total com base nesta resposta.
  </Step>

  <Step title="Ofereça upsells e aplique o cupom">
    [`POST /webstore/upsells`](/api-reference/checkout/list-upsells) e
    [`GET /webstore/discount/{code}`](/api-reference/checkout/get-discount).
  </Step>

  <Step title="Descubra o que o pagamento exige">
    [`GET /webstore/gateway`](/api-reference/loja/list-gateways) diz quais métodos estão
    ativos e quais campos do comprador cada um exige. Combine com
    [`GET /webstore/checkout_fields`](/api-reference/loja/list-checkout-fields) para os
    campos personalizados da loja.
  </Step>

  <Step title="Crie o pedido">
    [`POST /webstore/checkout`](/api-reference/checkout/create-checkout) devolve
    `checkout_url` para redirecionar, ou o código PIX e o QR Code.
  </Step>

  <Step title="Acompanhe o pagamento">
    [`GET /webstore/order_status/{order_id}`](/api-reference/checkout/get-order-status)
    para fazer polling na tela do PIX até o status virar `APPROVED`.

    Se você tem um backend, prefira o webhook `ORDER_APPROVED`. Veja
    [Webhooks](/api-reference/webhooks).
  </Step>
</Steps>

## Depois da compra

O checkout não é o fim da vitrine. Com a sessão do comprador em mãos, dois grupos abrem:

<CardGroup cols={2}>
  <Card title="Conta do comprador" icon="receipt" href="/api-reference/conta/list-my-orders">
    Histórico de pedidos, detalhe com o conteúdo entregue e envio de avaliação.
  </Card>

  <Card title="Afiliados" icon="share-nodes" href="/api-reference/afiliados/get-affiliate-panel">
    O comprador vira afiliado, cria links de indicação, acompanha o extrato e pede saque.
  </Card>
</CardGroup>

Para atribuir uma venda a quem indicou, resolva o `?ref=` da URL com
[`GET /webstore/affiliate/ref/{code}`](/api-reference/afiliados/resolve-referral-code),
guarde o código pelos dias que ele informar e mande em `affiliate_code` no checkout.

## Preços são sempre resolvidos no servidor

Vale repetir porque é o erro mais comum ao construir uma vitrine própria: **nenhum preço
enviado pelo cliente é aceito**.

O `POST /webstore/cart` re-resolve o preço de cada item, incluindo ofertas de upsell
amarradas ao produto-gatilho. O `POST /webstore/checkout` refaz essa mesma resolução por
conta própria, de forma independente. Um valor adulterado no navegador não passa nem na
exibição nem na cobrança.

Por isso o carrinho do seu front deve guardar apenas **IDs e quantidades**, nunca preços.

## Campos personalizados: dois níveis

A CentralCart tem dois tipos de campo personalizado, e eles vão para lugares diferentes
no checkout:

| Origem                                                                                             | Onde aparece                 | Para onde vai no checkout     |
| -------------------------------------------------------------------------------------------------- | ---------------------------- | ----------------------------- |
| [`GET /webstore/checkout_fields`](/api-reference/loja/list-checkout-fields)                        | Uma vez por pedido           | `fields` na raiz do body      |
| Array `fields` de cada produto em [`GET /webstore/package`](/api-reference/catalogo/list-packages) | Uma vez por item do carrinho | `options` do item em `cart[]` |

Em ambos, a chave é o `name` do campo.

## Formato de erro

Erros seguem sempre o mesmo envelope. Veja [Erros](/api-reference/erros) para a lista de
status e como tratar cada um.

```json theme={null}
{
  "errors": [
    { "message": "Cupom de desconto não encontrado." }
  ]
}
```

<Tip>
  Endpoints de catálogo mudam pouco. Se o seu front tem camada de servidor (Server
  Components no Next.js, por exemplo), busque o catálogo lá com cache e revalidação.
  A página fica mais rápida e a sua loja aguenta muito mais tráfego simultâneo.
</Tip>
