Pontos finais CRM
Conecte o WAzion ao seu CRM ou ERP externo para que a IA e o painel lateral acessem dados de clientes, pedidos e produtos do seu sistema.
O que são os Endpoints CRM?
Os Endpoints CRM permitem que a WAzion consulte informações do seu sistema externo (CRM, ERP, base de dados própria). Ao contrário das Funções IA (que a IA decide quando chamar), esses endpoints são chamados automaticamente quando o agente abre uma conversa ou busca informações.
Para o Painel Lateral
Mostra dados do cliente junto à conversa (pedidos, histórico, informações de contato).
Para a IA
Fornece contexto inicial sobre o cliente para que a IA responda com informações relevantes.
1 sidePanel_CustomerInfo
Fornece informações do cliente que são exibidas no painel lateral da extensão quando o agente abre uma conversa.
Parâmetros enviados
| phone | Telefone do cliente (E.164) |
| token | Token de autenticação |
| relatedphones | Telefones relacionados (array) |
Resposta esperada
{
"found": true,
"customers": [
{
"name": "Juan García",
"email": "juan@email.com",
"phone": "+34612345678",
"shopUrl": "https://tucrm.com/c/123",
"ordersCount": 5,
"totalSpent": 450.00,
"totalRefunded": 0,
"state": "VIP - Activo",
"orders": [...],
"abandonedCarts": [...]
}
]
}
Nota: Você pode usar “customer“ (objeto) ou “customers“ (array) para suportar múltiplos clientes. SEMPRE retorna HTTP 200, mesmo que não encontre o cliente (use “found“: false).
📦 Ver estrutura completa da resposta (pedidos, itens, rastreamento, carrinhos abandonados)
Estrutura JSON completa com todos os campos suportados:
{
"found": true,
"customers": [
{
"// Datos básicos del cliente"
"name": "Juan García López",
"email": "juan@email.com",
"phone": "+34612345678",
"shopUrl": "https://tu-crm.com/clientes/123",
"ordersCount": 15,
"totalSpent": 1250.50,
"totalRefunded": 50.00,
"totalDiscounts": 25.00,
"state": "Cliente VIP",
"// Array de pedidos"
"orders": [
{
"name": "#ORD-2025-001",
"date": "2025-01-10T14:30:00Z",
"amount": 129.99,
"netAmount": 104.99,
"totalRefunded": 25.00,
"totalDiscounts": 10.00,
"currency": "EUR",
"cancelled": false,
"shopUrl": "https://tu-crm.com/pedidos/1234",
"note": "Entregar por la tarde",
"// Items del pedido"
"items": [
{
"title": "Camiseta Premium Azul - Talla L",
"quantity": 2,
"currentQuantity": 2,
"amount": 59.98,
"originalAmount": 59.98,
"discountedAmount": 59.98,
"discount": 0,
"refundedQuantity": 0,
"refundedAmount": 0,
"status": "active" // active | partially_refunded | fully_refunded
}
],
"// Tracking de envíos"
"tracking": [
{
"number": "ES123456789012",
"company": "SEUR",
"url": "https://www.seur.com/tracking/...",
"displayStatus": "Entregado"
}
]
}
],
"// Carritos abandonados"
"abandonedCarts": [
{
"date": "2025-01-14T18:45:00Z",
"url": "https://tu-tienda.com/cart/recover/abc123",
"items": [
{
"title": "Zapatillas Running Pro",
"quantity": 1,
"amount": 129.99
}
]
}
]
}
]
}
Campos do cliente:
| Campo | Tipo | Obrigatório |
|---|---|---|
| name | string | Sim |
| string | Sim | |
| phone | string | Sim |
| shopUrl | string | No |
| ordersCount | number | Sim |
| totalSpent | number | Sim |
| totalRefunded | number | No |
| totalDiscounts | number | No |
| state | string | Sim |
| orders | array | No |
| abandonedCarts | array | No |
Campos do pedido (order):
| Campo | Tipo | Descrição |
|---|---|---|
| name | string | ID/Número do pedido |
| date | string | Data ISO 8601 |
| amount | number | Total do pedido |
| netAmount | number | Valor líquido (após reembolsos) |
| currency | string | Código da moeda (EUR, USD...) |
| cancelled | boolean | true se está cancelado |
| shopUrl | string | URL do pedido no seu sistema |
| note | string | Nota do pedido |
| items | array | Produtos do pedido |
| tracking | array | Envios/rastreamento |
Campos do item:
| Campo | Tipo | Descrição |
|---|---|---|
| title | string | Nome do produto |
| quantity | number | Quantidade solicitada |
| currentQuantity | number | Quantidade atual (após reembolsos) |
| amount | number | Preço total do item |
| refundedQuantity | number | Unidades reembolsadas |
| refundedAmount | number | Valor reembolsado |
| status | string | active | partially_refunded | fully_refunded |
Campos do tracking:
| Campo | Tipo | Descrição |
|---|---|---|
| number | string | Número de rastreamento |
| company | string | Empresa de envio |
| url | string | URL de rastreamento |
| displayStatus | string | Estado legível (Entregue, Em trânsito...) |
Rótulos de tradução (UI)
Para que a extensão mostre os textos no idioma correto, inclua o objeto “labels“ com as traduções:
{
"found": true,
"customer": { ... },
"labels": {
"label_languages": "es",
"customer_info": "Información del Cliente",
"name": "Nombre",
"email": "Email",
...
}
}
Ver tabela completa de etiquetas disponíveis
| Key | Default (ES) | Descrição |
|---|---|---|
| label_languages | "es" | Idioma das etiquetas. Se for diferente do idioma da loja, a WAzion as traduz automaticamente |
| customer_info | "Información del Cliente" | Título seção cliente |
| name | "Nombre" | Etiqueta nome |
| "Email" | Etiqueta email | |
| phone | "Teléfono" | Etiqueta telefone |
| orders_count | "Pedidos" | Contador de pedidos |
| total_spent | "Total gastado" | Total gasto |
| total_refunded | "Total reembolsado" | Reembolsos |
| discounts | "Descuentos" | Descontos |
| customer_state | "Estado" | Estado do cliente |
| recent_orders | "Pedidos recientes" | Título pedidos |
| order | "Pedido" | Pedido individual |
| orders | "Pedidos" | Pedidos |
| order_number | "Nº de pedido" | Número do pedido |
| date | "Fecha" | Data |
| amount | "Importe" | Importe |
| net_amount | "Importe neto" | Importe líquido |
| subtotal | "Subtotal" | Subtotal |
| discount | "Descuento" | Desconto individual |
| refund | "Reembolso" | Reembolso |
| refunded | "Reembolsado" | Crachá reembolsado |
| cancelled | "Cancelado" | Crachá cancelado |
| cancel_reason | "Motivo cancelación" | Motivo de cancelamento |
| items | "Artículos" | Produtos/Artigos |
| item_status | "Estado artículo" | Estado do artigo |
| quantity | "Cantidad" | Quantidade |
| original_quantity | "Cantidad original" | Quantidade original |
| current_quantity | "Cantidad actual" | Quantidade atual |
| sku | "SKU" | SKU |
| shipments | "Envíos" | Envios |
| shipping | "Envío" | Envio individual |
| tracking_number | "Nº seguimiento" | Número de rastreamento |
| no_shipping_info | "Sin información de envío" | Sem envio |
| order_note | "Nota del pedido" | Notas do pedido |
| fully_refunded | "Reembolsado completamente" | Item 100% reembolsado |
| partially_refunded | "Reembolsado parcialmente" | Item parcialmente reembolsado |
| active | "Activo" | Estado ativo |
| abandoned_carts | "Carrito/s abandonado/s" | Carrinhos abandonados |
| copy_link | "Copiar enlace" | Botão copiar |
| view_customer | "Ver perfil del cliente" | Botão ver cliente |
| view_profile | "Ver perfil" | Botão ver perfil |
| remove_assignment | "Quitar asignación" | Botão desvincular |
| not_found | "Cliente no encontrado" | Mensagem não encontrada |
| no_orders | "Sin pedidos" | Sem pedidos |
| error | "Error" | Prefixo de erro |
| Estados do cliente | ||
| state_no_orders | "Sin pedidos" | Estado: sem pedidos |
| state_conflictive | "Conflictivo" | Estado: conflituoso |
| state_processing | "Procesando" | Estado: processando |
| state_new_orders | "Pedidos nuevos" | Estado: pedidos novos |
| state_recent_orders | "Pedidos recientes" | Estado: pedidos recentes |
| state_old_orders | "Pedidos antiguos" | Estado: pedidos antigos |
Tradução automática: Se você enviar labels em um idioma (ex: inglês com label_languages: “en“) e a loja estiver configurada em outro (ex: espanhol), o WAzion traduzirá automaticamente todos os labels. Isso permite que você mantenha seu CRM em um único idioma.
2 ai_CustomerInitialInfo
Fornece contexto inicial sobre o cliente à IA. Este texto é incluído no prompt da IA para que ela possa responder com informações relevantes sobre o cliente.
Parâmetros enviados
| phone | Telefone do cliente (E.164) |
| token | Token de autenticação |
| relatedphones | Telefones relacionados (array) |
| order | Número do pedido mencionado (opcional) |
| Email do cliente (opcional) | |
| test | true“ se for teste |
Resposta esperada
{
"found": true,
"info": "Cliente: Juan García.
VIP: Sí. Total pedidos: 5.
Último pedido: #12345 (15/01/2024)
Estado: Entregado.
Productos frecuentes: Zapatos, Camisetas.
ALERTA: Cliente alérgico al gluten."
}
Importante: O campo “info“ é texto livre que a IA lerá como contexto. Inclui histórico de compras, preferências, alertas importantes (alergias, problemas prévios), estado do cliente, método de pagamento/entrega preferido, etc.
3 sidePanel_CustomerFindToJoin
Permite buscar clientes no seu sistema para vinculá-los a uma conversa no WhatsApp. Útil quando o cliente escreve de um número diferente do registrado.
Parâmetros enviados
| query | Texto de busca |
| token | Token de autenticação |
| phone | Telefone atual da conversa |
| relatedphones | Telefones já relacionados (array, para excluí-los) |
Resposta esperada
{
"customers": [
{
"id": "cust_123",
"name": "Juan García",
"email": "juan@email.com",
"phone": "+34612345678"
},
{
"id": "cust_456",
"name": "Juan Martínez",
"email": "juanm@email.com",
"phone": "+34687654321"
}
]
}
Nota: Puedes usar “customers“ o “results“ como nome do array. O campo “phone“ de cada cliente permite à WAzion vincular automaticamente a conversa.
4 search_Products
Permite buscar produtos no seu catálogo externo. Os resultados são exibidos no painel lateral e o agente pode compartilhá-los com o cliente. A IA também pode buscar produtos para responder perguntas.
Nota para CRM Custom: WAzion atua como proxy transparente para este endpoint. A resposta do seu CRM é devolvida diretamente para a extensão sem alterações. Você deve implementar a estrutura completa documentada se quiser aproveitar todas as funcionalidades. Os campos enriquecidos (target_locale, title_copy, raw, etc.) são gerados automaticamente apenas para lojas Shopify.
Parâmetros enviados
| Parâmetro | Tipo | Descrição |
|---|---|---|
| q | string | Texto de busca (mínimo 2 caracteres) |
| token | string | Token de autenticação da loja |
| phone | string | Telefone do cliente (E.164) - para URLs localizadas por país |
| format | string | ai“ quando a IA busca produtos (muda a estrutura da resposta) |
| target_locale | string | Idioma detectado do cliente com base no seu telefone (ex: “es“, “de“, “fr“) |
| test | boolean | true“ se for teste de conexão |
Novo: target_locale - WAzion detecta automaticamente o idioma do cliente com base no prefixo do seu telefone. Por exemplo, +34... → “es“, +49... → “de“. Use este parâmetro para devolver produtos no idioma correto.
Resposta formato NORMAL (painel lateral)
Quando o agente busca produtos pelo painel. Inclui campos para copiar/compartilhar.
{
"http_status": 200,
"count": 1,
"products": [
{
"title": "Camiseta Premium",
"title_copy": "Premium T-Shirt",
"handle": "camiseta-premium",
"description": "Descripción truncada a 500 chars...",
"sku": "CAM-001",
"image": "https://proxy/imagen.jpg",
"url": "https://tutienda.es/products/camiseta-premium",
"variants": [
{
"id": "12345678",
"title": "M / Rojo",
"title_copy": "M / Red",
"has_custom_title": true,
"sku": "CAM-001-M-RED",
"image": "https://proxy/variante.jpg",
"url": "https://tutienda.es/products/camiseta-premium?variant=12345678"
}
]
}
],
"target_locale": "en",
"raw": { ... }
}
Resposta formato IA (quando format=“ai“)
Quando a IA busca produtos. Estrutura simplificada sem campos de cópia, descrição completa.
{
"count": 1,
"products": [
{
"title": "Premium T-Shirt",
"handle": "camiseta-premium",
"description": "Descripción COMPLETA sin truncar para contexto IA...",
"sku": "CAM-001",
"url": "https://tutienda.es/products/camiseta-premium",
"variants": [
{
"id": "12345678",
"title": "M / Red",
"sku": "CAM-001-M-RED",
"url": "https://tutienda.es/products/camiseta-premium?variant=12345678"
}
]
}
],
"locale": "en"
}
Ver todos os campos do produto
| Campo | Normal | IA | Descrição |
|---|---|---|---|
| title | Original | Traduzido | Título do produto |
| title_copy | Traduzido | - | Título para copiar (idioma do cliente) |
| handle | ✓ | ✓ | Slug do produto |
| description | 500 caracteres | Completa | Descrição (HTML limpo) |
| sku | ✓ | ✓ | SKU da primeira variante |
| image | ✓ | - | URL da imagem (pode ser proxy) |
| url | ✓ | ✓ | URL localizada do produto |
| variants | ✓ | ✓ | Array de variantes |
Ver campos de cada variante
| Campo | Normal | IA | Descrição |
|---|---|---|---|
| id | ✓ | ✓ | ID da variante |
| title | Original | Traduzido | Título da variante (ex: “M / Vermelho“) |
| title_copy | Traduzido | - | Título para copiar (idioma do cliente) |
| has_custom_title | ✓ | - | true se tiver título personalizado (não “Default Title“) |
| sku | ✓ | ✓ | SKU da variante |
| image | ✓ | - | Imagem específica da variante (ou do produto, se não tiver) |
| url | ✓ | ✓ | URL com ?variant=ID |
Ver campos da resposta raiz
| Campo | Normal | IA | Descrição |
|---|---|---|---|
| http_status | ✓ | - | Código HTTP da resposta |
| count | ✓ | ✓ | Número de produtos encontrados |
| products | ✓ | ✓ | Array de produtos |
| target_locale | ✓ | - | Locale usado para traduções |
| locale | - | ✓ | Locale usado (somente formato AI) |
| raw | ✓ | - | Resposta bruta da fonte (debug) |
🌍 URLs localizadas por país
O parâmetro phone contém o telefone do cliente (E.164). Use-o para detectar seu país e retornar URLs adaptadas:
- Domínios específicos por país (tutienda.es, tutienda.de, tutienda.fr)
- Rotas com prefixo de idioma (/es/, /de/, /fr/)
- Parâmetros de localidade (?locale=es_ES)
- Mercados específicos de Shopify
Exemplo: Se o telefone começa por +34 (Espanha), devolver URLs com domínio .es ou /es/.
5 globalSearch
Busca global de clientes para o buscador flutuante da extensão. Permite buscar por nome, email, telefone ou número do pedido.
Parâmetros enviados
| Parâmetro | Tipo | Descrição |
|---|---|---|
| query | string | Texto de busca (mínimo 2 caracteres) |
| token | string | Token de autenticação da loja |
Resposta esperada
{
"found": true,
"customers": [
{
"id": "cust_123",
"name": "Juan García López",
"email": "juan.garcia@email.com",
"phone": "+34612345678",
"customerUrl": "https://tucrm.com/clientes/123",
"orders": [
{
"number": "#ORD-1234",
"url": "https://tucrm.com/pedidos/1234"
},
{
"number": "#ORD-1233",
"url": "https://tucrm.com/pedidos/1233"
}
]
}
]
}
Campos de cada cliente
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| id | string | Sim | ID único do cliente no seu sistema |
| name | string | Sim | Nome completo do cliente |
| string | Sim | Email do cliente | |
| phone | string | Sim | Telefone do cliente (E.164 preferido, ex: +34612345678) |
| customerUrl | string | Não | URL para ver o cliente no seu CRM (é exibido como link clicável) |
| orders | array | Não | Array com os últimos pedidos (máximo 3) |
Campos de cada pedido (orders[])
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| number | string | Sim | Número do pedido (ex: “#ORD-1234“) |
| url | string | Não | URL para ver o pedido no seu sistema |
Notas importantes
- • O campo
phoneé obrigatório para que o agente possa abrir a conversa com esse cliente. - • No máximo 15 resultados serão mostrados ao usuário (limitado automaticamente).
- • Os duplicados por telefone são eliminados automaticamente.
- • Se
customerUrlestiver presente, o nome do cliente será um link clicável. - • Os pedidos são exibidos como links individuais abaixo do cliente.
Especificações Técnicas
Tempos limite
| globalSearch | 5s |
| Outros endpoints | 10s |
| Tempo limite de conexão | 5s |
| Repetições | Não |
Métodos HTTP
| Configurável | GET / POST |
| Corpo (POST) | JSON / Form |
| Parâmetros (GET) | Query string |
Requisitos
- HTTPS obrigatório
- Resposta JSON válida
- HTTP 200 sempre (usar found:false se não houver dados)
Diferença com Funções IA
Os Endpoints CRM NÃO tentam novamente automaticamente se falharem. São chamados em tempo real enquanto o agente trabalha, então devem responder rapidamente. Se falhar, a informação simplesmente não aparece.
Tipos de Autenticação
Exemplo de URL (GET + autenticação por query)
// WAzion llamará:
https://tu-api.com/customer
?phone=+34612345678
&token=tu-token-secreto
&relatedphones=["+34698765432"]
&test=false
Exemplos de Implementação
<?php
// Endpoint: /api/customer-info
header('Content-Type: application/json');
// Obtener parámetros (soporta GET y POST)
$input = json_decode(file_get_contents('php://input'), true) ?? $_GET;
$phone = $input['phone'] ?? '';
$token = $input['token'] ?? '';
$relatedPhones = $input['relatedphones'] ?? [];
$order = $input['order'] ?? '';
$isTest = ($input['test'] ?? '') === 'true';
// Verificar token
if ($token !== 'tu-token-secreto') {
echo json_encode(['found' => false, 'error' => 'No autorizado']);
exit;
}
// Si es test, devolver datos de ejemplo
if ($isTest) {
echo json_encode([
'found' => true,
'customers' => [[
'name' => 'Cliente de Prueba',
'email' => 'test@example.com',
'phone' => '+34612345678',
'shopUrl' => 'https://tucrm.com/cliente/123',
'ordersCount' => 3,
'totalSpent' => 150.00,
'state' => 'Activo',
'orders' => []
]]
]);
exit;
}
// Buscar por teléfono principal + relacionados
$allPhones = array_merge([$phone], $relatedPhones);
$customers = buscarClientesPorTelefonos($allPhones);
echo json_encode([
'found' => !empty($customers),
'customers' => $customers
]);
const express = require('express');
const app = express();
app.use(express.json());
const SECRET_TOKEN = 'tu-token-secreto';
app.all('/api/customer-info', async (req, res) => {
// Soporta GET y POST
const params = { ...req.query, ...req.body };
const { phone, token, relatedphones = [], order, test } = params;
// Verificar token
if (token !== SECRET_TOKEN) {
return res.json({ found: false, error: 'No autorizado' });
}
// Datos de test
if (test === 'true') {
return res.json({
found: true,
customers: [{
name: 'Cliente de Prueba',
email: 'test@example.com',
phone: '+34612345678',
shopUrl: 'https://tucrm.com/cliente/123',
ordersCount: 3,
totalSpent: 150.00,
state: 'Activo',
orders: []
}]
});
}
// Buscar clientes
const allPhones = [phone, ...relatedphones];
const customers = await buscarClientesPorTelefonos(allPhones);
res.json({ found: customers.length > 0, customers });
});
app.listen(3000);
from flask import Flask, request, jsonify
app = Flask(__name__)
SECRET_TOKEN = 'tu-token-secreto'
@app.route('/api/customer-info', methods=['GET', 'POST'])
def customer_info():
# Soporta GET y POST
params = {**request.args, **request.get_json(silent=True) or {}}
phone = params.get('phone', '')
token = params.get('token', '')
related_phones = params.get('relatedphones', [])
is_test = params.get('test') == 'true'
# Verificar token
if token != SECRET_TOKEN:
return jsonify({'found': False, 'error': 'No autorizado'})
# Datos de test
if is_test:
return jsonify({
'found': True,
'customers': [{
'name': 'Cliente de Prueba',
'email': 'test@example.com',
'phone': '+34612345678',
'shopUrl': 'https://tucrm.com/cliente/123',
'ordersCount': 3,
'totalSpent': 150.00,
'state': 'Activo',
'orders': []
}]
})
# Buscar clientes
all_phones = [phone] + related_phones
customers = buscar_clientes_por_telefonos(all_phones)
return jsonify({'found': len(customers) > 0, 'customers': customers})
Histórico de alterações
sidePanel_CustomerInfo agora traduz automaticamente todos os rótulos se label_languages for diferente do idioma da loja. Você pode manter seu CRM em um único idioma (ex: inglês) e o WAzion cuida das traduções.
WAzion agora envia o idioma detectado do cliente (baseado no prefixo do seu telefone) como parâmetro target_locale. Útil para devolver produtos no idioma correto do cliente.