Pedidos

Los pedidos representan las dispensaciones de productos a miembros del club. Esta página documenta los endpoints para gestionar pedidos, incluyendo creación, procesamiento, fulfillment y seguimiento.

Flujo de Pedido

Loading diagram...

El modelo de Pedido

El modelo de pedido contiene toda la información sobre una dispensación, incluyendo items, pagos, estado de fulfillment y metadata.

Propiedades

  • Name
    id
    Type
    string
    Description

    Identificador único del pedido.

  • Name
    displayId
    Type
    string
    Description

    Número de pedido legible (ej: #1234).

  • Name
    status
    Type
    OrderStatus
    Description

    Estado general del pedido.

  • Name
    fulfillmentStatus
    Type
    FulfillmentStatus
    Description

    Estado del proceso de fulfillment.

  • Name
    paymentStatus
    Type
    PaymentStatus
    Description

    Estado del pago.

  • Name
    customer
    Type
    object
    Description

    Información del cliente que realizó el pedido.

  • Name
    items
    Type
    array
    Description

    Lista de items en el pedido.

    • Name
      id
      Type
      string
      Description

      ID del item.

    • Name
      title
      Type
      string
      Description

      Nombre del producto.

    • Name
      variantId
      Type
      string
      Description

      ID de la variante comprada.

    • Name
      quantity
      Type
      number
      Description

      Cantidad de unidades.

    • Name
      unitPrice
      Type
      number
      Description

      Precio por unidad.

    • Name
      total
      Type
      number
      Description

      Total del item.

  • Name
    payments
    Type
    array
    Description

    Pagos asociados al pedido.

  • Name
    subtotal
    Type
    number
    Description

    Subtotal sin impuestos ni envío.

  • Name
    shippingTotal
    Type
    number
    Description

    Costo de envío.

  • Name
    taxTotal
    Type
    number
    Description

    Total de impuestos.

  • Name
    total
    Type
    number
    Description

    Total del pedido.

  • Name
    currency
    Type
    string
    Description

    Código de moneda (ARS, USD).

  • Name
    shippingAddress
    Type
    Address
    Description

    Dirección de envío.

  • Name
    createdAt
    Type
    timestamp
    Description

    Fecha de creación del pedido.

Ejemplo de pedido completo

{
  "id": "order_01HQ8XYZ123",
  "displayId": "#1234",
  "status": "completed",
  "fulfillmentStatus": "shipped",
  "paymentStatus": "captured",
  "customer": {
    "id": "cus_01HQ8ABC456",
    "email": "maria@email.com",
    "firstName": "María",
    "lastName": "González"
  },
  "items": [
    {
      "id": "item_01HQ8DEF789",
      "title": "Blue Dream 5g",
      "variantId": "variant_01HQ_BD_5G",
      "quantity": 2,
      "unitPrice": 1650000,
      "total": 3300000,
      "thumbnail": "https://storage.cannahub.tech/..."
    }
  ],
  "payments": [
    {
      "id": "pay_01HQ8GHI012",
      "amount": 3300000,
      "currency": "ARS",
      "status": "captured",
      "providerId": "mercadopago",
      "createdAt": "2024-03-20T15:30:00Z"
    }
  ],
  "subtotal": 3300000,
  "shippingTotal": 0,
  "taxTotal": 0,
  "total": 3300000,
  "currency": "ARS",
  "shippingAddress": {
    "firstName": "María",
    "lastName": "González",
    "address1": "Av. Corrientes 1234",
    "city": "Buenos Aires",
    "province": "CABA",
    "postalCode": "C1043",
    "countryCode": "AR"
  },
  "createdAt": "2024-03-20T15:00:00Z",
  "updatedAt": "2024-03-20T16:00:00Z"
}

Estados del Pedido

OrderStatus

EstadoDescripción
pendingPedido creado, pendiente de procesamiento
requires_actionRequiere acción del usuario o administrador
completedPedido completado exitosamente
canceledPedido cancelado

FulfillmentStatus

EstadoDescripción
not_fulfilledNo procesado aún
partially_fulfilledParcialmente procesado
fulfilledCompletamente procesado
shippedEnviado/entregado al cliente
returnedDevuelto
canceledFulfillment cancelado

PaymentStatus

EstadoDescripción
not_paidSin pago registrado
awaitingEsperando confirmación de pago
capturedPago capturado/confirmado
partially_refundedParcialmente reembolsado
refundedCompletamente reembolsado

GET/api/orders

Listar pedidos

Este endpoint permite obtener una lista paginada de pedidos con filtros opcionales.

Parámetros opcionales

  • Name
    limit
    Type
    integer
    Description

    Número máximo de pedidos a retornar (default: 10).

  • Name
    offset
    Type
    integer
    Description

    Número de pedidos a saltar para paginación.

  • Name
    status
    Type
    string
    Description

    Filtrar por estado del pedido.

  • Name
    fulfillment_status
    Type
    string
    Description

    Filtrar por estado de fulfillment.

  • Name
    payment_status
    Type
    string
    Description

    Filtrar por estado de pago.

  • Name
    customer_id
    Type
    string
    Description

    Filtrar por ID de cliente.

Request

GET
/api/orders
curl -G https://yourapp.com/api/orders \
  -H "Authorization: Bearer {token}" \
  -d limit=10 \
  -d status=pending

Response

{
  "orders": [
    {
      "id": "order_01HQ8XYZ123",
      "displayId": "#1234",
      "status": "pending",
      "total": 3300000,
      "customer": {
        "email": "maria@email.com"
      },
      "createdAt": "2024-03-20T15:00:00Z"
    }
  ],
  "count": 1,
  "offset": 0,
  "limit": 10
}

GET/api/orders/:id

Obtener pedido

Este endpoint permite obtener los detalles completos de un pedido específico.

Request

GET
/api/orders/:id
curl https://yourapp.com/api/orders/order_01HQ8XYZ123 \
  -H "Authorization: Bearer {token}"

Response

{
  "order": {
    "id": "order_01HQ8XYZ123",
    "displayId": "#1234",
    "status": "pending",
    "fulfillmentStatus": "not_fulfilled",
    "paymentStatus": "captured",
    "items": [...],
    "payments": [...],
    "total": 3300000
  }
}

POST/store/carts/:id/complete

Crear pedido (desde carrito)

Los pedidos se crean completando un carrito existente. Este es el flujo estándar para miembros.

Flujo completo

  1. Crear carrito con región
  2. Agregar items al carrito
  3. Seleccionar método de envío
  4. Inicializar sesión de pago
  5. Completar el carrito (crea el pedido)

Request

POST
/store/carts/:id/complete
// 1. Crear carrito
const { cart } = await medusa.carts.create({
  region_id: 'reg_argentina'
})

// 2. Agregar items
await medusa.carts.lineItems.create(cart.id, {
  variant_id: 'variant_01HQ_BD_5G',
  quantity: 2
})

// 3. Agregar método de envío
await medusa.carts.addShippingMethod(cart.id, {
  option_id: 'so_pickup'
})

// 4. Inicializar pago
await medusa.carts.createPaymentSessions(cart.id)
await medusa.carts.setPaymentSession(cart.id, {
  provider_id: 'mercadopago'
})

// 5. Completar pedido
const { order } = await medusa.carts.complete(cart.id)

Response

{
  "type": "order",
  "order": {
    "id": "order_01HQ8XYZ123",
    "displayId": "#1234",
    "status": "pending",
    "paymentStatus": "awaiting",
    "items": [...],
    "total": 3300000
  }
}

POST/api/orders/:id/capture

Capturar pago

Captura el pago de un pedido. Esto confirma que el pago fue recibido.

Request

POST
/api/orders/:id/capture
curl -X POST https://yourapp.com/api/orders/order_01HQ8XYZ123/capture \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json"

Response

{
  "order": {
    "id": "order_01HQ8XYZ123",
    "paymentStatus": "captured"
  }
}

POST/api/orders/:id/fulfill

Crear fulfillment

Crea un fulfillment para marcar items como procesados y listos para entrega.

Request

POST
/api/orders/:id/fulfill
curl -X POST https://yourapp.com/api/orders/order_01HQ8XYZ123/fulfill \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "id": "item_01HQ8DEF789",
        "quantity": 2
      }
    ],
    "locationId": "loc_highup_main"
  }'

