Receta: Shopify (Flow)
Dispara el envío de plantilla desde Shopify Flow, sin código y sin un servidor propio.
Esta es la receta guiada del contrato genérico de
Mensajes de Plantilla: el mismo POST, resuelto paso a paso
desde Shopify.
Shopify no llama a esta API por su cuenta, pero Shopify Flow —la app oficial de
automatización, gratuita— sí puede: se dispara con el carrito abandonado y hace el POST.
Es el camino sin código y sin un servidor propio en medio.
Antes de empezar
| Requisito | Dónde se resuelve |
|---|---|
| Plantilla aprobada | Con su nombre técnico y su language exactos — los lista GET /v1/templates. |
| API key | Con alcance outbound:send para enviar, más outbound:read si vas a verificar el estado — ver Autenticación. |
| Teléfono exigido en el checkout | Shopify → Settings → Checkout: Customer contact method en "Phone number or email", y Shipping address phone number en "Required". Sin teléfono en el carrito no hay a quién escribirle. |
| Email nativo de recuperación apagado | Shopify → Marketing → Automations: si el WhatsApp toma el relevo, desactiva el "Abandoned checkout" nativo. Si no, el cliente recibe dos recordatorios del mismo carrito. |
El workflow
- Trigger — Customer abandons checkout.
- Condition —
abandonment.customer.defaultPhoneNumberis not empty. Un checkout sin teléfono no se puede enviar: cortarlo acá evita gastar la llamada en un422. - Action — Send HTTP request, con método
POST, la URLhttps://api.ya.onl/v1/template-messagesy dos headers:X-API-Keycon tu key yContent-Type: application/json.
El cuerpo
{
"event_id": "CART-{{ abandonment.id | split: '/' | last }}",
"phone": "{{ abandonment.customer.defaultPhoneNumber.phoneNumber }}",
"template": { "name": "TU_PLANTILLA", "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 | Qué hace esa línea |
|---|---|
event_id |
Recorta el GID de Shopify (gid://shopify/Abandonment/774830424) a su último segmento, que respeta el charset del campo, y el prefijo CART- cubre el mínimo de 8 caracteres y da la idempotencia: si Flow reintenta, el cliente no recibe dos mensajes. |
phone |
defaultPhoneNumber.phoneNumber ya viene en E.164 (+51987654321), que es exactamente lo que exige el campo. |
template |
Objeto con el nombre y el idioma de tu plantilla, tal como están aprobados en Meta: reemplaza TU_PLANTILLA y ajusta language. |
variables |
Por posición, en el orden de tu plantilla: "1" el nombre, "2" los primeros tres productos. Ajusta la cantidad a la que la plantilla exige — que falte una es un 422. El replace saca las comillas del título, que romperían el JSON. |
occurred_at |
abandonment.createdAt ya trae offset, y es lo que activa la ventana de frescura: un abandono viejo vuelve discarded con motivo stale en vez de enviarse tarde. |
La receta es genérica. El contrato es el mismo desde cualquier plataforma capaz de
hacer un POST — otro ecommerce, tu propio backend o un automatizador tipo Zapier o
Make. Shopify Flow es sólo el ejemplo guiado, porque resuelve el disparo del abandono sin
escribir código.
Verificar que salió
curl https://api.ya.onl/v1/template-messages/CART-774830424 \
-H "X-API-Key: yv_live_v1_tu_api_key"Con la misma key —siempre que tenga outbound:read— y el mismo event_id que armó Flow.
Un 404 significa que la llamada nunca llegó: revisa el historial de ejecuciones del
workflow en Flow.
