# 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.

> Os dados e nomes de template são ilustrativos. As funções de banco e fila representam operações que você implementa no seu sistema; não são endpoints da Patrocinio Tech.

## O fluxo em quatro etapas

| Etapa | Resultado |
| --- | --- |
| [1. Preparar](https://patrociniotech.com/documentacao-api/exemplo.md) | Telefone normalizado, template compatível e operação gravada antes do envio. |
| [2. Enviar](https://patrociniotech.com/documentacao-api/exemplo.md) | Aceite da Meta associado ao seu pedido e ao message\_id. |
| [3. Receber eventos](https://patrociniotech.com/documentacao-api/exemplo.md) | Status confirmado no seu banco, sem aplicar eventos repetidos. |
| [4. Recuperar eventos](https://patrociniotech.com/documentacao-api/exemplo.md) | Entregas do webhook que falharam reenfileiradas após corrigir o receptor. |

## 1. Prepare a operação

Consulte [o template do número de envio](https://patrociniotech.com/documentacao-api/templates.md). 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 · validar telefone

```bash
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

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 · enviar aviso

```bash
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"
  }'
```

JSON · envio aceito

```json
{
  "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](https://patrociniotech.com/documentacao-api/erros.md).

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

Configure o endpoint em Integrações. Verifique a [assinatura sobre o corpo original](https://patrociniotech.com/documentacao-api/webhook.md), grave o evento em uma fila durável e só então responda 200.

JSON · confirmação de entrega

```json
{
  "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",
    "client_ref": "pedido-8421-aviso-entrega",
    "campaign_id": null,
    "error": null
  }
}
```

Node.js · recepção com fila durável

```javascript
// 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",
      id: delivery_id, // índice único: integração + id
      corpo: req.body,
    });
    return res.sendStatus(200); // inclui duplicata já gravada
  } catch {
    return res.sendStatus(503); // a gravação não foi confirmada
  }
});
```

Node.js · processamento da fila

```javascript
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);
    } else if (event === "message.received") {
      await tx.registrarMensagemRecebidaSeNova(data);
    }
    await tx.marcarEventoProcessado(item.id);
  });
}
```

> Implemente os índices únicos, a fila e as transações no seu banco. Se o evento chegar antes da resposta do envio, mantenha-o para conciliação posterior. Efeitos externos, como emitir um bilhete, precisam de uma operação própria com idempotência.

## 4. Recupere eventos que falharam

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 · consultar eventos com falha

```bash
curl "https://api.patrociniotech.com/public/v1/deliveries?status=failed&limit=200" \
  -H "Authorization: Bearer SUA_CHAVE"
```

cURL · reenfileirar eventos com falha

```bash
curl -X POST "https://api.patrociniotech.com/public/v1/deliveries/retry-failed" \
  -H "Authorization: Bearer SUA_CHAVE"
```

> Reenviar uma entrega do webhook repete o evento para o seu servidor. Isso não envia outra mensagem ao contato. O receptor deve reconhecer o mesmo `delivery_id`. Veja [paginação e reenvio de entregas](https://patrociniotech.com/documentacao-api/entregas.md).

## Estados no seu sistema

| 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. |

---

Fonte: https://patrociniotech.com/documentacao-api/exemplo
Índice para IA: https://patrociniotech.com/documentacao-api/llms.txt