Response

{
  "order": {
    "id": "order_01HQ8XYZ123",
    "fulfillmentStatus": "fulfilled",
    "fulfillments": [
      {
        "id": "ful_01HQ8JKL345",
        "items": [...],
        "createdAt": "2024-03-20T16:00:00Z"
      }
    ]
  },
  "fulfillmentId": "ful_01HQ8JKL345"
}

POST/api/orders/:id/ship

Marcar como enviado

Marca un fulfillment como enviado/entregado al cliente.

Request

POST
/api/orders/:id/ship
curl -X POST https://yourapp.com/api/orders/order_01HQ8XYZ123/ship \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "fulfillmentId": "ful_01HQ8JKL345"
  }'

Response

{
  "order": {
    "id": "order_01HQ8XYZ123",
    "fulfillmentStatus": "shipped"
  }
}

POST/api/orders/:id/cancel

Cancelar pedido

Cancela un pedido. Solo se pueden cancelar pedidos que no han sido enviados o entregados.

Request

POST
/api/orders/:id/cancel
curl -X POST https://yourapp.com/api/orders/order_01HQ8XYZ123/cancel \
  -H "Authorization: Bearer {token}"

Response

{
  "order": {
    "id": "order_01HQ8XYZ123",
    "status": "canceled"
  }
}

