# Retirada na loja

Pedidos com `delivery_method=pickup`: o cliente paga online (ou no balcão) e **vai buscar pessoalmente**. Sem transportadora, sem rastreio — no lugar disso, um código de confirmação que o cliente apresenta na hora de retirar.

> Pré-requisitos: leia primeiro [Pedidos: visão geral](/guia/pedidos). Os conceitos de `possible-statuses`, rota única `/status` e `workflow_type` valem aqui também.

---

## Quando um pedido cai aqui

Retirada é um **eixo de fulfillment**, não um perfil comercial: o que manda é o campo `delivery_method=pickup`, definido na criação do pedido. Qualquer `workflow_type` pode terminar em retirada — um pedido de industrialização, por exemplo, passa pela fábrica e depois fica pronto para o cliente buscar. Em pedidos antigos você ainda encontra `workflow_type=in_store_pickup`; trate igual.

```jsonc
{
  "order_number": "ORD-000456",      // identificador público do pedido
  "delivery_method": "pickup",       // ← é por aqui que você reconhece
  "workflow_type": "in_store_pickup",
  "status": "ready_for_pickup",
  "pickup_address": {…},             // onde o cliente retira (quando definido)
  "picked_up_at": null               // preenche quando o cliente buscar
}
```

O que muda na prática: o pedido **nunca passa** por `ready_to_ship`/`shipped`. O `possible-statuses` já cuida disso — em pedidos de retirada, os status de envio nem aparecem como opção (e vice-versa: pedidos de envio nunca veem os status de retirada).

---

## O caminho

```mermaid
stateDiagram-v2
    direction LR
    [*] --> paid
    paid --> preparing
    preparing --> ready_for_pickup
    ready_for_pickup --> picked_up: código<br/>confirmado
    ready_for_pickup --> pickup_expired: prazo<br/>estourou
    picked_up --> delivered: automático
    pickup_expired --> cancelled: automático
    delivered --> [*]
    cancelled --> [*]
```

A bifurcação em relação ao fluxo de [entrega](/guia/pedidos-entrega) acontece **em `preparing`**: onde o pedido de envio iria para `ready_to_ship`, o de retirada vai para `ready_for_pickup`. Antes disso, o começo é idêntico.

> Você pode encontrar um status `reserved` no catálogo de enums. Ignore-o ao integrar: nenhuma transição parte de `paid` para ele — o caminho real é `paid → preparing → ready_for_pickup`.

## Etapa a etapa

| Status | O que significa | Sua ação | Próximo |
|---|---|---|---|
| `paid` | Pagamento confirmado. | `{ "status": "preparing" }` quando começar a separar. | `preparing` |
| `preparing` | Separando o pedido. **Emita aqui a NF-e ou Declaração** ([fiscal](/guia/pedidos-fiscal)) — sem documento, a próxima transição é recusada. | `{ "status": "ready_for_pickup" }` com o pedido separado e documento emitido. | `ready_for_pickup` |
| `ready_for_pickup` | Cliente avisado de que pode buscar. O relógio de expiração está correndo. | Quando o cliente aparecer: `{ "status": "picked_up", "data": { "confirmation_code": "4821" } }` com o código que **ele** apresentar. | `picked_up` → `delivered` |
| `picked_up` | Cliente retirou. | Nada — o sistema encadeia `delivered` **no mesmo request**. | `delivered` (automático) |
| `pickup_expired` | O prazo de retirada venceu sem o cliente aparecer. | Nada — o sistema cascateia o cancelamento com estorno. | `cancelled` (automático) |

Tudo pela dupla de sempre:

<a class="api-route" href="/reference/pedidos#tag/pedidos/GET/api/v1/sellers/orders/{id}/possible-statuses"><span class="api-method api-method-get">GET</span><span class="api-path">/api/v1/sellers/orders/{id}/possible-statuses</span></a>

<a class="api-route" href="/reference/pedidos#tag/pedidos/POST/api/v1/sellers/orders/{id}/status"><span class="api-method api-method-post">POST</span><span class="api-path">/api/v1/sellers/orders/{id}/status</span></a>

---

## O código de confirmação

