> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getjusto.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Editar precio de un producto en un menú

> Cambia el precio, el precio con descuento o la disponibilidad del producto en un menú, sin modificar los demás menús. El precio actual en cada menú está en menus de GET /ecommerce/products/{productId}. Requiere edición de productos habilitada en la marca.

**Cómo funcionan los menús y precios**

Un menú es una lista de precios: dice qué productos se venden y a qué precio. En el administrador se llama *menú* y en la API *precio*: cada menú es un registro de `GET /ecommerce/prices`, y su `_id` es el `menuId` que aparece en `menus` de cada producto. Una marca puede tener varios menús, por ejemplo uno general, uno para un local y uno de almuerzo.

**1. Cada pedido usa un solo menú.** Los menús no se mezclan: el cliente ve el precio y la disponibilidad que el producto tiene en el menú que se está usando.

**2. Cómo se elige el menú en la tienda online.** Se revisan los menús habilitados de mayor a menor `priority` y se usa el primero que cumple todas estas condiciones:

- `storesIds` está vacío o incluye el local del pedido. Mientras no se sepa el local, los menús con locales no aplican.
- `channels` está vacío o incluye el canal del pedido. Si el cliente aún no elige cómo recibir el pedido, se considera delivery.
- `schedule` está abierto a la hora de entrega menos el tiempo de preparación del local, o ahora si el pedido no es programado. El horario solo restringe si `availableAtPeriods` es `true`; si no, el menú aplica a toda hora, salvo los días cerrados (`closedDays`).
- Faltan al menos `daysBefore` días de calendario para esa fecha.
- `segmentIds` está vacío, o el cliente inició sesión y pertenece a alguna de esas audiencias.

Si ningún menú cumple, se usa el menú por defecto (`isDefault`), aunque no cumpla sus condiciones. Si la marca no tiene menú por defecto, se usa el de mayor `priority`. Si la marca tiene un solo menú habilitado, se usa siempre.

**3. Productos no disponibles.** Si el producto no está disponible en el menú que se usa, no aparece en la tienda. Si en el administrador tiene un mensaje de no disponible, aparece con ese mensaje, pero no se puede comprar. Un producto tampoco aparece si tiene un modificador obligatorio sin opciones disponibles en ese menú. Agotado (`out-of-stock`) es otra cosa: se marca por local, y el producto aparece como agotado, salvo que la marca active *Ocultar productos no disponibles o sin stock*: entonces los agotados no aparecen.

**4. Cada menú tiene su propio precio.** Cambiar el precio en un menú no cambia los demás. Para cambiarlo en toda la marca, cámbialo en cada menú donde el producto está disponible. Para cambiarlo solo en un local, canal u horario, usa el punto 2 para saber qué menú se usa ahí.

**5. Descuentos.** `discountPrice` es el precio final que paga el cliente, no un monto ni un porcentaje, y no puede ser mayor que el precio: si bajas `price` por debajo del descuento guardado, envía también `discountPrice`. Si es menor que el precio, la tienda muestra el precio normal tachado. En las respuestas viene como `discount`. Enviar `discountPrice` deja un solo descuento, y `null` lo quita. En el administrador se pueden guardar varios descuentos seguidos: en ese caso `discount` es el primero, pero el cliente paga el último.

**6. Los cambios no son instantáneos.** La tienda se actualiza en segundo plano, y el menú elegido para cada cliente se guarda hasta 15 minutos, así que un cambio en las condiciones de un menú puede tardar ese tiempo en verse.



## OpenAPI

````yaml put /ecommerce/products/{productId}/menus/{menuId}
openapi: 3.1.0
info:
  title: Justo API
  version: 3.0.0
servers:
  - url: https://api.service.getjusto.com/v3
    description: Production server
