> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ararahq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Confirmação de pedido

> Avise o cliente pelo WhatsApp quando o pedido for confirmado, enviado, entregue ou quando o pagamento falhar, sem mensagem duplicada.

Ao final, seu backend envia uma mensagem a cada etapa do pedido (confirmado, enviado, entregue, pagamento recusado) e sabe quando alguma não chegou.

## Antes de começar

* Chave de API na variável `ARARA_API_KEY`. Ver [Autenticação](/api-reference/authentication).
* Número conectado na organização. Ver [Números](/numbers).
* Templates `UTILITY` aprovados (o passo 1 cria). Ver [Templates](/concepts/templates).
* Webhook configurado para receber o status de entrega. Ver [Webhooks](/webhooks).
* Telefone do cliente em E.164 (`+5511999999999`). `(11) 99999-9999` precisa ser convertido antes.

## Passo a passo

<Steps>
  <Step title="Crie os templates">
    Um template `UTILITY` por etapa. Exemplo do primeiro:

    ```bash theme={null}
    curl -X POST https://api.ararahq.com/v1/templates \
      -H "Authorization: Bearer $ARARA_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "pedido_confirmado",
        "category": "UTILITY",
        "language": "pt_BR",
        "body": "Pedido {{1}} confirmado.\n\nTotal: R$ {{2}}\nPagamento: {{3}}\nPrazo: {{4}}\n\nAvisamos quando for despachado.",
        "samples": { "1": "ARA-12345", "2": "147,90", "3": "Pix", "4": "2 dias úteis" },
        "buttons": [
          { "type": "URL", "text": "Ver pedido", "url": "https://meusite.com/pedido/{{1}}" }
        ]
      }'
    ```

    Repita para os outros três, trocando `name`, `body`, `samples` e `buttons`:

    | `name` | `body` | Botão `URL` |
    | - | - | - |
    | `pedido_enviado` | `Seu pedido {{1}} saiu para entrega.\n\nCódigo de rastreio: {{2}}\nTransportadora: {{3}}` | "Rastrear", `https://meusite.com/rastreio/{{2}}` |
    | `pedido_entregue` | `Seu pedido {{1}} foi entregue.\n\nSe algo não estiver certo, responda esta mensagem.` | sem botão |
    | `pagamento_falhou` | `Não conseguimos confirmar o pagamento do pedido {{1}}.\n\nMotivo: {{2}}\n\nVocê pode tentar de novo pelo link abaixo.` | "Tentar novamente", `https://meusite.com/checkout/{{1}}` |

    * `samples` é um objeto com o número da variável como chave.
    * No botão de URL, `{{N}}` reaproveita a variável `N` do corpo. Só o trecho **depois da última `/`** do valor entra no link. Passe um identificador simples (id do pedido, código de rastreio), não uma URL inteira.
    * A resposta traz o `id` (UUID). Acompanhe a aprovação com `GET /v1/templates/{id}/status` ou pelo webhook `template.updated`.
  </Step>

  <Step title="Envie em cada etapa do pedido">
    A `Idempotency-Key` vem do pedido e da etapa. Se o seu job rodar de novo (retry, webhook reenviado pela loja), a Arara devolve a mensagem original em vez de enviar outra.

    <CodeGroup>
      ```typescript Node.js theme={null}
      // notify-order.ts
      import { NodeSDK } from '@ararahq/sdk';

      const sdk = new NodeSDK({ apiKey: process.env.ARARA_API_KEY! });

      interface Order {
        id: string;
        phone: string; // E.164, ex.: +5511999999999
        totalFormatted: string;
        paymentMethod: string;
        estimatedDelivery: string;
      }

      function send(order: Order, templateName: string, templateVariables: string[], idempotencyKey: string) {
        return sdk.messages.send({ receiver: order.phone, templateName, templateVariables }, { idempotencyKey });
      }

      export function notifyOrderConfirmed(order: Order) {
        const variables = [order.id, order.totalFormatted, order.paymentMethod, order.estimatedDelivery];
        return send(order, 'pedido_confirmado', variables, `order-confirmed-${order.id}`);
      }

      export function notifyOrderShipped(order: Order, trackingCode: string, carrier: string) {
        return send(order, 'pedido_enviado', [order.id, trackingCode, carrier], `order-shipped-${order.id}-${trackingCode}`);
      }

      export function notifyOrderDelivered(order: Order) {
        return send(order, 'pedido_entregue', [order.id], `order-delivered-${order.id}`);
      }

      export function notifyPaymentFailed(order: Order, reason: string, attempt: number) {
        return send(order, 'pagamento_falhou', [order.id, reason], `payment-failed-${order.id}-${attempt}`);
      }
      ```

      ```python Python theme={null}
      # notify_order.py
      from arara_api_sdk import AraraClient
      from arara_api_sdk.models.message import SendMessageRequest

      client = AraraClient()  # lê ARARA_API_KEY do ambiente


      def notify_order_confirmed(order):
          return client.messages.send(
              SendMessageRequest(
                  receiver=order.phone,
                  template_name="pedido_confirmado",
                  template_variables=[
                      order.id,
                      order.total_formatted,
                      order.payment_method,
                      order.estimated_delivery,
                  ],
              ),
              idempotency_key=f"order-confirmed-{order.id}",
          )
      ```

      ```php PHP theme={null}
      <?php
      // notify_order.php
      use Arara\Arara;
      use Arara\Config;

      function notifyOrderConfirmed(object $order): array
      {
          $sdk = new Arara(new Config(apiKey: getenv('ARARA_API_KEY')));

          return $sdk->messages->send(
              receiver: $order->phone,
              templateName: 'pedido_confirmado',
              variables: [
                  $order->id,
                  $order->total_formatted,
                  $order->payment_method,
                  $order->estimated_delivery,
              ],
              idempotencyKey: "order-confirmed-{$order->id}",
          );
      }
      ```
    </CodeGroup>

    A API responde `202` com `{ id, status, mode, sender, receiver, body, cost, reason }`. Guarde o `id` (`ara_msg_...`) junto do pedido para casar com o webhook.

    | Etapa | Gatilho típico |
    | - | - |
    | Confirmado | Webhook de pedido pago da sua loja ou gateway |
    | Enviado | Criação do envio (ex.: `fulfillments/create` no Shopify, ver [integração Shopify](/integracoes/shopify)) |
    | Entregue | Webhook do rastreador ou da transportadora |
    | Pagamento falhou | Webhook do gateway de pagamento |
  </Step>

  <Step title="Acompanhe a entrega">
    O status chega pelo webhook `message.status_updated`, em minúsculas: `queued`, `processing`, `scheduled`, `sent`, `delivered`, `read`, `failed`, `canceled`.

    ```json theme={null}
    {
      "event": "message.status_updated",
      "apiVersion": "...",
      "timestamp": "...",
      "organizationId": "...",
      "data": {
        "id": "ara_msg_...",
        "status": "failed",
        "receiver": "...",
        "sender": "...",
        "errorDetails": "..."
      }
    }
    ```

    Valide a assinatura antes de processar (ver [Webhooks](/webhooks)). Com `failed`, leia `errorDetails`. Se o número não recebe WhatsApp, caia para e-mail ou SMS no seu sistema. Ver [Erros de envio](/erros-de-envio).
  </Step>
</Steps>

## Armadilhas

<Warning>
  Em `POST /v1/messages` a idempotência não compara o conteúdo. A mesma chave com outro destinatário ou outras variáveis devolve a mensagem original, sem erro. Para reenviar de propósito (o cliente corrigiu o telefone, por exemplo), use outra chave. A chave não expira e vale por usuário dono da chave de API.
</Warning>

* **Template não abre a janela de 24h.** Ela abre quando o cliente responde. A partir daí o [Brain](/brain) ou o seu time respondem.
* **Oferta de nova compra é `MARKETING`.** Não coloque cupom em template `UTILITY`: crie um template `MARKETING` separado e envie só para quem aceitou receber marketing.

## Próximos passos

<CardGroup cols={2}>
  <Card title="Atendimento com vários atendentes" icon="users" href="/recipes/inbox-support">
    Quem atende quando o cliente responde.
  </Card>

  <Card title="Carrinho abandonado" icon="cart-shopping" href="/recipes/abandoned-cart">
    Recupere quem não chegou a virar pedido.
  </Card>

  <Card title="Eventos de webhook" icon="bell" href="/webhooks/events">
    Payload de cada evento.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.