Registro de Actividad

Los pedidos en Cannahub incluyen un registro de actividad para tracking de cambios. Las actividades se almacenan en order.metadata.activityLogs.

  • Name
    activityLogs
    Type
    array
    Description

    Historial de actividades del pedido.

    • Name
      type
      Type
      'system' | 'user'
      Description

      Tipo de actividad.

    • Name
      status
      Type
      'info' | 'success' | 'warning' | 'error'
      Description

      Estado/nivel de la actividad.

    • Name
      description
      Type
      string
      Description

      Clave de traducción o descripción de la actividad.

    • Name
      at
      Type
      string
      Description

      Fecha y hora de la actividad (ISO 8601).

    • Name
      author
      Type
      object
      Description

      Usuario que realizó la acción.

      • Name
        id
        Type
        string
        Description

        ID del usuario.

      • Name
        firstName
        Type
        string
        Description

        Nombre del usuario.

      • Name
        lastName
        Type
        string
        Description

        Apellido del usuario.

Tipos de Descripción

ClaveSignificado
orders:activity.createdPedido creado
orders:activity.paymentConfirmedPago confirmado
orders:activity.fulfilledPedido preparado
orders:activity.shippedPedido enviado
orders:activity.completedPedido completado
orders:activity.invoicedPedido facturado
orders:activity.cancelledPedido cancelado
orders:activity.noteNota agregada

Ejemplo de actividad

{
  "activityLogs": [
    {
      "type": "system",
      "status": "success",
      "description": "orders:activity.created",
      "at": "2024-03-20T15:00:00Z",
      "author": {
        "id": "user_01HQ8ABC",
        "firstName": "Juan",
        "lastName": "Admin"
      }
    },
    {
      "type": "system",
      "status": "success",
      "description": "orders:activity.paymentConfirmed",
      "at": "2024-03-20T15:30:00Z",
      "author": {
        "id": "user_01HQ8ABC",
        "firstName": "Juan",
        "lastName": "Admin"
      }
    },
    {
      "type": "system",
      "status": "success",
      "description": "orders:activity.fulfilled",
      "at": "2024-03-20T16:00:00Z",
      "author": {
        "id": "user_01HQ8ABC",
        "firstName": "Juan",
        "lastName": "Admin"
      }
    },
    {
      "type": "system",
      "status": "success",
      "description": "orders:activity.completed",
      "at": "2024-03-20T17:00:00Z",
      "author": {
        "id": "user_01HQ8ABC",
        "firstName": "Juan",
        "lastName": "Admin"
      }
    }
  ]
}

POST/api/orders/create-and-process

BFF Route: Crear y Procesar Pedido

Este endpoint orquesta todo el flujo de creación de pedido internamente:

  1. Crear carrito
  2. Agregar items (en paralelo)
  3. Configurar método de envío
  4. Inicializar sesión de pago
  5. Completar pedido
  6. Capturar pago
  7. Crear fulfillment
  8. Marcar como enviado
  9. Registrar actividades

