Connect

Resumir ventas de Shopify

Ventas de Shopify de un período, por moneda.

Tool IDshopify.ventas.resumir
Nombre MCPshopify__ventas__resumir
Conectorshopify
Planoaction
Scope (permiso)shopify:pedidos
Authconnection_credentials
Versión1
Sensibleno
Deprecadono
ComportamientoreadOnly=true, destructive=false, idempotent=true, openWorld=true

Requiere conexión. Indica cuál en cada llamada: header X-Connect-Connection en REST y campo connectionId en el execute de MCP. No hay resolución implícita, ni siquiera con una sola conexión activa: la conexión es la empresa. El id sale de conexiones.estado.consultar.

Qué hace

Suma con decimales exactos los pedidos creados en el rango: subtotal, descuentos, impuestos, envío, bruto, reembolsado y neto (bruto − reembolsado). Excluye pedidos cancelados y de prueba. cobertura.completa es true solo si se leyeron todos los pedidos del rango y el historial alcanza; si no, cobertura.motivos dice por qué y, con mas_paginas, sigue con cobertura.siguientePagina y suma tú los resultados. Son pedidos, no cobros liquidados. Connect consulta Shopify en vivo y no guarda nada: cada llamada lee la tienda de la conexión.

Entrada

CampoTipoRequeridoDescripción
desdestring `^\d4-\d2-\d2T\d2:\d2(?::\d2(?:.\d9)?)?(?:Z[+-]\d2:\d2)$`sí
hastastring `^\d4-\d2-\d2T\d2:\d2(?::\d2(?:.\d9)?)?(?:Z[+-]\d2:\d2)$`sí
paginastringnoEl valor cobertura.siguientePagina de una respuesta anterior con el MISMO rango.
JSON Schema de entrada
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "desde": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,9})?)?(?:Z|[+-]\\d{2}:\\d{2})$",
      "description": "Pedidos creados desde este instante (inclusive). Instante ISO 8601 con zona, por ejemplo `2026-10-01T00:00:00-03:00`."
    },
    "hasta": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,9})?)?(?:Z|[+-]\\d{2}:\\d{2})$",
      "description": "Pedidos creados antes de este instante (exclusive). Instante ISO 8601 con zona, por ejemplo `2026-10-01T00:00:00-03:00`."
    },
    "pagina": {
      "description": "El valor `cobertura.siguientePagina` de una respuesta anterior con el MISMO rango.",
      "type": "string",
      "minLength": 1,
      "maxLength": 4096
    }
  },
  "required": [
    "desde",
    "hasta"
  ],
  "additionalProperties": false
}

Ejemplo

curl
curl -X POST https://connect.emisso.ai/api/v1/tools/shopify.ventas.resumir/execute \
  -H "Authorization: Bearer connect_sk_…" \
  -H "X-Connect-Connection: conn_9tKfR2mQx4Vb" \
  -H "Content-Type: application/json" \
  -d '{"input":{"desde":"2026-10-01T00:00:00-03:00","hasta":"2026-10-16T00:00:00-03:00"}}'
MCP · meta-tool execute
{
  "tool": "shopify.ventas.resumir",
  "params": {
    "desde": "2026-10-01T00:00:00-03:00",
    "hasta": "2026-10-16T00:00:00-03:00"
  },
  "connectionId": "conn_9tKfR2mQx4Vb"
}

Salida esperada (200):

{
  "data": {
    "desde": "2026-10-01T03:00:00.000Z",
    "hasta": "2026-10-16T03:00:00.000Z",
    "moneda": "CLP",
    "pedidos": 2,
    "cancelados": 1,
    "totales": {
      "subtotal": "41970.0",
      "descuentos": "2000.0",
      "impuestos": "6701.0",
      "envio": "3990.0",
      "bruto": "45960.0",
      "reembolsado": "12990.0",
      "neto": "32970.0",
      "actual": "32970.0"
    },
    "cobertura": {
      "completa": true,
      "motivos": [],
      "siguientePagina": null,
      "paginasLeidas": 1
    },
    "historial": {
      "completo": false,
      "diasDisponibles": 60
    }
  },
  "meta": {
    "request_id": "req_…",
    "tool_id": "shopify.ventas.resumir",
    "plane": "action",
    "latency_ms": 7410,
    "audit_status": "recorded"
  }
}

Si cobertura.completa es false, no informes los totales como las ventas del período.

Salida