security: []
paths:
  /ecommerce/products/{productId}/menus/{menuId}:
    put:
      summary: Update product price in a menu
      description: >-
        Cambia el precio, el precio con descuento o la disponibilidad del
        producto en un menú, sin modificar los demás menús. El precio actual en
        cada menú está en menus de GET /ecommerce/products/{productId}. Requiere
        edición de productos habilitada en la marca.


        **Cómo funcionan los menús y precios**


        Un menú es una lista de precios: dice qué productos se venden y a qué
        precio. En el administrador se llama *menú* y en la API *precio*: cada
        menú es un registro de `GET /ecommerce/prices`, y su `_id` es el
        `menuId` que aparece en `menus` de cada producto. Una marca puede tener
        varios menús, por ejemplo uno general, uno para un local y uno de
        almuerzo.


        **1. Cada pedido usa un solo menú.** Los menús no se mezclan: el cliente
        ve el precio y la disponibilidad que el producto tiene en el menú que se
        está usando.


        **2. Cómo se elige el menú en la tienda online.** Se revisan los menús
        habilitados de mayor a menor `priority` y se usa el primero que cumple
        todas estas condiciones:


        - `storesIds` está vacío o incluye el local del pedido. Mientras no se
        sepa el local, los menús con locales no aplican.

        - `channels` está vacío o incluye el canal del pedido. Si el cliente aún
        no elige cómo recibir el pedido, se considera delivery.

        - `schedule` está abierto a la hora de entrega menos el tiempo de
        preparación del local, o ahora si el pedido no es programado. El horario
        solo restringe si `availableAtPeriods` es `true`; si no, el menú aplica
        a toda hora, salvo los días cerrados (`closedDays`).

        - Faltan al menos `daysBefore` días de calendario para esa fecha.

        - `segmentIds` está vacío, o el cliente inició sesión y pertenece a
        alguna de esas audiencias.


        Si ningún menú cumple, se usa el menú por defecto (`isDefault`), aunque
        no cumpla sus condiciones. Si la marca no tiene menú por defecto, se usa
        el de mayor `priority`. Si la marca tiene un solo menú habilitado, se
        usa siempre.


        **3. Productos no disponibles.** Si el producto no está disponible en el
        menú que se usa, no aparece en la tienda. Si en el administrador tiene
        un mensaje de no disponible, aparece con ese mensaje, pero no se puede
        comprar. Un producto tampoco aparece si tiene un modificador obligatorio
        sin opciones disponibles en ese menú. Agotado (`out-of-stock`) es otra
        cosa: se marca por local, y el producto aparece como agotado, salvo que
        la marca active *Ocultar productos no disponibles o sin stock*: entonces
        los agotados no aparecen.


        **4. Cada menú tiene su propio precio.** Cambiar el precio en un menú no
        cambia los demás. Para cambiarlo en toda la marca, cámbialo en cada menú
        donde el producto está disponible. Para cambiarlo solo en un local,
        canal u horario, usa el punto 2 para saber qué menú se usa ahí.


        **5. Descuentos.** `discountPrice` es el precio final que paga el
        cliente, no un monto ni un porcentaje, y no puede ser mayor que el
        precio: si bajas `price` por debajo del descuento guardado, envía
        también `discountPrice`. Si es menor que el precio, la tienda muestra el
        precio normal tachado. En las respuestas viene como `discount`. Enviar
        `discountPrice` deja un solo descuento, y `null` lo quita. En el
        administrador se pueden guardar varios descuentos seguidos: en ese caso
        `discount` es el primero, pero el cliente paga el último.


        **6. Los cambios no son instantáneos.** La tienda se actualiza en
        segundo plano, y el menú elegido para cada cliente se guarda hasta 15
        minutos, así que un cambio en las condiciones de un menú puede tardar
        ese tiempo en verse.
      parameters:
        - in: path
          name: productId
          required: true
          schema:
            type: string
          description: ID Justo o ID externo del producto.
        - in: path
          name: menuId
          required: true
          schema:
            type: string
          description: ID Justo o ID externo del menú (GET /ecommerce/prices).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/apiProductMenuUpdateInput'
      responses:
        '200':
          description: The OpenAPI spec
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  data:
                    $ref: '#/components/schemas/apiListingProduct'
        '400':
          description: Errors
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: 'false'
                  error:
                    type: object
                    properties:
                      error:
                        type: string
                        example: error
                      message:
                        type: string
                        example: The request has an error
