Mirror all SPECs and construction docs from pizza-digital, add hub/sidebar links and bidirectional sync scripts.
135 lines
3.3 KiB
Markdown
135 lines
3.3 KiB
Markdown
# API de entrada — WhatsApp
|
||
|
||
| Campo | Valor |
|
||
|-------|--------|
|
||
| Versão | 0.1 |
|
||
| Data | 2026-10-19 |
|
||
| Origin no pedido | `whatsapp` |
|
||
| Badge na Central | **WHATSAPP** |
|
||
|
||
Primeira API de canal digital: qualquer bot / n8n / Make / Evolution API envia JSON autenticado e o pedido cai em `/pedidos` com a mesma fila do PDV.
|
||
|
||
---
|
||
|
||
## 1. Auth
|
||
|
||
Header obrigatório:
|
||
|
||
```http
|
||
X-Api-Key: <INBOUND_API_KEY>
|
||
```
|
||
|
||
(ou `Authorization: Bearer <INBOUND_API_KEY>`)
|
||
|
||
Variável no servidor: `INBOUND_API_KEY` (ver `.env.example`).
|
||
|
||
---
|
||
|
||
## 2. Criar pedido (recomendado)
|
||
|
||
```http
|
||
POST /api/inbound/whatsapp
|
||
Content-Type: application/json
|
||
X-Api-Key: pizza-inbound-805353
|
||
```
|
||
|
||
```json
|
||
{
|
||
"storeSlug": "pizza-digital-piloto",
|
||
"externalId": "wamid.HBgLNTU0Nzk5ODg3NzY2FQIAEhggEXAMPLE",
|
||
"customerName": "Ana Silva Santos",
|
||
"customerPhone": "5547999887766",
|
||
"fulfillment": "entrega",
|
||
"bairro": "Centro",
|
||
"address": "Rua das Palmeiras, 120",
|
||
"notes": "sem cebola",
|
||
"items": [
|
||
{ "name": "Calabresa", "quantity": 1, "sizeCode": "grande" },
|
||
{ "name": "Coca-Cola 2L", "quantity": 1 }
|
||
]
|
||
}
|
||
```
|
||
|
||
| Campo | Obrigatório | Notas |
|
||
|-------|-------------|--------|
|
||
| `storeSlug` | sim | slug da loja |
|
||
| `externalId` | recomendado | idempotência (`wa:<id>`) — reenvio não duplica |
|
||
| `customerName` | sim | nome completo |
|
||
| `customerPhone` | sim | WhatsApp do cliente |
|
||
| `fulfillment` | não | `entrega` (default) · `retirada` · `mesa` |
|
||
| `bairro` / `address` | entrega | ao menos um |
|
||
| `items[].menuItemId` | um dos dois | id do menu |
|
||
| `items[].name` | um dos dois | match fuzzy no cardápio |
|
||
| `items[].sizeCode` | não | `broto`…`familia` (preço × fator) |
|
||
|
||
Resposta: mesmo payload de `POST /api/orders` (code, items, origin=`whatsapp`).
|
||
|
||
---
|
||
|
||
## 3. Webhook Meta Cloud API (opcional)
|
||
|
||
| Método | Rota | Uso |
|
||
|--------|------|-----|
|
||
| `GET` | `/api/inbound/whatsapp/meta` | Verificação (`WHATSAPP_VERIFY_TOKEN`) |
|
||
| `POST` | `/api/inbound/whatsapp/meta` | Eventos de mensagem |
|
||
|
||
Configure no Meta:
|
||
- Callback URL: `https://<host>/api/inbound/whatsapp/meta`
|
||
- Verify token: valor de `WHATSAPP_VERIFY_TOKEN`
|
||
- Loja default: `WHATSAPP_STORE_SLUG`
|
||
|
||
### Formato de texto aceito no chat
|
||
|
||
```text
|
||
PEDIDO
|
||
Nome: Ana Silva
|
||
Telefone: 47999887766
|
||
Entrega
|
||
Bairro: Centro
|
||
Endereço: Rua das Palmeiras, 120
|
||
1x Calabresa
|
||
1x Coca-Cola 2L
|
||
Obs: sem cebola
|
||
```
|
||
|
||
Mensagens que não começam com `PEDIDO` / `#PEDIDO` são ignoradas (200 OK, sem criar pedido).
|
||
|
||
---
|
||
|
||
## 4. Fluxo típico com n8n
|
||
|
||
```text
|
||
WhatsApp (Evolution / Meta)
|
||
→ n8n parseia intenção / menu
|
||
→ POST /api/inbound/whatsapp (JSON estruturado)
|
||
→ Central /pedidos (badge WHATSAPP + som)
|
||
→ KDS
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Smoke test
|
||
|
||
```bash
|
||
curl -sS -X POST https://pizza.myvexx.com/api/inbound/whatsapp \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-Api-Key: pizza-inbound-805353" \
|
||
-d '{
|
||
"storeSlug":"pizza-digital-piloto",
|
||
"externalId":"test-wa-001",
|
||
"customerName":"Ana Silva Santos",
|
||
"customerPhone":"47999887766",
|
||
"fulfillment":"entrega",
|
||
"bairro":"Centro",
|
||
"address":"Rua Teste, 1",
|
||
"items":[{"name":"Calabresa","quantity":1,"sizeCode":"grande"}]
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Próximos passos
|
||
|
||
- Validar `X-Hub-Signature-256` do Meta
|
||
- Resposta automática ao cliente (pedido #code + tracking)
|
||
- Catálogo rápido via botões WhatsApp (interactive messages)
|