CampoTipoRequeridoDescripción
desdestringsíInicio del rango pedido, en UTC (Z).
hastastringsíFin del rango pedido, en UTC (Z).
monedastring ^[A-Z]{3}$síMoneda de la tienda: la de todos los totales.
pedidosenterosíPedidos no cancelados ni de prueba que suman en esta respuesta.
canceladosenterosíPedidos cancelados del rango leído; no suman.
totalesobjetosíSumas exactas como texto decimal, en la moneda de la tienda.
totales.subtotalstring ^-?[0-9]{1,19}(?:\.[0-9]{1,9})?$síSuma de subtotales (después de descuentos).
totales.descuentosstring ^-?[0-9]{1,19}(?:\.[0-9]{1,9})?$síSuma de descuentos. Informativa: ya está restada del subtotal y del bruto.
totales.impuestosstring ^-?[0-9]{1,19}(?:\.[0-9]{1,9})?$síSuma de impuestos.
totales.enviostring ^-?[0-9]{1,19}(?:\.[0-9]{1,9})?$síSuma de envíos.
totales.brutostring ^-?[0-9]{1,19}(?:\.[0-9]{1,9})?$síSuma de los totales de los pedidos antes de devoluciones (total).
totales.reembolsadostring ^-?[0-9]{1,19}(?:\.[0-9]{1,9})?$síSuma de lo reembolsado de esos pedidos, a la fecha de la consulta.
totales.netostring ^-?[0-9]{1,19}(?:\.[0-9]{1,9})?$síbruto − reembolsado. Lo reembolsado se descuenta una sola vez.
totales.actualstring ^-?[0-9]{1,19}(?:\.[0-9]{1,9})?$síSuma de los totales actuales (currentTotalPriceSet): ya descuenta devoluciones y quitas de líneas. Es otra medida que neto; no le restes reembolsado.
coberturaobjetosíQué cubren estas sumas.
cobertura.completabooleanosítrue solo si ESTA respuesta sumó TODOS los pedidos del rango que la conexión puede ver y el historial alcanza. Una respuesta pedida con pagina nunca es completa por sí sola: suma solo el tramo desde ese cursor.
cobertura.motivoslista de "mas_paginas" · "tope_paginas" · "tiempo_agotado" · "cupo_shopify" · "continuacion" · "historial_limitado" · …síPor qué no es completa: mas_paginas (quedan pedidos; sigue con siguientePagina y suma tú los resultados), tope_paginas, tiempo_agotado o cupo_shopify (por qué paró esta llamada antes de terminar; siempre van con mas_paginas), continuacion (se pidió con pagina: los totales son solo de ese tramo; la serie está completa cuando la última respuesta ya no trae mas_paginas ni motivos de historial), historial_limitado (el rango empieza antes de los 60 días visibles sin read_all_orders) o historial_desconocido (Shopify no informó los permisos).
cobertura.siguientePaginastringnullsí
cobertura.paginasLeidasenterosíPáginas de Shopify leídas en esta llamada.
historialobjetosíCuánto historial de pedidos alcanza esta conexión según los permisos concedidos en Shopify.
historial.completobooleanonullsí
historial.diasDisponiblesenteronullsí
JSON Schema de salida
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "desde": {
      "type": "string",
      "description": "Inicio del rango pedido, en UTC (Z)."
    },
    "hasta": {
      "type": "string",
      "description": "Fin del rango pedido, en UTC (Z)."
    },
    "moneda": {
      "type": "string",
      "pattern": "^[A-Z]{3}$",
      "description": "Moneda de la tienda: la de todos los totales."
    },
    "pedidos": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991,
      "description": "Pedidos no cancelados ni de prueba que suman en esta respuesta."
    },
    "cancelados": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991,
      "description": "Pedidos cancelados del rango leído; no suman."
    },
    "totales": {
      "type": "object",
      "properties": {
        "subtotal": {
          "type": "string",
          "pattern": "^-?[0-9]{1,19}(?:\\.[0-9]{1,9})?$",
          "description": "Suma de subtotales (después de descuentos)."
        },
        "descuentos": {
          "type": "string",
          "pattern": "^-?[0-9]{1,19}(?:\\.[0-9]{1,9})?$",
          "description": "Suma de descuentos. Informativa: ya está restada del subtotal y del bruto."
        },
        "impuestos": {
          "type": "string",
          "pattern": "^-?[0-9]{1,19}(?:\\.[0-9]{1,9})?$",
          "description": "Suma de impuestos."
        },
        "envio": {
          "type": "string",
          "pattern": "^-?[0-9]{1,19}(?:\\.[0-9]{1,9})?$",
          "description": "Suma de envíos."
        },
        "bruto": {
          "type": "string",
          "pattern": "^-?[0-9]{1,19}(?:\\.[0-9]{1,9})?$",
          "description": "Suma de los totales de los pedidos antes de devoluciones (`total`)."
        },
        "reembolsado": {
          "type": "string",
          "pattern": "^-?[0-9]{1,19}(?:\\.[0-9]{1,9})?$",
          "description": "Suma de lo reembolsado de esos pedidos, a la fecha de la consulta."
        },
        "neto": {
          "type": "string",
          "pattern": "^-?[0-9]{1,19}(?:\\.[0-9]{1,9})?$",
          "description": "bruto − reembolsado. Lo reembolsado se descuenta una sola vez."
        },
        "actual": {
          "type": "string",
          "pattern": "^-?[0-9]{1,19}(?:\\.[0-9]{1,9})?$",
          "description": "Suma de los totales actuales (`currentTotalPriceSet`): ya descuenta devoluciones y quitas de líneas. Es otra medida que `neto`; no le restes `reembolsado`."
        }
      },
      "required": [
        "subtotal",
        "descuentos",
        "impuestos",
        "envio",
        "bruto",
        "reembolsado",
        "neto",
        "actual"
      ],
      "additionalProperties": false,
      "description": "Sumas exactas como texto decimal, en la moneda de la tienda."
    },
    "cobertura": {
      "type": "object",
      "properties": {
        "completa": {
          "type": "boolean",
          "description": "true solo si ESTA respuesta sumó TODOS los pedidos del rango que la conexión puede ver y el historial alcanza. Una respuesta pedida con `pagina` nunca es completa por sí sola: suma solo el tramo desde ese cursor."
        },
        "motivos": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "mas_paginas",
              "tope_paginas",
              "tiempo_agotado",
              "cupo_shopify",
              "continuacion",
              "historial_limitado",
              "historial_desconocido"
            ]
          },
          "description": "Por qué no es completa: `mas_paginas` (quedan pedidos; sigue con `siguientePagina` y suma tú los resultados), `tope_paginas`, `tiempo_agotado` o `cupo_shopify` (por qué paró esta llamada antes de terminar; siempre van con `mas_paginas`), `continuacion` (se pidió con `pagina`: los totales son solo de ese tramo; la serie está completa cuando la última respuesta ya no trae `mas_paginas` ni motivos de historial), `historial_limitado` (el rango empieza antes de los 60 días visibles sin `read_all_orders`) o `historial_desconocido` (Shopify no informó los permisos)."
        },
        "siguientePagina": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 4096
            },
            {
              "type": "null"
            }
          ],
          "description": "Pásalo en `pagina` para sumar el resto del rango; null si no quedan pedidos."
        },
        "paginasLeidas": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991,
          "description": "Páginas de Shopify leídas en esta llamada."
        }
      },
      "required": [
        "completa",
        "motivos",
        "siguientePagina",
        "paginasLeidas"
      ],
      "additionalProperties": false,
      "description": "Qué cubren estas sumas."
    },
    "historial": {
      "type": "object",
      "properties": {
        "completo": {
          "anyOf": [
            {
              "type": "boolean"
            },
            {
              "type": "null"
            }
          ],
          "description": "true si la tienda concedió `read_all_orders` y se ve todo el historial; false si solo se ven los últimos 60 días; null si Shopify no informó los permisos."
        },
        "diasDisponibles": {
          "anyOf": [
            {
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            },
            {
              "type": "null"
            }
          ],
          "description": "60 cuando el historial está limitado; null en otro caso."
        }
      },
      "required": [
        "completo",
        "diasDisponibles"
      ],
      "additionalProperties": false,
      "description": "Cuánto historial de pedidos alcanza esta conexión según los permisos concedidos en Shopify."
    }
  },
  "required": [
    "desde",
    "hasta",
    "moneda",
    "pedidos",
    "cancelados",
    "totales",
    "cobertura",
    "historial"
  ],
  "additionalProperties": false
}