components:
  schemas:
    apiProductMenuUpdateInput:
      type: object
      description: >-
        Cambios del producto en un menú. Los campos omitidos y los demás menús
        se conservan.
      minProperties: 1
      additionalProperties: false
      properties:
        price:
          type: number
          minimum: 0
          description: >-
            Precio base en la moneda de la marca. 0 significa gratis. Es
            obligatorio si el producto aún no tiene precio en ese menú.
        discountPrice:
          type:
            - number
            - 'null'
          minimum: 0
          description: >-
            Precio con descuento: el precio final rebajado, menor o igual al
            precio base. No es un monto ni un porcentaje. Reemplaza los
            descuentos guardados en ese menú; null los quita. Si bajas price por
            debajo del precio con descuento actual, envía también discountPrice
            o null.
        available:
          type: boolean
          description: >-
            Si el producto se vende en ese menú. Al asignar un precio en un menú
            nuevo sin este campo, queda disponible.
      example:
        price: 5490
        discountPrice: 4990
        available: true
    apiListingProduct:
      type: object
      description: Producto del catálogo.
      properties:
        productId:
          type: string
          description: ID Justo del producto.
        importId:
          type: string
          description: ID de importación del producto.
        name:
          type: string
          description: Nombre del producto.
        internalName:
          type: string
          description: Nombre interno del producto.
        description:
          type: string
          description: Descripción visible del producto.
        seoTitle:
          type:
            - string
            - 'null'
          maxLength: 300
          description: >-
            Título SEO independiente del nombre. Null o texto vacío restaura el
            título automático.
        seoDescription:
          type:
            - string
            - 'null'
          maxLength: 1000
          description: >-
            Metadescripción independiente de la descripción. Null o texto vacío
            restaura el valor automático.
        seoImageURL:
          type:
            - string
            - 'null'
          maxLength: 2048
          description: >-
            URL absoluta http o https sin credenciales, para SEO y enlaces
            compartidos. Null o texto vacío restaura la imagen automática. No
            modifica la galería.
        richContent:
          type:
            - string
            - 'null'
          maxLength: 50000
          description: >-
            HTML sanitizado, disponible en GET individual y respuesta de PUT.
            Null elimina el contenido. Admite texto, imágenes, galerías, tablas
            y acordiones; elimina scripts, estilos y clases.
        richContentPosition:
          type:
            - string
            - 'null'
          enum:
            - beforeModifiers
            - afterModifiers
            - null
          description: >-
            Posición del contenido respecto a los modificadores. Null usa
            beforeModifiers.
        hasRichContent:
          type: boolean
          description: >-
            Indica si tiene contenido enriquecido. El listado omite el HTML;
            consulta el detalle para obtenerlo.
        url:
          type: string
          description: URL pública del producto.
        partialUrl:
          type: string
          description: Path público del producto.
        categoriesNames:
          type: array
          description: Nombres de categorías asociadas.
          items:
            type: string
        categoriesIds:
          type: array
          description: IDs de categorías asociadas.
          items:
            type: string
        modifiersIds:
          type: array
          description: IDs de modificadores asociados.
          items:
            type: string
        externalId:
          type: string
          description: ID externo configurado por la marca.
        metadata:
          type: object
          description: Metadata del item escrita por API v3.
          additionalProperties: true
        images:
          type: array
          description: URLs de imágenes del producto.
          items:
            type: string
        menus:
          type: array
          description: >-
            Precio y disponibilidad en cada menú. El cliente ve sólo los del
            menú que aplica en su pedido; ver GET /ecommerce/prices.
          items:
            type: object
            description: >-
              Precio y disponibilidad del item en un menú (precio). Viene una
              entrada por cada menú de la marca, también los deshabilitados. En
              las opciones de modificador solo vienen menuId, price y available.
            properties:
              menuId:
                type: string
                description: ID Justo del menú (_id en GET /ecommerce/prices).
              price:
                type: number
                description: >-
                  Precio base en este menú. Si el item no tiene configuración en
                  este menú, es 0 y available no viene.
              discount:
                type:
                  - number
                  - 'null'
                description: >-
                  Precio con descuento: el precio final rebajado, no un monto ni
                  un porcentaje. null si no tiene. Si en el administrador se
                  guardaron varios descuentos seguidos, es el primero, pero el
                  cliente paga el último.
              available:
                type: boolean
                description: >-
                  true si se vende en este menú. Si es false o no viene, no se
                  vende: el item no aparece mientras se use este menú, salvo que
                  tenga un mensaje de no disponible en el administrador;
                  entonces aparece con ese mensaje, pero no se puede comprar.
              externalId:
                type: string
                description: >-
                  ID externo del producto en este menú: el de reemplazo si se
                  configuró; si no, el externalId del producto.
            additionalProperties: true

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.