En esta guía te explico el escenario que montamos en Make para eso: la elección del disparador, el mapeo de campos, los productos del pedido, cómo evitar duplicados, reembolsos y cancelaciones, y un aviso en Slack al final. Puedes seguirla paso a paso aunque sea tu primer escenario de verdad.
Primero decide: ¿una fila por pedido o una por producto?
Respóndelo antes de abrir Make, porque cambia toda la hoja.
- Una fila por pedido es lo tuyo si te importan las ventas, los clientes y el estado del pedido. El pedido #1042 es una fila, con los productos juntos en una celda «Artículos».
- Una fila por producto es lo tuyo si te importan los productos: planificar stock, reponer con proveedores, ver qué SKU se vende con cuál. El pedido #1042 con tres productos se convierte en tres filas con el mismo número de pedido.
Si necesitas las dos cosas, usa dos pestañas en la misma hoja y aliméntalas desde el mismo escenario. No intentes que una sola pestaña haga ambos trabajos.
Paso 1: Elige el disparador: Watch orders o Watch events
La app de Shopify en Make te ofrece dos formas realistas de empezar.
Shopify > Watch orders es un disparador por polling. Make consulta tu tienda según la programación del escenario (cada 15 minutos, cada hora, lo que tú pongas) y trae los pedidos que aún no ha visto. Es lo más fácil de configurar y suficiente para la mayoría de tiendas pequeñas. Dos cosas que debes saber:
- No es instantáneo. Un pedido hecho a las 10:01 puede llegar a la hoja a las 10:15.
- Cada consulta programada gasta credits, aunque no haya pedidos nuevos. Una programación cada 5 minutos en una tienda tranquila quema credits en ejecuciones vacías.
Shopify > Watch events es el disparador instantáneo, basado en webhooks. Shopify envía el pedido a Make en el momento en que ocurre el evento. Eliges un topic de webhook de Shopify como orders/create, orders/paid, orders/cancelled o refunds/create (Make puede listarlos en el formato enum de Shopify, por ejemplo ORDERS_CREATE). Sin consultas vacías, sin esperas. La contrapartida: cada disparador escucha un solo topic, y si Shopify envía el mismo evento dos veces (reintenta cuando la entrega no se confirma), necesitas tu propia comprobación de duplicados. Lo vemos en el paso 5.
Lo que usamos por defecto: Watch events con orders/paid si la hoja es para contabilidad, orders/create si es para preparar envíos. Watch orders solo cuando el cliente quiere lo más simple posible y el retraso le da igual.
Un detalle de Watch orders: recuerda dónde se quedó. Si haces clic dos veces en «Run once» mientras pruebas, la segunda ejecución a menudo no devuelve nada. Haz clic derecho en el módulo y elige desde dónde empezar, o crea un pedido de prueba nuevo.
Paso 2: Prepara la hoja
Crea la fila de encabezados antes de configurar el módulo de Google Sheets, para que Make pueda leer las columnas. Una estructura que aguanta bien para registrar pedidos:
| Columna | Campo de origen |
|---|---|
| ID de pedido | id |
| Número de pedido | name (p. ej. #1042) |
| Fecha | created_at |
| Email del cliente | email |
| Total | total_price |
| Moneda | currency |
| Estado de pago | financial_status |
| Estado de envío | fulfillment_status |
| Artículos | con una fórmula (abajo) |
| Estado | lo escribe el escenario de reembolsos/cancelaciones |
Pon el ID de pedido en la columna A. Es la clave de la que depende todo lo demás. El número de pedido (#1042) queda más bonito, pero Shopify usa el ID numérico en los datos de reembolsos y cancelaciones. Los campos de origen son los nombres del webhook de pedidos de Shopify, que es lo que entrega Watch events. Watch orders puede llamar algunos de otra forma, así que elígelos en el panel de mapeo.
Paso 3: Mapea los campos (una fila por pedido)
Añade Google Sheets > Add a Row, elige la hoja y la pestaña, pon «Table contains headers» en Yes y las columnas aparecerán como campos.
La mayoría se mapean directamente. Algunos necesitan una función:
- Fecha:
formatDate(1.created_at; "YYYY-MM-DD HH:mm"; "Europe/Madrid"). Cambia la zona horaria por la de tu tienda. Las fechas ISO en bruto se ordenan bien, pero cuestan de leer. - Total: Shopify envía los precios como texto. Si quieres que la hoja los sume, usa
parseNumber(1.total_price; ".")o da formato de número a la columna en Sheets. - Artículos:
join(map(1.line_items; "title"); ", ")te da «Camisa de lino, Bolsa de lona» en una celda. ¿Quieres cantidades? Usa un Iterator y un Tools > Text aggregator con{{quantity}} × {{title}}y mapea el texto agregado. - Estado de envío viene vacío en pedidos sin enviar. Envuélvelo:
ifempty(1.fulfillment_status; "unfulfilled").
Ejecuta el escenario una vez con un pedido de prueba real y revisa cada columna.
Paso 4: Una fila por producto con Iterator
Para registrar a nivel de producto, añade Flow Control > Iterator entre el disparador y el módulo de Sheets, y mapea line_items[] en su campo Array. Cada producto del pedido se convierte en un bundle propio.
En Add a Row, mapea los campos del pedido desde el disparador (número, fecha, email) y los del producto desde el Iterator (title, variant_title, sku, quantity, price). Añade una columna ID de línea y mapea el id del Iterator. ID de pedido + ID de línea es tu clave única aquí.
Sobre los credits: cada bundle que pasa por Add a Row cuesta credits, así que un pedido con 10 productos son 10 ejecuciones de ese módulo. Si tus pedidos son grandes, sustituye Add a Row por un Array aggregator (Source module: el Iterator) seguido de Google Sheets > Bulk Add Rows (advanced). Una escritura por pedido en lugar de una por producto, y será mucho más difícil que choques con los límites de Google durante unas rebajas.
Paso 5: Evita filas duplicadas (busca antes de añadir)
Los duplicados vienen de tres sitios: reintentos del webhook, alguien que vuelve a ejecutar el escenario y un Watch orders reiniciado a un punto anterior. La solución es la misma: comprueba antes de escribir.
Lo obvio es usar Google Sheets > Search Rows filtrando por ID de pedido y añadir la fila solo si no encuentra nada. El problema: cuando Search Rows no encuentra nada, no devuelve nada, y los módulos siguientes simplemente no se ejecutan. Tu rama de «añadir si no existe» nunca se dispara.
Dos formas de resolverlo:
- El truco del agregador. Pon un Array aggregator justo después de Search Rows (Source module: Search Rows). El agregador devuelve un bundle aunque la búsqueda esté vacía. Añade un Router: la ruta 1 con el filtro
length(Array) = 0→ Add a Row; la ruta 2 conlength(Array) > 0→ Update a Row (con el número de fila del array) o simplemente termina. - Data store. Crea un data store en Make con el ID de pedido como clave. Antes de escribir, usa Data store > Check the existence of a record; devuelve un sí/no por el que puedes filtrar. Después de escribir la fila, Add/replace a record. Es más rápido que buscar en una hoja grande y no depende de que nadie toque la columna A.
En modo por producto, busca por ID de pedido + ID de línea, o comprueba el pedido una vez antes del Iterator y sáltate el pedido entero si ya está.
Paso 6: Gestiona reembolsos y cancelaciones
No borres filas cuando se reembolsa un pedido. Las filas borradas rompen totales que alguien ya ha reportado. Actualiza la fila.
Monta un segundo escenario, pequeño:
- Shopify > Watch events con el topic
refunds/create(y una copia conorders/cancelled). - Google Sheets > Search Rows por ID de pedido. En los reembolsos, el ID está en el campo
order_id; en las cancelaciones, es eliddel propio pedido. - Google Sheets > Update a Row con el número de fila encontrado: pon Estado en «Reembolsado», «Reembolso parcial» o «Cancelado» y escribe el importe reembolsado en su propia columna. Los reembolsos parciales son habituales, así que no sobrescribas el total original.
Si un pedido cancelado nunca se registró (cancelado antes del pago mientras disparas con orders/paid), la búsqueda no encuentra nada y el escenario termina sin ruido. Normalmente es justo lo que quieres.
Paso 7: Añade un aviso en Slack
Añade Slack > Create a Message al final del escenario principal. No avises de cada pedido: la gente silencia ese canal en una semana. Pon un filtro en la ruta:
- total del pedido por encima del umbral que elijas,
- pedidos con nota del cliente (
noteno está vacío), - o un producto o método de envío concreto.
Un mensaje útil: Nuevo pedido {{1.name}}, {{1.total_price}} {{1.currency}}, {{1.email}} más un enlace al pedido en el panel de Shopify.
Gestión de errores que de verdad ayuda
Clic derecho en un módulo y Add error handler:
- En el módulo de Google Sheets, usa Retry (antes Break) con reintentos automáticos. Google devuelve errores de límite de peticiones en horas punta, y un reintento unos minutos después casi siempre funciona.
- En el módulo de Slack, usa Skip (antes Ignore). Un aviso fallido no debería marcar la ejecución como error si la fila ya se escribió.
- Resume viene bien cuando una consulta falla y prefieres escribir un valor por defecto («desconocido») en lugar de parar.
- Commit y Rollback solo importan en módulos que admiten transacciones, como los data stores. Las escrituras en Google Sheets no se pueden deshacer: un motivo más para comprobar duplicados antes.
Activa también Store incomplete executions en los ajustes del escenario, para que un pedido fallido te espere en lugar de desaparecer; Retry lo necesita. Otro motivo para gestionar errores: por defecto, Make desactiva un escenario tras 3 errores seguidos, y uno que empieza con un disparador instantáneo como Watch events, tras el primero.
Checklist rápida de pruebas
- Haz un pedido de prueba con dos productos distintos y revisa las dos pestañas.
- Vuelve a ejecutar el mismo bundle y confirma que no aparece una segunda fila.
- Reembolsa un producto y comprueba que se actualizan las columnas de estado y reembolso.
- Cancela un pedido sin pagar y confirma que no se rompe nada.
- Revisa el historial del escenario al cabo de un día para ver cuántos credits gastas.