WhatsApp Business API para confirmação de assinatura
O cenário envia ao cliente um modelo personalizado de WhatsApp quando uma nova assinatura é ativada.
Visão geral do caso de uso
O cenário envia para o cliente um template personalizado de WhatsApp quando uma nova assinatura é ativada. A mensagem inclui o nome do cliente, nome do serviço, valor do pagamento e data de ativação. Um botão de URL estático abre a página de gerenciamento de assinatura.
Exemplo de modelo
Olá,{{1}}! Sua assinatura.{{2}}para{{3}}está ativo em{{4}}. Bem-vindo a bordo!
- {{1}}nome do cliente
- {{2}}nome do serviço ou plano
- {{3}}valor do pagamento
- {{4}}data de ativação
- “Ver assinatura”botão — fixo no modelo Meta

Quando usá-lo
Acesse este cenário quando a cobrança ou seu sistema de assinatura confirmar uma nova inscrição ou primeiro pagamento e o cliente ainda precisar de prova de que o acesso está ativo em um canal que ele realmente verá. Isso se encaixa nos fluxos de integração de IA SaaS, programas de associação que recebem novos assinantes com detalhes do plano e integradores conectando webhooks de cobrança de assinatura em confirmações do WhatsApp.
Fluxo de Trabalho
- Atos do cliente
O cliente completa o cadastro da assinatura e a cobrança confirma a ativação.
user action - Evento de captura
O sistema resolve os campos de número de telefone e assinatura do cliente.
phone:"+…" - Construir & enviar
Uma mensagem de modelo personalizada é criada com quatro variáveis de corpo e um botão de URL estático.
POST/sendTemplate - Entregue
O cliente recebe a confirmação pelo WhatsApp e pode abrir os detalhes da assinatura através do botão.
delivered - Status rastreado
O resultado da entrega é registrado para cobrança ou acompanhamento de CRM.
status:"read"

