Endpoint CRM
Collega WAzion con il tuo CRM o ERP esterno affinché l’IA e il pannello laterale possano accedere ai dati di clienti, ordini e prodotti del tuo sistema.
Cosa sono gli Endpoints CRM?
Gli Endpoint CRM permettono a WAzion di consultare informazioni dal tuo sistema esterno (CRM, ERP, database proprietario). A differenza delle Funzioni IA (che l’IA decide quando chiamare), questi endpoint vengono chiamati automaticamente quando l’agente apre una conversazione o cerca informazioni.
Per il Pannello Laterale
Mostra i dati del cliente accanto alla conversazione (ordini, cronologia, informazioni di contatto).
Per l’IA
Fornisci un contesto iniziale sul cliente affinché l’IA risponda con informazioni rilevanti.
1 sidePanel_CustomerInfo
Fornisce informazioni sul cliente che vengono visualizzate nel pannello laterale dell’estensione quando l’agente apre una conversazione.
Parametri inviati
| phone | Telefono del cliente (E.164) |
| token | Token di autenticazione |
| relatedphones | Telefoni correlati (array) |
Risposta attesa
{
"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: Puoi usare “customer“ (oggetto) o “customers“ (array) per supportare più clienti. RESTITUISCE SEMPRE HTTP 200, anche se non trovi il cliente (usa “found“: false).
📦 Vedi struttura completa della risposta (ordini, articoli, tracciamento, carrelli abbandonati)
Struttura JSON completa con tutti i campi supportati:
{
"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
}
]
}
]
}
]
}
Campi del cliente:
| Campo | Tipo | Richiesto |
|---|---|---|
| name | string | Sì |
| string | Sì | |
| phone | string | Sì |
| shopUrl | string | No |
| ordersCount | number | Sì |
| totalSpent | number | Sì |
| totalRefunded | number | No |
| totalDiscounts | number | No |
| state | string | Sì |
| orders | array | No |
| abandonedCarts | array | No |
Campi dell’ordine (order):
| Campo | Tipo | Descrizione |
|---|---|---|
| name | string | ID/Numero dell’ordine |
| date | string | Data ISO 8601 |
| amount | number | Totale dell’ordine |
| netAmount | number | Importo netto (dopo rimborsi) |
| currency | string | Codice valuta (EUR, USD...) |
| cancelled | boolean | vero se è cancellato |
| shopUrl | string | URL all’ordine nel tuo sistema |
| note | string | Nota dell’ordine |
| items | array | Prodotti dell’ordine |
| tracking | array | Spedizioni/tracciamento |
Campi dell’articolo:
| Campo | Tipo | Descrizione |
|---|---|---|
| title | string | Nome del prodotto |
| quantity | number | Quantità ordinata |
| currentQuantity | number | Quantità attuale (dopo rimborsi) |
| amount | number | Prezzo totale dell’articolo |
| refundedQuantity | number | Unità rimborsate |
| refundedAmount | number | Importo rimborsato |
| status | string | active | partially_refunded | fully_refunded |
Campi del tracciamento:
| Campo | Tipo | Descrizione |
|---|---|---|
| number | string | Numero di tracciamento |
| company | string | Impresa di spedizioni |
| url | string | URL di tracciamento |
| displayStatus | string | Stato leggibile (Consegnato, In transito...) |
Etichette di traduzione (UI)
Affinché l’estensione mostri i testi nella lingua corretta, includi l’oggetto “labels“ con le traduzioni:
{
"found": true,
"customer": { ... },
"labels": {
"label_languages": "es",
"customer_info": "Información del Cliente",
"name": "Nombre",
"email": "Email",
...
}
}
Vedi tabella completa delle etichette disponibili
| Key | Default (ES) | Descrizione |
|---|---|---|
| label_languages | "es" | Lingua delle etichette. Se diversa dalla lingua del negozio, WAzion le traduce automaticamente |
| customer_info | "Información del Cliente" | Titolo sezione cliente |
| name | "Nombre" | Etichetta nome |
| "Email" | Etichetta email | |
| phone | "Teléfono" | Etichetta telefono |
| orders_count | "Pedidos" | Contatore ordini |
| total_spent | "Total gastado" | Totale speso |
| total_refunded | "Total reembolsado" | Rimborsi |
| discounts | "Descuentos" | Sconti |
| customer_state | "Estado" | Stato del cliente |
| recent_orders | "Pedidos recientes" | Titolo ordini |
| order | "Pedido" | Ordine individuale |
| orders | "Pedidos" | Ordini |
| order_number | "Nº de pedido" | Numero d’ordine |
| date | "Fecha" | Data |
| amount | "Importe" | Importo |
| net_amount | "Importe neto" | Importo netto |
| subtotal | "Subtotal" | Totale parziale |
| discount | "Descuento" | Sconto individuale |
| refund | "Reembolso" | Rimborso |
| refunded | "Reembolsado" | Badge rimborsato |
| cancelled | "Cancelado" | Badge annullato |
| cancel_reason | "Motivo cancelación" | Motivo della cancellazione |
| items | "Artículos" | Prodotti/Articoli |
| item_status | "Estado artículo" | Stato dell’articolo |
| quantity | "Cantidad" | Quantità |
| original_quantity | "Cantidad original" | Quantità originale |
| current_quantity | "Cantidad actual" | Quantità attuale |
| sku | "SKU" | SKU |
| shipments | "Envíos" | Spedizioni |
| shipping | "Envío" | Spedizione individuale |
| tracking_number | "Nº seguimiento" | Numero di tracciamento |
| no_shipping_info | "Sin información de envío" | Senza spedizione |
| order_note | "Nota del pedido" | Note dell’ordine |
| fully_refunded | "Reembolsado completamente" | Voce 100% rimborsata |
| partially_refunded | "Reembolsado parcialmente" | Voce parzialmente rimborsata |
| active | "Activo" | Stato attivo |
| abandoned_carts | "Carrito/s abandonado/s" | Carrelli abbandonati |
| copy_link | "Copiar enlace" | Pulsante copia |
| view_customer | "Ver perfil del cliente" | Pulsante visualizza cliente |
| view_profile | "Ver perfil" | Pulsante vedi profilo |
| remove_assignment | "Quitar asignación" | Pulsante scollega |
| not_found | "Cliente no encontrado" | Messaggio non trovato |
| no_orders | "Sin pedidos" | Senza ordini |
| error | "Error" | Prefisso di errore |
| Stati del cliente | ||
| state_no_orders | "Sin pedidos" | Stato: nessun ordine |
| state_conflictive | "Conflictivo" | Stato: conflittuale |
| state_processing | "Procesando" | Stato: in elaborazione |
| state_new_orders | "Pedidos nuevos" | Stato: nuovi ordini |
| state_recent_orders | "Pedidos recientes" | Stato: ordini recenti |
| state_old_orders | "Pedidos antiguos" | Stato: ordini vecchi |
Traduzione automatica: Se invii etichette in una lingua (es: inglese con label_languages: “en“) e il negozio è configurato in un’altra (es: spagnolo), WAzion tradurrà automaticamente tutte le etichette. Questo ti permette di mantenere il tuo CRM in una sola lingua.
2 ai_CustomerInitialInfo
Fornisce un contesto iniziale sul cliente all’IA. Questo testo viene incluso nel prompt dell’IA affinché possa rispondere con informazioni rilevanti sul cliente.
Parametri inviati
| phone | Telefono del cliente (E.164) |
| token | Token di autenticazione |
| relatedphones | Telefoni correlati (array) |
| order | Numero d’ordine menzionato (opzionale) |
| Email del cliente (opzionale) | |
| test | vero se è una prova |
Risposta attesa
{
"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: Il campo “info“ è testo libero che l’IA leggerà come contesto. Include la cronologia degli acquisti, le preferenze, gli avvisi importanti (allergie, problemi precedenti), lo stato del cliente, il metodo di pagamento/spedizione preferito, ecc.
3 sidePanel_CustomerFindToJoin
Consente di cercare clienti nel tuo sistema per collegarli a una conversazione di WhatsApp. Utile quando il cliente scrive da un numero diverso da quello registrato.
Parametri inviati
| query | Testo di ricerca |
| token | Token di autenticazione |
| phone | Telefono attuale della conversazione |
| relatedphones | Telefoni già correlati (array, per escluderli) |
Risposta attesa
{
"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: Puoi usare “customers“ o “results“ come nome dell’array. Il campo “phone“ di ogni cliente permette a WAzion di collegare automaticamente la conversazione.
4 search_Products
Consente di cercare prodotti nel tuo catalogo esterno. I risultati vengono mostrati nel pannello laterale e l’agente può condividerli con il cliente. L’IA può anche cercare prodotti per rispondere alle domande.
Nota per CRM Custom: WAzion agisce come proxy trasparente per questo endpoint. La risposta del tuo CRM viene restituita direttamente all’estensione senza modifiche. Devi implementare la struttura completa documentata se desideri sfruttare tutte le funzionalità. I campi arricchiti (target_locale, title_copy, raw, ecc.) vengono generati automaticamente solo per i negozi Shopify.
Parametri inviati
| Parametro | Tipo | Descrizione |
|---|---|---|
| q | string | Testo di ricerca (minimo 2 caratteri) |
| token | string | Token di autenticazione del negozio |
| phone | string | Telefono del cliente (E.164) - per URL localizzate per paese |
| format | string | ai“ quando l’IA cerca prodotti (cambia struttura della risposta) |
| target_locale | string | Lingua rilevata del cliente basata sul suo telefono (es: “es“, “de“, “fr“) |
| test | boolean | vero se è una prova di connessione |
Nuovo: target_locale - WAzion rileva automaticamente la lingua del cliente basandosi sul prefisso del suo telefono. Per esempio, +34... → “es“, +49... → “de“. Usa questo parametro per restituire i prodotti nella lingua corretta.
Risposta formato NORMALE (pannello laterale)
Quando l’agente cerca prodotti dal pannello. Include campi per copiare/condividere.
{
"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": { ... }
}
Risposta formato AI (quando format=“ai“)
Quando l’IA cerca prodotti. Struttura semplificata senza campi di copia, descrizione 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"
}
Visualizza tutti i campi del prodotto
| Campo | Normale | IA | Descrizione |
|---|---|---|---|
| title | Original | Tradotto | Titolo del prodotto |
| title_copy | Tradotto | - | Titolo da copiare (lingua del cliente) |
| handle | ✓ | ✓ | Slug del prodotto |
| description | 500 caratteri | Completa | Descrizione (HTML pulito) |
| sku | ✓ | ✓ | SKU della prima variante |
| image | ✓ | - | URL dell’immagine (può essere proxied) |
| url | ✓ | ✓ | URL localizzata del prodotto |
| variants | ✓ | ✓ | Array di varianti |
Vedere campi di ogni variante
| Campo | Normale | IA | Descrizione |
|---|---|---|---|
| id | ✓ | ✓ | ID della variante |
| title | Original | Tradotto | Titolo della variante (es: “M / Rosso“) |
| title_copy | Tradotto | - | Titolo da copiare (lingua del cliente) |
| has_custom_title | ✓ | - | vero se ha un titolo personalizzato (non “Titolo Predefinito“) |
| sku | ✓ | ✓ | SKU della variante |
| image | ✓ | - | Immagine specifica della variante (o del prodotto se non ne ha) |
| url | ✓ | ✓ | URL con ?variant=ID |
Visualizza campi della risposta radice
| Campo | Normale | IA | Descrizione |
|---|---|---|---|
| http_status | ✓ | - | Codice HTTP della risposta |
| count | ✓ | ✓ | Numero di prodotti trovati |
| products | ✓ | ✓ | Array di prodotti |
| target_locale | ✓ | - | Locale usato per le traduzioni |
| locale | - | ✓ | Locale usato (solo formato AI) |
| raw | ✓ | - | Risposta raw dalla fonte (debug) |
🌍 URL localizzate per paese
Il parametro phone contiene il numero di telefono del cliente (E.164). Usalo per rilevare il suo paese e restituire URL adattate:
- Domini specifici per paese (tutienda.es, tutienda.de, tutienda.fr)
- Percorsi con prefisso di lingua (/es/, /de/, /fr/)
- Parametri di locale (?locale=es_ES)
- Mercati specifici di Shopify
Esempio: Se il telefono inizia con +34 (Spagna), restituire URL con dominio .es o /es/.
5 globalSearch
Ricerca globale di clienti per il motore di ricerca flottante dell’estensione. Permette di cercare per nome, email, telefono o numero d’ordine.
Parametri inviati
| Parametro | Tipo | Descrizione |
|---|---|---|
| query | string | Testo di ricerca (minimo 2 caratteri) |
| token | string | Token di autenticazione del negozio |
Risposta attesa
{
"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"
}
]
}
]
}
Campi di ogni cliente
| Campo | Tipo | Richiesto | Descrizione |
|---|---|---|---|
| id | string | Sì | ID univoco del cliente nel tuo sistema |
| name | string | Sì | Nome completo del cliente |
| string | Sì | Email del cliente | |
| phone | string | Sì | Telefono del cliente (E.164 preferito, es: +34612345678) |
| customerUrl | string | No | URL per vedere il cliente nel tuo CRM (viene mostrato come link cliccabile) |
| orders | array | No | Array con gli ultimi ordini (massimo 3) |
Campi di ogni ordine (orders[])
| Campo | Tipo | Richiesto | Descrizione |
|---|---|---|---|
| number | string | Sì | Numero d’ordine (es: “#ORD-1234“) |
| url | string | No | URL per vedere l’ordine nel tuo sistema |
Note importanti
- • Il campo
phoneè obbligatorio affinché l’agente possa aprire la conversazione con quel cliente. - • Saranno mostrati all’utente massimo 15 risultati (limitato automaticamente).
- • I duplicati per telefono vengono eliminati automaticamente.
- • Se
customerUrlè presente, il nome del cliente sarà un collegamento cliccabile. - • Gli ordini sono mostrati come singoli collegamenti sotto il cliente.
Specifiche Tecniche
Timeout
| globalSearch | 5s |
| Altri endpoint | 10s |
| Timeout di connessione | 5s |
| Ritenti | No |
Metodi HTTP
| Configurabile | GET / POST |
| Corpo (POST) | JSON / Form |
| Parametri (GET) | Query string |
Requisiti
- HTTPS obbligatorio
- Risposta JSON valida
- HTTP 200 sempre (usare found:false se non ci sono dati)
Differenza con Funzioni IA
Gli endpoint CRM NON tentano automaticamente di nuovo in caso di errore. Vengono chiamati in tempo reale mentre l’agente lavora, quindi devono rispondere rapidamente. Se falliscono, l’informazione semplicemente non appare.
Tipi di Autenticazione
Esempio URL (GET + query auth)
// WAzion llamará:
https://tu-api.com/customer
?phone=+34612345678
&token=tu-token-secreto
&relatedphones=["+34698765432"]
&test=false
Esempi di Implementazione
<?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})
Cronologia delle modifiche
sidePanel_CustomerInfo ora traduce automaticamente tutte le etichette se label_languages è diverso dalla lingua del negozio. Puoi mantenere il tuo CRM in una sola lingua (es: inglese) e WAzion si occupa delle traduzioni.
WAzion ora invia la lingua rilevata del cliente (basata sul prefisso del suo telefono) come parametro target_locale. Utile per restituire i prodotti nella lingua corretta del cliente.