Do envio à confirmação de entrega
Um aviso de pedido com referência própria, proteção contra duplicação e atualização de status pelo webhook.
O fluxo em quatro etapas (link para esta seção)
| Etapa | Resultado |
|---|---|
| 1. Preparar | Telefone normalizado, template compatível e operação gravada antes do envio. |
| 2. Enviar | Aceite da Meta associado ao seu pedido e ao message_id. |
| 3. Receber eventos | Status confirmado no seu banco, sem aplicar eventos repetidos. |
| 4. Recuperar eventos | Entregas do webhook que falharam reenfileiradas após corrigir o receptor. |
1. Prepare a operação (link para esta seção)
Consulte o template do número de envio. Confira o consentimento do contato e salve sua operação com uma chave única antes de chamar a API.
| No seu registro | Exemplo |
|---|---|
| Referência da operação | pedido-8421-aviso-entrega |
| Chave de idempotência | pedido-8421-aviso-entrega-v1 |
| Dados de envio | Destinatário, phone_number_id, template, idioma e variáveis. |
| Estado inicial | Pendente. Registre o resultado de cada tentativa sem substituir a chave original. |
Normalizar o telefone antes de enviar
curl -X POST https://api.patrociniotech.com/public/v1/validate \
-H "Authorization: Bearer SUA_CHAVE" \
-H "Content-Type: application/json" \
-d '{"to": "(21) 99999-9999", "country": "BR"}'Quando data.valid for true, use o telefone de data.to. Em caso contrário, corrija o cadastro. A validação confirma o formato, não a existência no WhatsApp.
2. Envie e registre o aceite (link para esta seção)
O modelo abaixo usa duas variáveis numeradas: nome e pedido. Mantenha o mesmo corpo e a mesma chave ao repetir esta operação.
curl -X POST https://api.patrociniotech.com/public/v1/messages \
-H "Authorization: Bearer SUA_CHAVE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-8421-aviso-entrega-v1" \
-d '{
"to": "5521999999999",
"phone_number_id": "SEU_NUMERO_ID",
"template": "aviso_entrega",
"language": "pt_BR",
"variables": ["Maria", "8421"],
"client_ref": "pedido-8421-aviso-entrega"
}'{
"success": true,
"data": {
"message_id": "wamid.EXEMPLO",
"status": "sent",
"to": "5521999999999",
"client_ref": "pedido-8421-aviso-entrega"
}
}Associe message_id à operação gravada. client_ref volta no webhook para ajudar na conciliação, mas não substitui a chave de idempotência.
sent significa aceite da Meta. O relatório só deve contar como entregue após o evento correspondente. Em falha de conexão ou resultado incerto, preserve a operação e use a política de novas tentativas.Para uma fila de envios, aplique o limite de 600 requisições por minuto por chave ao conjunto dos workers. Somar vários processos com limites separados pode ultrapassar o teto.
3. Receba e processe o webhook (link para esta seção)
Configure o endpoint em Integrações. Verifique a assinatura sobre o corpo original, grave o evento em uma fila durável e só então responda 200.
{
"event": "message.status",
"occurred_at": "2026-10-06T14:02:11Z",
"delivery_id": "8814",
"data": {
"message_id": "wamid.EXEMPLO",
"status": "delivered",
"status_rank": 3,
"to": "5521999999999",
"phone_number_id": "SEU_NUMERO_ID",// Configure req.rawBody e assinaturaValida conforme a página Webhook.
app.post("/webhooks/patrociniotech", async (req, res) => {
if (!assinaturaValida(req, process.env.PT_WEBHOOK_SECRET)) return res.sendStatus(401);
const { delivery_id, event } = req.body;
if (!delivery_id || !["message.status", "message.received"].includes(event)) {
return res.sendStatus(400);
}
try {
await inserirEventoSeNovo({
integracao: "patrociniotech",async function processarEvento(evento) {
await transacao(async (tx) => {
const item = await tx.bloquearEvento(evento.id);
if (item.processado) return;
const { event, data } = item.corpo;
if (event === "message.status" && !data.test) {
// Atualize por message_id, client_ref e número da empresa.
// sent < delivered < read; failed pode substituir sent,
// mas não pode apagar uma entrega ou leitura confirmada.
await tx.atualizarStatusSemRegressao(data);4. Recupere eventos que falharam (link para esta seção)
A fila tenta entregar os eventos por cerca de 31 horas, com pausas progressivas. Se as tentativas esgotarem, corrija o receptor antes de solicitar o reenvio.
curl "https://api.patrociniotech.com/public/v1/deliveries?status=failed&limit=200" \
-H "Authorization: Bearer SUA_CHAVE"curl -X POST "https://api.patrociniotech.com/public/v1/deliveries/retry-failed" \
-H "Authorization: Bearer SUA_CHAVE"delivery_id. Veja paginação e reenvio de entregas.Estados no seu sistema (link para esta seção)
| Estado | Evidência |
|---|---|
| Aceita | Resposta do envio com message_id e status sent. |
| Entregue / lida | Evento message.status com delivered ou read, conciliado com a operação. |
| Falhou | Recusa confirmada ou evento failed. Guarde error.code e error.reason quando presentes. |
| Aguardando confirmação | Sem evidência suficiente do resultado. Preserve a operação e investigue; não presuma falha nem gere outro envio. |