Implementação técnica
Pré-requisitos
- Chave da API 1MSG · Como conseguir a chave da API
- Conta do WhatsApp Business · Como Conectar WABA
- Modelo de WhatsApp · Como Aprovar o Template WABA
- Opção de consentimento do cliente · Como Gerenciar o Consentimento dos Clientes
Exemplos de código
#!/usr/bin/env bash
set -euo pipefail
# === Configuration (replace "___" placeholders) ===
API_BASE_URL="https://api.1msg.io" # production 1MSG API base URL
CHANNEL_ID="___" # channel ID from 1MSG dashboard
API_TOKEN="___" # channel JWT token (Bearer)
TEMPLATE_NAME="___" # approved template name
TEMPLATE_NAMESPACE="___" # template namespace (required — send fails without it)
TEMPLATE_LANGUAGE="___" # template language code, e.g. "en"
# === Test data ===
TEST_PHONE="___" # client phone in international format
TEST_CUSTOMERNAME="___" # {{1}} customer name
TEST_SERVICE="___" # {{2}} service name
TEST_PAYMENTAMOUNT="___" # {{3}} payment amount
TEST_DATE="___" # {{4}} date or time
PHONE_NORM="$(printf '%s' "$TEST_PHONE" | tr -cd '0-9')"
for pair in "CHANNEL_ID=$CHANNEL_ID" "API_TOKEN=$API_TOKEN" \
"TEMPLATE_NAME=$TEMPLATE_NAME" "TEMPLATE_NAMESPACE=$TEMPLATE_NAMESPACE" \
"TEMPLATE_LANGUAGE=$TEMPLATE_LANGUAGE" "TEST_PHONE=$TEST_PHONE" \
"TEST_CUSTOMERNAME=$TEST_CUSTOMERNAME" \
"TEST_SERVICE=$TEST_SERVICE" \
"TEST_PAYMENTAMOUNT=$TEST_PAYMENTAMOUNT" \
"TEST_DATE=$TEST_DATE"; do
val="${pair#*=}"
if [ -z "$val" ] || [ "$val" = "___" ]; then
echo "Missing configuration value: ${pair%%=*}" >&2
exit 1
fi
done
if [ -z "$PHONE_NORM" ]; then
echo "Error: phone number has no digits after normalization" >&2
exit 1
fi
URL="${API_BASE_URL%/}/${CHANNEL_ID}/sendTemplate"
# params carries body ONLY. Button text is fixed in the Meta template — no button param.
# {{1}} customer name → ${TEST_CUSTOMERNAME}
# {{2}} service name → ${TEST_SERVICE}
# {{3}} payment amount → ${TEST_PAYMENTAMOUNT}
# {{4}} date or time → ${TEST_DATE}
read -r -d '' PAYLOAD <<JSON || true
{
"phone": "${PHONE_NORM}",
"template": "${TEMPLATE_NAME}",
"namespace": "${TEMPLATE_NAMESPACE}",
"language": { "policy": "deterministic", "code": "${TEMPLATE_LANGUAGE}" },
"params": [
{
"type": "body",
"parameters": [
{ "type": "text", "text": "${TEST_CUSTOMERNAME}" },
{ "type": "text", "text": "${TEST_SERVICE}" },
{ "type": "text", "text": "${TEST_PAYMENTAMOUNT}" },
{ "type": "text", "text": "${TEST_DATE}" }
]
}
]
}
JSON
RESPONSE="$(curl -s -w '\n%{http_code}' -X POST "$URL" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${API_TOKEN}" \
-d "$PAYLOAD")"
HTTP_CODE="$(printf '%s' "$RESPONSE" | tail -n1)"
BODY="$(printf '%s' "$RESPONSE" | sed '$d')"
case "$BODY" in
*'"sent":true'*) ok=1 ;;
*) ok=0 ;;
esac
if [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 300 ] && [ "$ok" -eq 1 ]; then
echo "Message sent to client."
echo "API response: $BODY"
else
echo "Send failed. HTTP status: $HTTP_CODE" >&2
echo "$BODY" >&2
exit 1
fi
Status de resposta e entrega
HTTP 2xx e JSON"sent": truemean 1MSGaceitoa mensagem para enviar — não que tenha chegado ao telefone do cliente.idcampowamid.…) para correlacionar chamadas de entrega.
{
"sent": true,
"id": "wamid.HBgLMzgwNjM5...",
"message": "Message accepted for delivery"
}sentAceito para envio —nãoainda no telefone do cliente
idArmazene; retornos de entrega.
hookInfoestão focados nisso
A entrega em si chega mais tarde, como um callback separado. Registre um webhookPOST …/webhook) e 1MSG POSTs atualizações de status para o seu endpoint HTTPS.hooks[]carga útil.
{
"hooks": [
{
"id": "gBGGeSaGViBfAgnlzOSHEwK9O6F",
"type": "message",
"status": "sent",
"timestamp": "1654864094",
"recipient_id": "556123122026"
}
]
}statussent,delivered,read— ou um status de falha quando aplicávelidCorrelaciona o retorno com o
idretornado pela chamada de enviotimestampSegundos Unix, como uma string
Se você prefere não receber retornos de chamada, faça uma votação.GET {base}/{channel}/hookInfo?messageId=<id>em vez disso. Na prática, a entrega muitas vezes é concluída em poucos segundos — mas o contrato da API não garante isso, então nunca bloqueie um fluxo aguardando por ele.
Erros comuns
| Status | Resposta | Causa |
|---|---|---|
| 200 | Message was not sent: template is not defined | namespace, template or language missing from the request body. |
| 200 | template name (…) does not exist in <language> | The template is approved in a different language than the one requested. |
| 200 | Message was not sent: provide chatId, phone, bsuid, or username | No recipient the channel could resolve. |
| 403 | access denied | The token is wrong, or belongs to a different channel than the URL. |
| 429 | too many requests. please try later | The channel is over its send rate. |