Errores de esta tool

CódigoHTTPReintentableQué hacer
connection_disabled403noReactívala en /connections o usa otra conexión del mismo sistema.
connection_not_found404noUsa uno de los connectionId que lista el error, o revisa la conexión en /connections. No hace falta reactivar nada.
connection_credential_required428noCrea un enlace con conexiones.enlace.crear (modo reconectar si la conexión ya existe) y pide a la persona que entregue la credencial de nuevo. No reintentes con la credencial anterior.
connection_busy409síEspera unos segundos y reintenta. Es una espera transitoria: no necesitas volver a conectar ni ingresar la credencial otra vez.
upstream_error502síReintenta más tarde. Si persiste, el problema está en el sistema externo, no en tu integración.
timeout504síReintenta. Para sincronizaciones largas usa la vía asíncrona y consulta el estado del trabajo.
connector_onboarding_required428noLee el mensaje: dice qué falta. Se completa en el portal de ese sistema, no en Connect, y después la llamada funciona sin cambios.
connection_scope_not_enabled403noPide a un owner/admin que habilite el scope en /connections para esa conexión, o usa otra que ya lo tenga activo. Cambiar la credencial del actor no resuelve este error.
rate_limited429síEspera y reintenta con backoff exponencial.
upstream_unexpected_response502noNo reintentes: la respuesta es determinista. Repórtalo con el request_id para que actualicemos el conector.
external_resource_not_found404noVerifica el identificador con la tool de búsqueda del mismo sistema. Reintentar con el mismo identificador da el mismo resultado.

Toda llamada puede devolver además los códigos transversales (validation_error, unauthorized, scope_not_granted, rate_limited, entre otros): el detalle vive en el catálogo de errores.

En esta página