---
name: shopify-costo-envios
description: "Solo lectura: compara lo que les cobras a los clientes por envío con el costo real de envío registrado en los pedidos, por transportadora y método. Úsala cuando quieras saber si estás subsidiando envíos o cobrando de más."
---

## Propósito
Compara el monto de envío cobrado a los clientes con el costo real de envío registrado en los pedidos, desglosado por transportadora y método de envío. Identifica dónde estás subsidiando el envío (cobras menos de lo que cuesta) o cobrando de más. Solo lectura, sin mutaciones.

## Requisitos
- Sesión autenticada de Shopify CLI: `shopify store auth --store <tu-tienda>.myshopify.com --scopes read_orders`
- Las consultas se ejecutan con `shopify store execute`.
- Permisos (scopes) de API: `read_orders`
- Los costos reales de envío solo están disponibles si se registraron por la API de Admin de Shopify o con envíos calculados por la transportadora; los pedidos creados a mano pueden no tener datos de costo.

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | string | sí | — | Dominio de la tienda (p. ej., mitienda.myshopify.com) |
| days_back | integer | no | 30 | Ventana de días hacia atrás |
| format | string | no | human | Formato de salida: `human` o `json` |

## Seguridad

> ℹ️ Skill de solo lectura: no ejecuta mutaciones. Puedes usarla en cualquier momento sin riesgo.

## Pasos

1. **OPERACIÓN:** `orders` — consulta
   **Entradas:** `query: "financial_status:paid created_at:>='<NOW - days_back days>'"`, `first: 250`, campos `shippingLines { title, discountedPriceSet, originalPriceSet, carrierIdentifier }`, cursor de paginación
   **Resultado esperado:** Pedidos con el detalle de sus líneas de envío; pagina hasta `hasNextPage: false`

2. Para cada línea de envío: registra la transportadora (desde `title` o `carrierIdentifier`), el monto cobrado (`discountedPriceSet`) y el costo real si está disponible

3. Agrupa por transportadora o método; calcula el total cobrado, el costo total y el subsidio o sobrecobro neto

## Operaciones GraphQL

```graphql
# orders:query — validada con api_version 2025-01
query ShippingCostAnalysis($query: String!, $after: String) {
  orders(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        name
        createdAt
        totalShippingPriceSet {
          shopMoney {
            amount
            currencyCode
          }
        }
        shippingLines(first: 5) {
          edges {
            node {
              id
              title
              carrierIdentifier
              originalPriceSet {
                shopMoney {
                  amount
                  currencyCode
                }
              }
              discountedPriceSet {
                shopMoney {
                  amount
                  currencyCode
                }
              }
            }
          }
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

## Seguimiento de la sesión

**Claude DEBE mostrar lo siguiente en cada etapa. Es obligatorio.**

**Al iniciar**, muestra:
```
╔═══════════════════════════════════════════════════╗
║  SKILL: Lo que cobras vs. lo que pagas en envíos  ║
║  Tienda: <dominio de la tienda>                   ║
║  Inicio: <AAAA-MM-DD HH:MM UTC>                   ║
╚═══════════════════════════════════════════════════╝
```

**Después de cada paso**, muestra:
```
[N/TOTAL] <CONSULTA|MUTACIÓN>  <OperationName>
          → Parámetros: <resumen breve de las entradas clave>
          → Resultado: <cantidad o desenlace>
```

**Al terminar**, muestra:

Para `format: human` (predeterminado):
```
══════════════════════════════════════════════
ANÁLISIS DE COSTOS DE ENVÍO  (<days_back> días)
  Pedidos analizados:              <n>
  Total cobrado a los clientes:    <monto>
  Pedidos con envío gratis:        <n>

  Por transportadora/método:
    "Envío estándar"   Pedidos: <n>  Cobrado: <monto>  Promedio: <monto>
    "Express"          Pedidos: <n>  Cobrado: <monto>  Promedio: <monto>
  Archivo: shipping_cost_<fecha>.csv
══════════════════════════════════════════════
```

Los montos van en la moneda de la tienda.

Para `format: json`, muestra:
```json
{
  "skill": "shopify-costo-envios",
  "store": "<dominio>",
  "period_days": 30,
  "orders_analyzed": 0,
  "total_shipping_charged": 0,
  "free_shipping_order_count": 0,
  "currency": "<moneda de la tienda>",
  "by_method": [],
  "output_file": "shipping_cost_<fecha>.csv"
}
```

## Formato de salida
Archivo CSV `shipping_cost_<AAAA-MM-DD>.csv` con las columnas:
`order_name`, `shipping_method`, `carrier`, `charged_amount`, `original_price`, `discount_applied`, `currency`

## Manejo de errores
| Error | Causa | Solución |
|-------|-------|----------|
| `THROTTLED` | Se superó el límite de solicitudes de la API | Espera 2 segundos y reintenta hasta 3 veces |
| No hay líneas de envío | Productos digitales o tienda con envío gratis | Reporta 0 en ingresos por envío |
| Falta el identificador de la transportadora | Métodos de envío personalizados o manuales | Usa `title` como nombre de la transportadora |

## Buenas prácticas
- Los pedidos con envío gratis muestran 0 cobrado, pero el costo real de la transportadora es tu subsidio: conocerlo por transportadora te ayuda a decidir el monto mínimo para envío gratis.
- La diferencia entre `originalPriceSet` y `discountedPriceSet` representa los descuentos de envío aplicados a los clientes; sirve para entender el costo total del subsidio de envío.
- Combínala con `shopify-ticket-promedio` para evaluar si tu monto mínimo para envío gratis está logrando el aumento esperado del ticket promedio.
- Para conciliar el costo real con las transportadoras, crúzalo con sus facturas: la API de Shopify solo guarda lo que se cobró a los clientes, no lo que se pagó a las transportadoras, a menos que tu integración con la transportadora registre esos costos.
