Skip and docs
This commit is contained in:
389
API_Store_External.md
Normal file
389
API_Store_External.md
Normal file
@@ -0,0 +1,389 @@
|
||||
# Atomenta API - Store Management & External Guide (Pedi Foods Edition)
|
||||
|
||||
Este documento é o guia definitivo e completo para parceiros e aplicações externas (como pedifoods.com.br) que consomem a API da plataforma Atomenta para gestão de lojas. **Esta API reflete 100% das funcionalidades do painel administrativo.**
|
||||
|
||||
## 🔐 Autenticação e Headers
|
||||
|
||||
Todas as chamadas devem usar autenticação híbrida.
|
||||
|
||||
### Headers Obrigatórios:
|
||||
- **Accept**: `application/json`
|
||||
- **Atomenta-Token**: `550e8400-e29b-41d4-a716-446655440008` (Escopo: Store Management)
|
||||
- **Authorization**: `Bearer <JWT_TOKEN>`
|
||||
|
||||
---
|
||||
|
||||
## 🏬 Gestão de Identidade e Lojas
|
||||
|
||||
### 1. Listar Lojas do Usuário
|
||||
**GET** `/api/store/list` - Retorna todas as lojas vinculadas ao token do usuário.
|
||||
|
||||
### 2. Informações Completas da Loja (Settings)
|
||||
**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,
|
||||
"result": {
|
||||
"isOpen": true,
|
||||
"statusLabel": "Aberto Agora",
|
||||
"isManualOpen": true,
|
||||
"fantasyName": "Pizzaria do Arantes",
|
||||
"razaoSocial": "Loverde Co LTDA",
|
||||
"document": "12.345.678/0001-99",
|
||||
"documentType": "CNPJ",
|
||||
"email": "loja@loverde.com.br",
|
||||
"phone": "11988776655",
|
||||
"paymentMethods": {
|
||||
"paymentOnDelivery": true,
|
||||
"acceptCash": true,
|
||||
"acceptCreditVisa": true,
|
||||
"acceptCreditMaster": true,
|
||||
"acceptCreditElo": true,
|
||||
"acceptVoucherAlelo": true,
|
||||
"acceptPix": true
|
||||
},
|
||||
"bankInfo": {
|
||||
"bankName": "Banco do Brasil",
|
||||
"accountType": "Corrente",
|
||||
"agency": "1234",
|
||||
"account": "56789-0",
|
||||
"pixKey": "12345678000199"
|
||||
},
|
||||
"openingHours": {
|
||||
"monday": [{"open": "18:00", "close": "23:00"}],
|
||||
"friday": [{"open": "11:00", "close": "15:00"}, {"open": "18:00", "close": "00:00"}]
|
||||
},
|
||||
"address": {
|
||||
"street": "Av. Brasil, 1000",
|
||||
"latitude": -23.55052,
|
||||
"longitude": -46.633308
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Dashboard Real-time (Portal Parity)
|
||||
|
||||
### 3. Dashboard e Monitoramento
|
||||
**GET** `/api/store/:storeId/dashboard`
|
||||
|
||||
**Resposta Detalhada (100% Parity):**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": false,
|
||||
"result": {
|
||||
"orderFlow": {
|
||||
"urgencys": [ { "id": "ORD-123", "clientName": "Daniel", "minutes": 45, "status": "PREPARING" } ],
|
||||
"received": [ /* Pedidos Pendentes */ ],
|
||||
"inProgress": [ /* Pedidos Em Preparo */ ],
|
||||
"readyTo": [ /* Pedidos Prontos para Entrega/Retirada */ ],
|
||||
"inRoute": [ /* Pedidos em Rota */ ],
|
||||
"delivered": [ /* Pedidos Finalizados na Sessão */ ]
|
||||
},
|
||||
"payments": {
|
||||
"totalSelledToday": 2450.00,
|
||||
"growthToday": 15.5,
|
||||
"avgTicket": 65.20,
|
||||
"growthPeriod": 8.5
|
||||
},
|
||||
"alerts": {
|
||||
"pendingOver3Minutes": 2,
|
||||
"delayedInProgress": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🍴 Catálogo e Menu (Complex Payloads)
|
||||
|
||||
### 4. Categorias de Pizza
|
||||
**POST** `/api/store/:storeId/catalog/categories`
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Pizzas Salgadas",
|
||||
"isPizzaCategory": true,
|
||||
"pizzaConfig": {
|
||||
"sizes": [
|
||||
{ "id": "small", "name": "Broto", "slices": 4, "maxFlavors": 1 },
|
||||
{ "id": "large", "name": "Grande", "slices": 8, "maxFlavors": 3 }
|
||||
],
|
||||
"doughs": [ { "id": "tradicional", "name": "Tradicional", "price": 0 } ],
|
||||
"crusts": [ { "id": "catupiry", "name": "Borda de Catupiry", "price": 10.00 } ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Produtos Tipo Combo ou Pizza
|
||||
**POST** `/api/store/:storeId/catalog/products`
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "pizza",
|
||||
"name": "Pizza de Calabresa",
|
||||
"categoryId": "cat_pizzas",
|
||||
"pizzaPrices": {
|
||||
"small": "35.00",
|
||||
"large": "55.00"
|
||||
},
|
||||
"addonGroups": [
|
||||
{
|
||||
"name": "Remover Ingredientes",
|
||||
"minSelectors": 0, "maxSelectors": 5,
|
||||
"items": [ { "name": "Sem Cebola", "price": 0 } ]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Histórico e Detalhes do Pedido
|
||||
|
||||
### 6. 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",
|
||||
"shortId": "1234",
|
||||
"clientName": "Arantes Loverde",
|
||||
"totalValue": 120.50,
|
||||
"netValue": 112.40,
|
||||
"pediFoodsFee": 1.00,
|
||||
"status": "COMPLETED",
|
||||
"createdAt": "2024-01-08T15:00:00Z",
|
||||
"confirmOtp": "12345678",
|
||||
"deliveryEstimate": "35-50 min",
|
||||
"deliveryTypeLabel": "Entrega Própria",
|
||||
"timeline": [
|
||||
{ "status": "PENDING", "time": "15:00:00", "message": "Pedido criado" },
|
||||
{ "status": "ACCEPTED", "time": "15:02:00", "message": "Chef aceitou o pedido" },
|
||||
{ "status": "COMPLETED", "time": "15:45:00", "message": "Entregue ao cliente" }
|
||||
],
|
||||
"items": [
|
||||
{ "name": "Pizza Grande", "price": 55.00, "choices": ["Borda Catupiry", "Meio Calabresa", "Meio Mussarela"] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 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
|
||||
**GET** `/api/store/:storeId/orders/:orderId`
|
||||
|
||||
Retorna o objeto completo do pedido (parity 100% com o painel).
|
||||
|
||||
---
|
||||
|
||||
## 💰 Financeiro Detalhado
|
||||
|
||||
### 7. Resumo de Performance e Gateway
|
||||
**GET** `/api/store/:storeId/financial/summary`
|
||||
|
||||
**Resposta:**
|
||||
```json
|
||||
{
|
||||
"error": false,
|
||||
"result": {
|
||||
"performance": {
|
||||
"totalSelledAllTime": 150230.50,
|
||||
"avgTicket": 72.00
|
||||
},
|
||||
"gateway": {
|
||||
"balance": { "balance": 1500.00, "available": 1200.00 },
|
||||
"transfers": [
|
||||
{ "id": "TRANS-1", "date": "2024-01-05", "value": 500.00, "status": "DONE" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ⭐ Reviews e Avaliações
|
||||
|
||||
### 8. Métricas e Respostas
|
||||
**GET** `/api/store/:storeId/reviews`
|
||||
|
||||
**Resposta:**
|
||||
```json
|
||||
{
|
||||
"error": false,
|
||||
"result": {
|
||||
"metrics": {
|
||||
"averageRate": "4.1",
|
||||
"totalReviews": 260,
|
||||
"starsDistribution": { "5": 121, "4": 60, "3": 23, "2": 15, "1": 39 },
|
||||
"itemFeedback": {
|
||||
"flavor": 207,
|
||||
"ingredients": 94,
|
||||
"packaging": 35,
|
||||
"temperature": 29,
|
||||
"appearance": 23
|
||||
},
|
||||
"improvementFeedback": {
|
||||
"quantity": 128,
|
||||
"temperature": 89,
|
||||
"packaging": 42,
|
||||
"ingredients": 23,
|
||||
"flavor": 13
|
||||
},
|
||||
"deliveryFeedback": {
|
||||
"positive": 102,
|
||||
"negative": 60
|
||||
}
|
||||
},
|
||||
"list": [
|
||||
{
|
||||
"id": "rev_1",
|
||||
"clientName": "Ana",
|
||||
"rate": 5,
|
||||
"message": "Melhor pizza!",
|
||||
"reply": "Obrigado Ana!",
|
||||
"repliedAt": "2024-01-08T16:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 9. Contestar Avaliação
|
||||
**POST** `/api/store/:storeId/reviews/:reviewId/dispute`
|
||||
```json
|
||||
{ "reason": "Cliente agressivo e mensagem falsa sobre o produto." }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🖼️ Upload de Ativos e Galeria
|
||||
**POST** `/api/store/:storeId/assets/upload` (Form-data: `file`) -> Retorna URL absoluta.
|
||||
|
||||
**GET** `/api/store/:storeId/assets` -> Retorna lista de URLs absolutas de todas as imagens da loja (logo, capa e produtos).
|
||||
|
||||
---
|
||||
|
||||
## 🏷️ Reordenação de Catálogo
|
||||
**POST** `/api/store/:storeId/catalog/products/reorder` (Payload: `{ "ids": ["p1", "p2", ...] }`)
|
||||
**POST** `/api/store/:storeId/catalog/categories/reorder` (Payload: `{ "ids": ["c1", "c2", ...] }`)
|
||||
|
||||
---
|
||||
|
||||
## 🛵 Fluxo de Entrega Pedi Foods (2-Step OTP)
|
||||
|
||||
| Campo | Tipo | Descrição |
|
||||
|---|---|---|
|
||||
| `otp` | String | Legacy OTP (4 digits). |
|
||||
| `confirmOtp` | String | **Novo:** Código de 8 dígitos para o motoboy. (Use este para o fluxo de 2 etapas) |
|
||||
| `deliveryEstimate` | String | Tempo estimado de entrega (ex: "30-45 min"). |
|
||||
| `pediFoodsFee` | Number | Taxa de serviço Pedi Foods calculada. |
|
||||
|
||||
## 8. Entrega e Confirmação (Motoboy Flow)
|
||||
|
||||
Novos endpoints públicos para confirmação de entrega em duas etapas.
|
||||
|
||||
### 8.1. Página de Confirmação
|
||||
`GET /delivery/confirm/:orderId`
|
||||
Renderiza a página para o motoboy iniciar o processo.
|
||||
|
||||
### 8.2. Validar Motoboy (Passo 1)
|
||||
`POST /delivery/confirm/:orderId/validate-motoboy`
|
||||
Valida o código de 8 dígitos (`confirmOtp`).
|
||||
|
||||
**Payload:**
|
||||
```json
|
||||
{ "otp": "12345678" }
|
||||
```
|
||||
|
||||
### 8.3. Validar Cliente (Passo 2)
|
||||
`POST /delivery/confirm/:orderId/validate-customer`
|
||||
Valida o código de 4 dígitos (`customerOtp`) e finaliza o pedido (`COMPLETED`).
|
||||
|
||||
**Payload:**
|
||||
```json
|
||||
{ "otp": "1234" }
|
||||
```
|
||||
Para garantir a segurança da entrega, o sistema utiliza um fluxo de confirmação em duas etapas via página pública:
|
||||
|
||||
1. **URL de Confirmação**: `https://atomenta.loverde.com.br/delivery/confirm/:orderRealId`
|
||||
2. **Passo 1 (Motoboy)**: O entregador insere o `confirmOtp` (8 dígitos) visível no painel da loja.
|
||||
3. **Passo 2 (Cliente)**: Após validar o código do motoboy, o sistema solicita o `customerOtp` (4 dígitos) que o cliente possui em seu app/notificação.
|
||||
4. **Finalização**: A validação bem-sucedida do segundo código altera o status do pedido para `COMPLETED` automaticamente.
|
||||
|
||||
Endpoints utilizados pela página pública (CORS habilitado para domínios parceiros):
|
||||
- `POST /delivery/confirm/:orderId/validate-motoboy` { "otp": "String(8)" }
|
||||
- `POST /delivery/confirm/:orderId/validate-customer` { "otp": "String(4)" }
|
||||
|
||||
---
|
||||
|
||||
## 🛒 Checkout e Criação de Pedido
|
||||
### 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",
|
||||
"userId": "user_guid_or_guest",
|
||||
"clientName": "João Silva",
|
||||
"clientPhone": "11999999999",
|
||||
"deliveryType": "DELIVERY", // ou "PICKUP"
|
||||
"address": {
|
||||
"street": "Rua das Flores",
|
||||
"number": "123",
|
||||
"neighborhood": "Centro",
|
||||
"city": "São Paulo",
|
||||
"state": "SP",
|
||||
"zip": "01000-000",
|
||||
"complement": "Apt 10",
|
||||
"lat": -23.55,
|
||||
"lng": -46.63
|
||||
},
|
||||
"paymentMethod": "PIX", // "CREDIT_CARD", "DEBIT_CARD", "CASH"
|
||||
"itemsTotal": 50.00,
|
||||
"deliveryFee": 5.00,
|
||||
"serviceFee": 0.00,
|
||||
"discount": 0.00,
|
||||
"total": 55.00,
|
||||
"items": [
|
||||
{
|
||||
"id": "prod_1",
|
||||
"name": "Pizza",
|
||||
"price": 50.00,
|
||||
"qty": 1,
|
||||
"image": "..."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Resposta Sucesso:**
|
||||
|
||||
```json
|
||||
{
|
||||
"error": false,
|
||||
"result": {
|
||||
"id": "order_guid",
|
||||
"shortId": "1234",
|
||||
"status": "PENDING",
|
||||
"paymentStatus": "PENDING",
|
||||
"paymentPayload": "..." // Se PIX (Big String Base64 ou Copia e Cola)
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user