This commit is contained in:
Daniel Arantes Loverde
2026-02-15 08:18:06 -03:00
parent d7b8b1864a
commit 0f5ad4c268
35 changed files with 4090 additions and 309 deletions

View File

@@ -22,7 +22,6 @@ Todas as chamadas devem usar autenticação híbrida.
**GET** `/api/store/:storeId/info` - Retorna a configuração completa da loja, incluindo dados bancários, horários e flags de pagamento.
**Resposta Exemplo:**
```json
{
"error": false,
@@ -73,7 +72,6 @@ Todas as chamadas devem usar autenticação híbrida.
**GET** `/api/store/:storeId/dashboard`
**Resposta Detalhada (100% Parity):**
```json
{
"error": false,
@@ -104,9 +102,84 @@ Todas as chamadas devem usar autenticação híbrida.
## 🍴 Catálogo e Menu (Complex Payloads)
### 4. Categorias de Pizza
**POST** `/api/store/:storeId/catalog/categories`
### 3.1 Catálogo Consolidado (App)
**GET** `/api/store/:storeId/catalog`
**Resposta:**
```json
{
"error": false,
"code": "STORE_CATALOG_RETRIEVED",
"result": [
{
"id": "cat_lanches",
"name": "Lanches",
"isPizzaCategory": false,
"products": [
{
"id": "prod_xburger",
"type": "prepared",
"name": "X-Burger",
"description": "Pão, carne e queijo",
"image": "/uploads/products/xburger.jpg",
"price": "25.00",
"addons": "yes",
"addonGroups": []
}
]
},
{
"id": "cat_pizzas",
"name": "Pizzas",
"isPizzaCategory": true,
"pizzaConfig": {
"sizes": [{ "id": "broto", "name": "Broto", "slices": 4, "maxFlavors": 1 }],
"doughs": [{ "id": "tradicional", "name": "Tradicional", "active": true }],
"crusts": [{ "id": "catupiry", "name": "Catupiry", "active": true, "priceModifier": "10.00" }]
},
"products": [
{
"id": "prod_pizza_calabresa",
"type": "pizza",
"name": "Pizza Calabresa",
"description": "Molho, mussarela e calabresa",
"image": "/uploads/products/pizza-calabresa.jpg",
"price": "0.00",
"pizzaPrices": {
"broto": "35.00",
"grande": "55.00"
},
"addons": "yes",
"addonGroups": []
}
]
}
]
}
```
**Regra de identificação de pizza:**
- Item pizza: `products[].type === "pizza"`.
- Configuração de montagem vem em `category.pizzaConfig`.
- Preço por tamanho vem em `product.pizzaPrices`.
### 4. Listar Categorias do Catálogo
**GET** `/api/store/:storeId/catalog/categories`
**Resposta:**
```json
{
"error": false,
"code": "CATEGORIES_RETRIEVED",
"result": [
{ "id": "cat_1", "name": "Pizzas", "isActive": true }
],
"message": "Categorias recuperadas com sucesso"
}
```
### 5. Criar Categoria (Ex.: Pizza)
**POST** `/api/store/:storeId/catalog/categories`
```json
{
"name": "Pizzas Salgadas",
@@ -122,9 +195,14 @@ Todas as chamadas devem usar autenticação híbrida.
}
```
### 5. Produtos Tipo Combo ou Pizza
**POST** `/api/store/:storeId/catalog/products`
### 6. Atualizar Categoria
**PUT** `/api/store/:storeId/catalog/categories/:id`
### 7. Excluir Categoria
**DELETE** `/api/store/:storeId/catalog/categories/:id`
### 8. Produtos Tipo Combo ou Pizza
**POST** `/api/store/:storeId/catalog/products`
```json
{
"type": "pizza",
@@ -148,11 +226,10 @@ Todas as chamadas devem usar autenticação híbrida.
## 📦 Histórico e Detalhes do Pedido
### 6. Histórico com Filtros
### 9. Histórico com Filtros
**GET** `/api/store/:storeId/orders/history?start=2024-01-01&end=2024-01-31&q=Ana`
**Objeto de Pedido Completo (result.list[0]):**
```json
{
"id": "order_guid",
@@ -181,7 +258,7 @@ Todas as chamadas devem usar autenticação híbrida.
> O campo `confirmOtp` (8 dígitos) é o código que o motoboy deve utilizar para iniciar a confirmação. O `customerOtp` (4 dígitos do cliente) **NÃO** é retornado via API por questões de segurança.
```
### 7. Detalhes de um Pedido Individual
### 10. Detalhes de um Pedido Individual
**GET** `/api/store/:storeId/orders/:orderId`
Retorna o objeto completo do pedido (parity 100% com o painel).
@@ -190,7 +267,7 @@ Retorna o objeto completo do pedido (parity 100% com o painel).
## 💰 Financeiro Detalhado
### 7. Resumo de Performance e Gateway
### 11. Resumo de Performance e Gateway
**GET** `/api/store/:storeId/financial/summary`
**Resposta:**
@@ -216,7 +293,7 @@ Retorna o objeto completo do pedido (parity 100% com o painel).
## ⭐ Reviews e Avaliações
### 8. Métricas e Respostas
### 12. Métricas e Respostas
**GET** `/api/store/:storeId/reviews`
**Resposta:**
@@ -330,13 +407,58 @@ Endpoints utilizados pela página pública (CORS habilitado para domínios parce
---
## 🛒 Checkout e Criação de Pedido
### 10.0 Validar Endereço de Entrega (Checkout)
**POST** `/api/store/:storeId/delivery/validate-address`
Endpoint para validar cobertura de entrega no checkout, quando o cliente troca o endereço antes do pagamento.
**Payload:**
```json
{
"address": {
"street": "Avenida das Andorinhas",
"number": "477",
"neighborhood": "Jardim Andorinhas",
"city": "Campinas",
"state": "SP",
"zip": "13101-400",
"lat": -22.918,
"lng": -47.01813
}
}
```
**Resposta Exemplo:**
```json
{
"error": false,
"code": "DELIVERY_ADDRESS_VALIDATED",
"result": {
"deliveryAllowed": true,
"reasonCode": "DELIVERY_ALLOWED",
"reasonMessage": "Endereço válido para entrega",
"deliveryMode": "KM",
"distance": 1.3,
"deliveryFee": 8,
"deliveryTime": "35 min",
"sameCity": false,
"matchedKmRange": { "from": 1, "to": 2, "price": 8, "time": 35 },
"matchedNeighborhood": null
}
}
```
**Regras:**
- `KM`: aprova somente até o limite da última faixa + `0.5 km` de tolerância.
- `NEIGHBORHOOD`: reprova se a cidade do endereço for diferente da cidade da loja.
- `NEIGHBORHOOD`: aprova com bairro configurado ou com fallback de mesma cidade.
### 10. Criar Novo Pedido (Public)
**POST** `/api/public/orders`
Este endpoint é utilizado pelo front-end de checkout (Pedi Foods) para criar o pedido no sistema da loja.
**Payload:**
```json
{
"storeId": "store_123456",
@@ -367,23 +489,152 @@ Este endpoint é utilizado pelo front-end de checkout (Pedi Foods) para criar o
"name": "Pizza",
"price": 50.00,
"qty": 1,
"image": "..."
"image": "...",
"addons": [
{
"addonId": "addon_bacon",
"name": "Bacon",
"price": 4.00,
"qty": 2
}
]
}
]
}
```
**Resposta Sucesso:**
**Regras para `items[].addons`:**
- `qty` do adicional é suportado (ex.: 2x bacon/ovo).
- Se `qty` não for enviado ou vier inválido, a API assume `1`.
- `qty` mínimo efetivo é `1`.
**Resposta Sucesso:**
```json
{
"error": false,
"result": {
"id": "order_guid",
"shortId": "1234",
"status": "PENDING",
"status": "PAYMENT_PENDING",
"paymentStatus": "PENDING",
"paymentPayload": "..." // Se PIX (Big String Base64 ou Copia e Cola)
"paymentMethod": "PIX",
"paymentPayload": {
"copyPaste": "000201010212...",
"qrCodeImage": "iVBORw0KGgoAAAANSUhEUgAA...",
"expirationDate": "2026-02-14T22:30:00.000Z"
},
"payment": {
"method": "PIX",
"status": "PENDING",
"pix": {
"copyPaste": "000201010212...",
"qrCodeImage": "iVBORw0KGgoAAAANSUhEUgAA...",
"expirationDate": "2026-02-14T22:30:00.000Z"
}
}
}
}
```
**Observação de segurança:** o Atomenta não retorna links de checkout/fatura do Asaas no response de criação de pedido.
### 10.1 Realtime de Status de Pedido (Socket.IO)
Para atualização em tempo real do checkout/app (sem depender de push), usar Socket.IO.
**Socket endpoint:**
- `ws://<host>:<port>/socket.io/` (usar `wss://` em produção com TLS)
**Auth no handshake:**
- Enviar JWT no campo `auth.token`.
- Exemplo: `Bearer <JWT_TOKEN>`.
**Evento para o cliente:**
- `order_update`
**Payload típico do evento:**
```json
{
"id": "order_guid",
"shortId": "1234",
"storeId": "store_123456",
"userId": "user_guid",
"status": "CONFIRMED",
"paymentStatus": "CONFIRMED",
"updatedAt": "2026-02-15T20:10:00.000Z"
}
```
### 10.2 Fallback de Status (Polling)
Caso não haja conexão socket, consultar status por HTTP até estado final.
**Endpoint:**
- `GET /api/public/orders/:orderId`
**Recomendação de intervalo:**
- 0-60s: `3s`
- 60-180s: `5s`
- acima de 180s: `10s`
- parar em status final (`COMPLETED`, `CANCELED`, `REFUNDED`).
### 11. Listar Lojas (Public App)
**GET** `/api/public/stores`
Endpoint utilizado pelo aplicativo Pedi Foods para listar todas as lojas disponíveis para o cliente.
**Resposta Sucesso:**
```json
{
"error": false,
"result": [
{
"id": "company_guid",
"storeId": "store_123456",
"name": "Pizzaria do Arantes",
"logo": "https://...",
"cover": "https://...",
"category": "Restaurante",
"isOpen": true,
"statusLabel": "Aberto Agora",
"rating": 4.8,
"deliveryTime": "30-45 min",
"deliveryFee": 5.00
}
]
}
```
---
## 📝 Gestão de Contratos (Store)
### 12. Verificar Status do Contrato
**GET** `/api/store/:storeId/contract/status`
Retorna o ID e o status do contrato mais recente da loja.
**Resposta Exemplo:**
```json
{
"error": false,
"result": {
"id": "contract_guid",
"status": "draft" // ou "signed"
}
}
```
### 13. Assinar Contrato
**POST** `/api/store/:storeId/contract/sign`
Assina o contrato draft atual da loja.
**Payload:**
```json
{
"method": "typed",
"typedName": "João Silva", // Obrigatório se method === "typed"
"signatureDataUrl": "data:image/png;base64,..." // Obrigatório se method === "draw"
}
```
### 14. Visualizar PDF do Contrato
**GET** `/api/store/contract/:contractId/pdf`
Retorna o stream do arquivo PDF do contrato (draft ou assinado).