É a peça central da retirada — e a parte mais incompreendida.

**Quem tem o código é o cliente, não você.** Um código numérico de 4 dígitos é gerado na criação do pedido e entregue só ao comprador (ele vê no acompanhamento do pedido dele). A API **nunca devolve esse código para a loja** — nem no detalhe do pedido, nem no `metadata`. É de propósito: o código prova que quem está no balcão é o comprador. Sua integração não consulta o código; ela **digita o que o cliente apresentar**.

```http
POST /api/v1/sellers/orders/ORD-000456/status
Content-Type: application/json

{ "status": "picked_up", "data": { "confirmation_code": "4821" } }
```

O `confirmation_code` é obrigatório nessa transição (o `payload_schema` do `possible-statuses` marca `required`). O que pode dar errado:

| Resposta | Quando | Como tratar |
|---|---|---|
| `422` em `confirmation_code` — "Código de confirmação incorreto. N tentativa(s) restante(s)." | Cliente ditou errado. | Peça para conferir e tente de novo. São **10 tentativas no total**. |
| `422` — "Pedido bloqueado por excesso de tentativas." | Estourou as 10 tentativas. | Só o suporte da plataforma destrava. |
| `422` em `status` — "ainda não está pronto para retirada" | Pedido não está em `ready_for_pickup`. | Confira o estado atual antes de confirmar. |
| `200`, mas o pedido virou `pickup_expired` | O prazo venceu antes da confirmação. | A expiração tem precedência — ver abaixo. |

**Confirmou, acabou.** O `picked_up` encadeia `delivered` automaticamente no mesmo request (o ato de digitar o código *é* a entrega física). Não chame `delivered` depois — a resposta já volta com o pedido entregue, e `picked_up_at` preenchido.

---

## Expiração da retirada

O pedido tem um prazo para ser retirado (por padrão, **3 dias** a partir da criação). Vencido o prazo:

- Uma tentativa de confirmação tardia move o pedido para `pickup_expired` em vez de aceitar a retirada — mesmo com o código certo.
- Você também pode marcar manualmente: `{ "status": "pickup_expired" }`.
- Em seguida o **sistema cancela sozinho** (`pickup_expired → cancelled`), disparando o pipeline completo: estorno ao cliente, liberação do estoque reservado, e-mail. Você não precisa (nem deve) chamar `cancelled` por conta própria.

Na timeline (`GET /orders/{id}/events`) o cancelamento aparece com motivo "Retirada expirada" e autoria do sistema. Cliente desistiu mas o prazo ainda não venceu? Aí é um cancelamento comum — ver abaixo.

---

## Cancelamento

Mesma regra dos outros fluxos: o seller só cancela **antes da preparação**. Em `paid`, mande `{ "status": "cancelled" }` com um `reason` opcional. De `preparing` em diante, o `possible-statuses` esconde a opção e a API recusa — cancelamento vira assunto da operação da plataforma.

A exceção prática é a expiração: `pickup_expired → cancelled` acontece sozinho, sem depender de ninguém.

---

## Emissão fiscal

A janela abre em `preparing` e segue aberta em `ready_for_pickup` e `picked_up` (e `delivered`). Retirada presencial **não dispensa documento**: a transição `preparing → ready_for_pickup` tem o mesmo gate fiscal do envio e recusa com 422 (campo `fiscal`) se não houver NF-e ou Declaração de Conteúdo emitida.

Ordem prática: separar → emitir documento ([fiscal](/guia/pedidos-fiscal)) → `ready_for_pickup` → aguardar o cliente. Etiqueta de transporte não se aplica — não há shipment de transportadora para gerar.

---

## Para onde ir agora

| Você precisa… | Vá para |
|---|---|
| Fluxo com envio/transportadora | [Pedidos: entrega](/guia/pedidos-entrega) |
| Emitir NF-e ou Declaração | [Pedidos: fiscal](/guia/pedidos-fiscal) |
| Pedido fabricado sob demanda (pode terminar em retirada) | [Pedidos: industrialização](/guia/pedidos-industrializacao) |
| Schemas e códigos de erro | [Referência da API](/reference/pedidos) |
