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

# Receta: Shopify (Flow)

> Dispara el envío de plantilla desde Shopify Flow, sin código y sin un servidor propio.

# Receta: Shopify (Flow)

Esta es la receta guiada del contrato genérico de
[Mensajes de Plantilla](/outbound/cart-abandonment): 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](/authentication). |
| **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

1. **Trigger** — *Customer abandons checkout*.
2. **Condition** — `abandonment.customer.defaultPhoneNumber` **is not empty**. Un checkout
   sin teléfono no se puede enviar: cortarlo acá evita gastar la llamada en un `422`.
3. **Action** — *Send HTTP request*, con método `POST`, la URL
   `https://api.ya.onl/v1/template-messages` y dos headers: `X-API-Key` con tu key y
   `Content-Type: application/json`.

## El cuerpo

```json theme={null}
{
  "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. |

<Note>
  **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.
</Note>

## Verificar que salió

```bash theme={null}
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.


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