API e desenvolvedores

Receita: Shopify (Flow)

Dispare o envio de template pelo Shopify Flow, sem código e sem um servidor seu.

Esta é a receita guiada do contrato genérico de Mensagens de Template: o mesmo POST, resolvido passo a passo a partir da Shopify.

A Shopify não chama esta API por conta própria, mas o Shopify Flow — o app oficial de automação, gratuito — chama: ele dispara com o carrinho abandonado e faz o POST. É o caminho sem código e sem um servidor seu no meio.

Antes de começar

Requisito Onde se resolve
Template aprovado Com o nome técnico e o language exatos — GET /v1/templates lista os que você tem.
API key Com o escopo outbound:send para enviar, mais outbound:read se você for consultar o estado — veja Autenticação.
Telefone exigido no checkout Shopify → Settings → Checkout: Customer contact method em "Phone number or email", e Shipping address phone number em "Required". Sem telefone no carrinho não há para quem escrever.
E-mail nativo de recuperação desligado Shopify → Marketing → Automations: se o WhatsApp assume, desative o "Abandoned checkout" nativo. Senão, o cliente recebe dois lembretes do mesmo carrinho.

O workflow

  1. Trigger — Customer abandons checkout.
  2. Condition — abandonment.customer.defaultPhoneNumber is not empty. Um checkout sem telefone não pode ser enviado: cortar aqui evita gastar a chamada num 422.
  3. Action — Send HTTP request, com método POST, a URL https://api.ya.onl/v1/template-messages e dois headers: X-API-Key com a sua key e Content-Type: application/json.

O corpo

{
  "event_id": "CART-{{ abandonment.id | split: '/' | last }}",
  "phone": "{{ abandonment.customer.defaultPhoneNumber.phoneNumber }}",
  "template": { "name": "SEU_TEMPLATE", "language": "es" },
  "variables": {
    "1": "{{ abandonment.customer.firstName }}",
    "2": "{% for item in abandonment.abandonedCheckoutPayload.lineItems limit: 3 %}{{ item.quantity }}× {{ item.title | replace: '\"', '' }}{% unless forloop.last %}, {% endunless %}{% endfor %}"
  },
  "occurred_at": "{{ abandonment.createdAt }}"
}
Campo O que essa linha faz
event_id Recorta o GID da Shopify (gid://shopify/Abandonment/774830424) até o último segmento, que respeita o charset do campo, e o prefixo CART- cobre o mínimo de 8 caracteres e dá a idempotência: se o Flow repetir, o cliente não recebe duas mensagens.
phone defaultPhoneNumber.phoneNumber já vem em E.164 (+51987654321), que é exatamente o que o campo exige.
template Objeto com o nome e o idioma do seu template, tal como estão aprovados na Meta: troque SEU_TEMPLATE e ajuste o language.
variables Por posição, na ordem do seu template: "1" o nome, "2" os três primeiros produtos. Ajuste a quantidade à que o template exige — faltar uma é um 422. O replace tira as aspas do título, que quebrariam o JSON.
occurred_at abandonment.createdAt já traz offset, e é o que liga a janela de frescura: um abandono velho volta discarded com motivo stale em vez de ser enviado atrasado.

A receita é genérica. O contrato é o mesmo a partir de qualquer plataforma capaz de fazer um POST — outro ecommerce, o seu próprio backend ou um automatizador tipo Zapier ou Make. O Shopify Flow é só o exemplo guiado, porque resolve o disparo do abandono sem escrever código.

Verificar que saiu

curl https://api.ya.onl/v1/template-messages/CART-774830424 \
  -H "X-API-Key: yv_live_v1_sua_api_key"

Com a mesma key — desde que ela tenha outbound:read — e o mesmo event_id que o Flow montou. Um 404 significa que a chamada nunca chegou: revise o histórico de execuções do workflow no Flow.

Precisa de ajuda?