Request Body

  • Name
    customer
    Type
    object
    Description

    Información del cliente.

    • Name
      id
      Type
      string
      Description

      ID del cliente en Medusa.

    • Name
      email
      Type
      string
      Description

      Email del cliente.

    • Name
      firstName
      Type
      string
      Description

      Nombre del cliente.

    • Name
      lastName
      Type
      string
      Description

      Apellido del cliente.

  • Name
    items
    Type
    array
    Description

    Items a incluir en el pedido.

    • Name
      variantId
      Type
      string
      Description

      ID de la variante del producto.

    • Name
      quantity
      Type
      number
      Description

      Cantidad a ordenar.

  • Name
    shippingMethod
    Type
    string
    Description

    Método de envío: pickup o delivery.

  • Name
    paymentMethod
    Type
    string
    Description

    Método de pago: cash, mercadopago, transfer.

  • Name
    locationId
    Type
    string
    Description

    ID de la ubicación de stock (para fulfillment).

  • Name
    notes
    Type
    string
    Description

    Notas adicionales para el pedido.

Beneficio de Performance

FlujoLlamadas APILatencia Estimada
Cliente directo15+ llamadas~3-5 segundos
BFF Route1 llamada~1-2 segundos
Reducción93%60-70%

Request

POST
/api/orders/create-and-process
curl -X POST https://app.cannahub.tech/api/orders/create-and-process \
  -H "Authorization: Bearer {admin_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "customer": {
      "id": "cus_01HQ8ABC456",
      "email": "maria@email.com",
      "firstName": "María",
      "lastName": "González"
    },
    "items": [
      { "variantId": "variant_01HQ_BD_5G", "quantity": 2 },
      { "variantId": "variant_01HQ_GG_1G", "quantity": 1 }
    ],
    "shippingMethod": "pickup",
    "paymentMethod": "cash",
    "locationId": "sloc_high_up"
  }'

Response

{
  "order": {
    "id": "order_01HQ8XYZ123",
    "displayId": "#1234",
    "status": "completed",
    "fulfillmentStatus": "shipped",
    "paymentStatus": "captured",
    "customer": {
      "id": "cus_01HQ8ABC456",
      "email": "maria@email.com",
      "firstName": "María",
      "lastName": "González"
    },
    "items": [
      {
        "id": "item_01HQ8DEF789",
        "title": "Blue Dream 5g",
        "quantity": 2,
        "unitPrice": 1650000,
        "total": 3300000
      },
      {
        "id": "item_01HQ8DEF790",
        "title": "Gorilla Glue 1g",
        "quantity": 1,
        "unitPrice": 350000,
        "total": 350000
      }
    ],
    "total": 3650000,
    "currency": "ARS"
  },
  "timeline": [
    {
      "action": "ORDER_CREATED",
      "timestamp": "2024-03-20T15:00:00Z"
    },
    {
      "action": "PAYMENT_CAPTURED",
      "timestamp": "2024-03-20T15:00:01Z"
    },
    {
      "action": "FULFILLMENT_CREATED",
      "timestamp": "2024-03-20T15:00:02Z"
    },
    {
      "action": "ORDER_SHIPPED",
      "timestamp": "2024-03-20T15:00:03Z"
    }
  ]
}

Diagrama de Flujo Interno

Loading diagram...

Mapeo Medusa

La API BFF transforma las respuestas de Medusa de snake_case a camelCase:

Campos de Order

UI (camelCase)Medusa (snake_case)
displayId / numberdisplay_id
createdAtcreated_at
subTotalsubtotal
discountTotaldiscount_total
taxTotaltax_total
shippingTotalshipping_total
paymentStatuspayment_status
fulfillmentStatusfulfillment_status
customerIdcustomer_id
currencycurrency_code

Campos de Order Item

UI (camelCase)Medusa (snake_case)
unitPriceunit_price
variantIdvariant_id
productIdproduct_id

Campos de Metadata

UI (camelCase)Medusa (snake_case)
activityLogsactivity_logs
isInvoicedisInvoiced
invoicedAtinvoicedAt

Las funciones de parser estan en /src/lib/medusa/orders.ts:

import { parseMedusaOrder, parseOrderMetadata, serializeOrderMetadata } from '@/lib/medusa/orders'

// Transforma respuesta Medusa a camelCase
const order = parseMedusaOrder(medusaResponse.order)

// Transforma metadata
const metadata = parseOrderMetadata(order.metadata)

// Serializa metadata para enviar a Medusa
const serialized = serializeOrderMetadata(metadata)

Próximos Pasos

API de ProductosAPI de MiembrosAPI de InventarioWebhooks