---
name: shopify-patrones-reembolsos-parciales
description: "Solo lectura: encuentra pedidos con varios reembolsos parciales o con una parte reembolsada inusualmente alta, que pueden indicar fraude, quejas crónicas o fallas del proceso. Úsala para revisar reembolsos sospechosos antes de actuar."
---

## Propósito
Revisa los pedidos recientes, extrae cada reembolso y marca los pedidos que tienen (a) dos o más reembolsos parciales, o (b) una proporción entre lo reembolsado y el total del pedido por encima de un umbral configurable. Estos patrones suelen indicar fraude amistoso (reclamos que se van sumando de a poco), un cliente recurrente insatisfecho o una falla en el proceso del equipo (reembolsar por partes en lugar de dar un solo crédito completo). Solo lectura: no ejecuta 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 de la API: `read_orders`

## Parámetros

| Parámetro | Tipo | Obligatorio | Predeterminado | Descripción |
|-----------|------|-------------|----------------|-------------|
| store | texto | sí | — | Dominio de la tienda (p. ej., tu-tienda.myshopify.com) |
| days_back | entero | no | 90 | Ventana de días hacia atrás de los pedidos por analizar |
| min_partials | entero | no | 2 | Mínimo de reembolsos parciales para marcar un pedido |
| ratio_threshold | decimal | no | 0.5 | Marca los pedidos en los que total reembolsado / total del pedido supera esta proporción (sigue siendo parcial, es decir, menor que 1.0) |
| min_order_value | decimal | no | 25 | Omite los pedidos de bajo valor, por debajo de este monto |
| format | texto | no | human | Formato de salida: `human` o `json` |

## Seguridad

> ℹ️ Skill de solo lectura: no ejecuta mutaciones. Puedes correrla en cualquier momento. Los pedidos marcados son solo una alerta: confírmalos con las notas del reembolso y el historial del cliente antes de tomar medidas contra la cuenta de un cliente.

## Pasos

1. **OPERACIÓN:** `orders` — consulta
   **Entradas:** `query: "created_at:>='<HOY - days_back días>' financial_status:partially_refunded"`, `first: 250`; selecciona `refunds { id, createdAt, totalRefundedSet, note }`, `totalPriceSet`, `customer` y el cursor de paginación
   **Resultado esperado:** Todos los pedidos con reembolso parcial y su historial completo de reembolsos; pagina hasta que `hasNextPage: false`

2. Para cada pedido, cuenta los reembolsos y suma `totalRefundedSet.shopMoney.amount`. Calcula `ratio = total_refunded / order_total`.

3. Marca los pedidos que cumplan cualquiera de las dos condiciones: `refund_count >= min_partials` O `ratio >= ratio_threshold` (y `ratio < 1.0`, para excluir los pedidos reembolsados por completo).

4. Agrupa los pedidos marcados por `customer.id` para detectar clientes reincidentes (más de un pedido marcado en la ventana).

## Operaciones GraphQL

```graphql
# orders:query — validada con api_version 2025-01
query PartialRefundPatterns($query: String!, $after: String) {
  orders(first: 250, after: $after, query: $query) {
    edges {
      node {
        id
        name
        createdAt
        displayFinancialStatus
        totalPriceSet {
          shopMoney {
            amount
            currencyCode
          }
        }
        totalRefundedSet {
          shopMoney {
            amount
            currencyCode
          }
        }
        refunds {
          id
          createdAt
          note
          totalRefundedSet {
            shopMoney {
              amount
              currencyCode
            }
          }
          refundLineItems(first: 50) {
            edges {
              node {
                quantity
                lineItem {
                  id
                  title
                  sku
                }
              }
            }
          }
        }
        customer {
          id
          displayName
          defaultEmailAddress {
            emailAddress
          }
          numberOfOrders
        }
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}
```

## Seguimiento de la sesión

**Claude DEBE mostrar la siguiente salida en cada etapa. Es obligatorio.**

**Al iniciar**, muestra:
```
╔══════════════════════════════════════════════╗
║  SKILL: Patrones de reembolsos parciales     ║
║  Tienda: <dominio de la tienda>              ║
║  Inicio: <YYYY-MM-DD HH:MM UTC>              ║
╚══════════════════════════════════════════════╝
```

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

**Al terminar**, muestra:

Para `format: human` (predeterminado):
```
══════════════════════════════════════════════
REPORTE DE PATRONES DE REEMBOLSOS PARCIALES  (<days_back> días)
  Pedidos con reembolso parcial:      <n>
  Marcados (varios reembolsos):       <n>
  Marcados (proporción alta):         <n>
  Clientes marcados más de una vez:   <n>

  Clientes marcados con mayor monto:
    <cliente>  Pedidos: <n>  Reembolsado: $<n>  Proporción: <pct>%
  Archivo: partial_refund_patterns_<fecha>.csv
══════════════════════════════════════════════
```

Para `format: json`, muestra:
```json
{
  "skill": "shopify-patrones-reembolsos-parciales",
  "store": "<dominio>",
  "period_days": 90,
  "partially_refunded_orders": 0,
  "flagged_multi_refund": 0,
  "flagged_high_ratio": 0,
  "repeat_flagged_customers": 0,
  "output_file": "partial_refund_patterns_<fecha>.csv"
}
```

## Formato de salida
Archivo CSV `partial_refund_patterns_<YYYY-MM-DD>.csv` con las columnas:
`order_name`, `order_id`, `customer_email`, `customer_lifetime_orders`, `order_total`, `total_refunded`, `refund_ratio`, `refund_count`, `flag_reason`, `first_refund_at`, `last_refund_at`

## 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 |
| El pedido tiene un reembolso, pero `totalRefundedSet` es cero | Reembolso registrado por 0 (solo una nota, no se movió dinero) | Exclúyelo del cálculo de la proporción, pero cuenta el reembolso |
| El cliente es nulo (pedido como invitado) | No hay cliente asociado | Agrupa por correo en lugar de por ID de cliente |
| No hay pedidos con reembolso parcial | Ventana limpia | Termina con el resumen: 0 marcados |

## Buenas prácticas
- Combina `min_partials: 2` y `ratio_threshold: 0.5` para obtener la señal más útil: un solo reembolso parcial pequeño suele ser legítimo.
- Ordena por `refund_ratio` de mayor a menor: las proporciones altas en pedidos de alto valor son la señal de fraude más fuerte.
- Un cliente marcado varias veces con `numberOfOrders > 5` suele ser alguien que se queja seguido, no un estafador: revisa las notas del reembolso antes de actuar.
- Usa esta skill cada trimestre junto con `shopify-reporte-riesgo-pedidos` para detectar el fraude posterior a la compra que los filtros antifraude no atrapan en el checkout.
- El contenido de la `note` del reembolso suele revelar el patrón (p. ej., "falta un artículo" repetido tres veces): lee las notas antes de marcar a un cliente.
