SHOPIFY

Admin GraphQL 2025-04 — Terraverde Tostadores

4 operaciones Admin API generadas con la skill shopify-admin · CULTIVA IA

API 2025-04 Node.js / fetch skill: shopify-admin Shopify Plus
1

Consultar productos activos con variantes e inventario

Sincronización con ERP externo — paginación con cursores

QUERY
Objetivo: Obtener los primeros 10 productos activos (estado ACTIVE) con sus variantes, precios, SKUs y niveles de inventario en todas las ubicaciones. Ideal para sincronizar stock en tiempo real con el ERP de Terraverde.

Patrón: Paginación Relay con first + after (cursor). El campo inventoryItem.inventoryLevels devuelve stock por ubicación.
products.graphql
# Busca los primeros 10 productos ACTIVE con variantes e inventario
query GetActiveProducts($cursor: String) {
  products(
    first: 10
    after: $cursor
    query: "status:active"
  ) {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        title
        handle
        status
        variants(first: 10) {
          edges {
            node {
              id
              sku
              title
              price
              inventoryQuantity
              inventoryItem {
                id
                inventoryLevels(first: 5) {
                  edges {
                    node {
                      available
                      location {
                        name
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
Variables de ejemplo
{
  "cursor": null  // null para primera página; luego endCursor
}
Respuesta parcial esperada
{
  "data": {
    "products": {
      "pageInfo": { "hasNextPage": true, "endCursor": "eyJsYXN0X2lkIjo..." },
      "edges": [{
        "node": {
          "id": "gid://shopify/Product/8812345678",
          "title": "Café Etiopía Yirgacheffe - Honey",
          "handle": "etiopia-yirgacheffe-honey",
          "variants": {
            "edges": [{
              "node": {
                "sku": "TV-ETH-H-250",
                "price": "14.90",
                "inventoryQuantity": 87
              }
            }]
          }
        }
      }]
    }
  }
}
📚 Docs: shopify.dev/docs/api/admin-graphql/2025-04/queries/products · El argumento query: acepta filtros tipo Lucene (status:active vendor:Terraverde). Para iterar todas las páginas, guardar endCursor y pasar como $cursor en la siguiente llamada.
2

Crear Draft Order para pedido B2B

Pedidos manuales recibidos por email o WhatsApp

MUTATION
Objetivo: Crear un pedido borrador para el cliente B2B Hostal Montserrat que pide 12 bolsas de 1 kg del blend casa. El draft se guarda como borrador para revisión antes de enviarlo al cliente para pago.

Patrón: draftOrderCreate recibe un DraftOrderInput con lineItems, customerId y note.
createDraftOrder.graphql
# Crea un Draft Order para pedido B2B de hostelería
mutation CreateB2BDraftOrder($input: DraftOrderInput!) {
  draftOrderCreate(input: $input) {
    draftOrder {
      id
      name
      status
      totalPriceSet {
        shopMoney {
          amount
          currencyCode
        }
      }
      invoiceUrl
    }
    userErrors {
      field
      message
    }
  }
}
Variables de ejemplo
{
  "input": {
    "customerId": "gid://shopify/Customer/6234567890",
    "lineItems": [
      {
        "variantId": "gid://shopify/ProductVariant/4398765432",
        "quantity": 12
      }
    ],
    "note": "Pedido B2B Hostal Montserrat — entrega 20/06/2026",
    "tags": ["b2b", "hostelería"],
    "shippingAddress": {
      "address1": "Calle Montserrat 12",
      "city": "Barcelona",
      "zip": "08001",
      "countryCode": "ES"
    }
  }
}
Respuesta de éxito esperada
{
  "data": {
    "draftOrderCreate": {
      "draftOrder": {
        "id": "gid://shopify/DraftOrder/5512345678",
        "name": "#D104",
        "status": "OPEN",
        "totalPriceSet": {
          "shopMoney": { "amount": "334.80", "currencyCode": "EUR" }
        },
        "invoiceUrl": "https://terraverde.myshopify.com/invoices/abc123..."
      },
      "userErrors": []
    }
  }
}
📚 Docs: shopify.dev/docs/api/admin-graphql/2025-04/mutations/draftOrderCreate · Usar draftOrderInvoiceSend para enviar el link de pago por email al cliente.
3

Actualizar metafields de producto

Origen del grano, altitud y proceso de beneficio

MUTATION
Objetivo: Almacenar atributos del café de especialidad como metafields en el namespace cafe_especialidad: país de origen, altitud (msnm) y proceso de beneficio (honey/washed/natural). Se muestran en la PDP de la tienda.

Patrón: metafieldsSet permite crear o actualizar múltiples metafields en una sola llamada con el identificador GID del producto.
setProductMetafields.graphql
# Upsert metafields de café de especialidad en el producto
mutation SetCafeEspecialidadMetafields(
  $metafields: [MetafieldsSetInput!]!
) {
  metafieldsSet(metafields: $metafields) {
    metafields {
      id
      namespace
      key
      value
      type
    }
    userErrors {
      field
      message
      code
    }
  }
}
Variables de ejemplo
{
  "metafields": [
    {
      "ownerId": "gid://shopify/Product/8812345678",
      "namespace": "cafe_especialidad",
      "key": "pais_origen",
      "type": "single_line_text_field",
      "value": "Etiopía"
    },
    {
      "ownerId": "gid://shopify/Product/8812345678",
      "namespace": "cafe_especialidad",
      "key": "altitud_msnm",
      "type": "number_integer",
      "value": "1950"
    },
    {
      "ownerId": "gid://shopify/Product/8812345678",
      "namespace": "cafe_especialidad",
      "key": "proceso",
      "type": "single_line_text_field",
      "value": "honey"
    }
  ]
}
cafe_especialidad.pais_origen
type: single_line_text_field · país de origen del grano
cafe_especialidad.altitud_msnm
type: number_integer · altitud sobre el nivel del mar
cafe_especialidad.proceso
type: single_line_text_field · honey / washed / natural
📚 Docs: shopify.dev/docs/api/admin-graphql/2025-04/mutations/metafieldsSet · Los metafields con namespace propio (cafe_especialidad) requieren definición de tipo en Settings > Custom Data antes de pintarlos en Liquid con product.metafields.cafe_especialidad.pais_origen.
4

Buscar cliente por email con historial de pedidos

Soporte al cliente y gestión de reclamaciones

QUERY
Objetivo: Localizar a un cliente por su dirección de email y obtener sus últimos 5 pedidos con estado, importe y productos. Útil para el equipo de soporte de Terraverde cuando reciben una reclamación por WhatsApp.

Patrón: customers(query: "email:...") + conexión anidada orders con sortKey: CREATED_AT reverse: true.
customerLookup.graphql
# Busca un cliente por email y devuelve sus últimos 5 pedidos
query GetCustomerByEmail($email: String!) {
  customers(
    first: 1
    query: $email
  ) {
    edges {
      node {
        id
        displayName
        email
        phone
        numberOfOrders
        totalSpentV2 {
          amount
          currencyCode
        }
        orders(
          first: 5
          sortKey: CREATED_AT
          reverse: true
        ) {
          edges {
            node {
              name
              createdAt
              displayFinancialStatus
              displayFulfillmentStatus
              currentTotalPriceSet {
                shopMoney {
                  amount
                  currencyCode
                }
              }
              lineItems(first: 3) {
                edges {
                  node {
                    name
                    quantity
                    sku
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
Variables de ejemplo
{
  "email": "email:montse.garcia@hostalbarcelona.com"
}
Respuesta parcial esperada
{
  "data": {
    "customers": {
      "edges": [{
        "node": {
          "displayName": "Montse García",
          "email": "montse.garcia@hostalbarcelona.com",
          "numberOfOrders": 8,
          "totalSpentV2": { "amount": "1247.60", "currencyCode": "EUR" },
          "orders": {
            "edges": [{
              "node": {
                "name": "#1043",
                "createdAt": "2026-06-01T10:22:00Z",
                "displayFinancialStatus": "PAID",
                "displayFulfillmentStatus": "IN_PROGRESS",
                "lineItems": {
                  "edges": [{
                    "node": {
                      "name": "Café Blend Casa - 1kg",
                      "quantity": 12,
                      "sku": "TV-BLC-1000"
                    }
                  }]
                }
              }
            }]
          }
        }
      }]
    }
  }
}
📚 Docs: shopify.dev/docs/api/admin-graphql/2025-04/queries/customers · El filtro email:xxx es sensible a case. Para búsquedas más robustas se puede combinar: "email:montse.garcia@hostalbarcelona.com". El campo totalSpentV2 suma pedidos pagados de por vida.