Você compra algo online e logo após o envio recebe email com código de rastreio. Aí começa a saga: copiar código, abrir site da transportadora, lembrar senha de cliente, ver "objeto postado" há 3 dias. Quando seu pedido finalmente chega, você não estava em casa porque ninguém te avisou. Multiplique isso por 1.000 entregas/dia e você tem o motivo de transportadoras gastarem milhões em call center.
WhatsApp resolve toda essa cadeia. Notificação proativa em cada etapa, confirmação de presença antes da entrega, foto da entrega como prova, avaliação no fim. Custo? 200x menor que ligação. Resultado? Reentregas caem de 12% para 3%.
O custo das reentregas
Números brutos do setor:
- Custo de uma ligação: R$3-8 (dependendo do plano de telefonia da transportadora)
- Custo de uma mensagem WhatsApp: R$0,02-0,15 (200-400x menor)
- Taxa de leitura email: 18%
- Taxa de leitura WhatsApp: 96%
- Custo médio de reentrega: R$12-25 por tentativa
- Reentrega evitada com WhatsApp: 60-75% (cliente avisa que não vai estar)
Os 6 eventos do ciclo de entrega
Mapeamento típico de uma entrega:
- POSTADO — pacote saiu do remetente, entrou no centro de distribuição
- EM TRÂNSITO — em movimento entre filiais
- SAIU PARA ENTREGA — entregador com o pacote, ETA 1-3h
- TENTATIVA — entregador foi mas não conseguiu entregar (ausente, endereço errado)
- ENTREGUE — entregue ao destinatário
- DEVOLVIDO — após N tentativas, volta para o remetente
Webhook da transportadora → ZAP API → cliente
// transportadora-webhook.ts
import express from "express";
import axios from "axios";
const app = express();
app.use(express.json());
const ZAP = axios.create({
baseURL: "https://api.zap-api.tech/v1",
headers: { Authorization: `Bearer ${process.env.ZAP_TOKEN}` },
});
app.post("/webhook/transportadora", async (req, res) => {
res.status(200).send("ok"); // ack imediato
const { trackingCode, status, deliveredAt, recipientPhone, photoUrl, deliveryGps } = req.body;
// Busca destinatário no banco a partir do trackingCode
const pedido = await db.query(
"SELECT * FROM pedidos WHERE tracking_code=$1",
[trackingCode],
).then(r => r.rows[0]);
if (!pedido) return;
switch (status) {
case "POSTADO":
await sendText(pedido.cliente_telefone, `📦 Seu pedido foi postado! Código de rastreio: ${trackingCode}`);
break;
case "SAIU_PARA_ENTREGA":
await sendText(
pedido.cliente_telefone,
`🛵 Seu pedido saiu para entrega!\n\nETA: 1-3 horas\nVocê estará no endereço para receber? Responda *SIM* ou *NÃO*.`,
);
break;
case "TENTATIVA":
await sendText(
pedido.cliente_telefone,
`⚠️ Não conseguimos entregar seu pedido.\nMotivo: ${req.body.failReason}\n\nDigite *REAGENDAR* para escolher novo dia ou *RETIRAR* para retirar no balcão.`,
);
break;
case "ENTREGUE":
// Confirmação com foto da entrega
await sendText(pedido.cliente_telefone, `✅ *Entregue!* 📸`);
if (photoUrl) {
await ZAP.post(`/instances/${process.env.INSTANCE_ID}/messages`, {
to: pedido.cliente_telefone,
type: "image",
image: { url: photoUrl, caption: "Foto da entrega" },
});
}
// Avaliação
await sendRatingButtons(pedido.cliente_telefone);
break;
case "DEVOLVIDO":
await sendText(
pedido.cliente_telefone,
`📤 Após 3 tentativas, seu pedido foi devolvido ao remetente. Entre em contato com o remetente para combinar novo envio.`,
);
break;
}
});
async function sendText(to: string, text: string) {
return ZAP.post(`/instances/${process.env.INSTANCE_ID}/messages`, { to, type: "text", text });
}
Confirmação por keyword
Cliente responde "SIM" ou manda foto da nota → você sabe que recebeu. Webhook detecta:
app.post("/webhook/zap", async (req, res) => {
res.status(200).send("ok");
if (req.body.type !== "message.received") return;
const { from, body, mediaUrl } = req.body.message;
const pedido = await db.query(
"SELECT * FROM pedidos WHERE cliente_telefone=$1 AND status='SAIU_PARA_ENTREGA' ORDER BY created_at DESC LIMIT 1",
[from],
).then(r => r.rows[0]);
if (!pedido) return;
const text = (body.text || "").trim().toUpperCase();
if (text === "SIM") {
await db.query("UPDATE pedidos SET cliente_em_casa=true WHERE id=$1", [pedido.id]);
await sendText(from, "Combinado! Entregador a caminho.");
}
if (text === "NAO") {
await sendText(from, "Sem problema. Vamos tentar amanhã. Pode confirmar o melhor horário?");
await db.query("UPDATE pedidos SET reagendar=true WHERE id=$1", [pedido.id]);
}
if (mediaUrl) {
// Cliente mandou foto da NF como prova
await arquivarNF(pedido.id, mediaUrl);
await sendText(from, "Recebemos a NF, obrigado!");
}
});
Localização do entregador em tempo real
Quando cliente confirma "SIM" para a entrega, mande localização atualizada do entregador a cada 10 minutos:
// cron a cada 10 min
async function updateDelivererLocation() {
const ativos = await db.query(`
SELECT p.*, e.gps_lat, e.gps_lng FROM pedidos p
JOIN entregadores e ON e.id = p.entregador_id
WHERE p.status='SAIU_PARA_ENTREGA' AND p.cliente_em_casa=true
`);
for (const p of ativos.rows) {
await ZAP.post(`/instances/${process.env.INSTANCE_ID}/messages`, {
to: p.cliente_telefone,
type: "location",
location: {
latitude: p.gps_lat,
longitude: p.gps_lng,
name: `Entregador a caminho — chegada estimada ${etaFromGps(p.gps_lat, p.gps_lng, p.endereco_lat, p.endereco_lng)}`,
},
});
}
}
Foto da entrega como prova legal
Entregador tira foto via app, sistema salva em S3, ZAP API envia para o cliente. A foto serve de evidência em caso de "não recebi":
async function notificaEntregue(pedido, photoUrl) {
// 1. Manda foto da entrega
await ZAP.post(`/instances/${process.env.INSTANCE_ID}/messages`, {
to: pedido.cliente_telefone,
type: "image",
image: {
url: photoUrl,
caption: `✅ Entrega realizada às ${new Date().toLocaleTimeString("pt-BR")}`,
},
});
// 2. Salva como prova legal
await db.query(`
UPDATE pedidos SET
status='ENTREGUE',
delivered_at=NOW(),
delivery_proof_url=$1
WHERE id=$2
`, [photoUrl, pedido.id]);
}
Casos práticos
Caso 1: E-commerce regional
Loja de perfumes que faz 800 entregas/dia em região metropolitana. Antes: 15% reentregas, custo R$2k/mês com call center. Após: 4% reentregas, sem call center. Economia anual R$35k. Bônus: NPS subiu de 62 para 81 — clientes elogiam comunicação.
Caso 2: Transportadora regional B2B
Empresa de logística que entrega para 30 lojas de varejo. Implementou WhatsApp para os clientes finais das lojas (não para as lojas). Entregadores tiram foto, sistema notifica. Lojas relataram queda de 60% em "cadê meu pedido?" no SAC delas — porque cliente já está informado direto.
Caso 3: Marketplace de produtos artesanais
Marketplace que conecta artesãos a compradores. Usa WhatsApp para todo o ciclo de entrega + envia avaliação no final que dispara comissão extra para o artesão se for 5 estrelas. Repeat purchase rate subiu de 18% para 31% pela percepção de cuidado.
FAQ
Funciona com Correios, Jadlog, Total Express?
Sim — qualquer transportadora que expõe webhook (a maioria moderna) ou tem API consultável. Para os Correios, é mais comum scraping do rastreamento (sem webhook nativo); para Jadlog/Total/Loggi, webhooks oficiais nas docs deles.
E se o número do cliente está errado?
Webhook ZAP API retorna erro not_a_whatsapp_number. Você tem 2 opções: (1) marcar pedido como "sem WhatsApp" e usar canal alternativo (SMS, email); (2) tentar números variantes (com/sem 9 antes, com/sem 55). Recomendamos sempre validar o número no ato do pedido com call-to-action no checkout: "Confirme com SMS para receber rastreio no WhatsApp".
Quantas tentativas de entrega antes de devolver?
Padrão do setor é 3. Mas com WhatsApp você pode ser mais flexível: cliente que confirmou ausência via mensagem pode ter 5 tentativas (já sabe que ele quer receber, só precisa coordenar). Cliente que ignorou todas as mensagens pode ir para devolução em 2 tentativas — sinal forte que não vai receber.
LGPD em rastreamento via WhatsApp?
Tratamento de dados (telefone, endereço) é necessário para "execução de contrato de transporte" — base legal LGPD Art. 7º V. Não precisa de opt-in explícito para mensagens operacionais (rastreamento). Mas inclua opt-out no rodapé: "Para parar de receber atualizações, responda SAIR."
Custo médio por entrega?
Cenário típico: 6 mensagens por entrega (postado, em trânsito, saiu, ETA, entregue, avaliação). Custo: R$0,90-1,20 por entrega. Compare com call center (R$5-15) ou SMS (R$0,30 por SMS, mas sem rich content). WhatsApp é o canal mais barato com a melhor experiência.
Próximo passo
Conecte sua transportadora à ZAP API em algumas horas e comece a notificar clientes proativamente. Criar conta grátis e teste o fluxo completo de rastreamento.