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

# Ejemplo: productos

> Ejemplo de listado, creación y actualización de productos con el SDK de TypeScript de La Pyme

Los métodos de productos viven en `lapyme.products`. Los nombres de campos del SDK son `camelCase`; el SDK convierte esos campos al contrato público `snake_case` antes de enviar la request.

## Listar productos

```typescript theme={null}
import { Lapyme } from "lapyme";

const lapyme = new Lapyme({
  bearerAuth: process.env["LAPYME_API_KEY"] ?? "",
});

const products = await lapyme.products.list({
  limit: 20,
  query: "remera",
  productType: "product",
  isActive: true,
});

for (const product of products.result.data) {
  console.log(product.id, product.name);
}
```

## Crear un producto

Los importes monetarios se envían en centavos. Reutilizá el mismo `idempotencyKey` si tenés que reintentar la misma creación.

```typescript theme={null}
import { Lapyme } from "lapyme";

const lapyme = new Lapyme({
  bearerAuth: process.env["LAPYME_API_KEY"] ?? "",
});

const product = await lapyme.products.create({
  idempotencyKey: crypto.randomUUID(),
  body: {
    name: "Remera básica",
    sku: "REM-BASICA-M",
    productType: "product",
    price: 1250000,
    cost: 700000,
    currency: "PES",
  },
});

console.log(product.result.data.product.id);
```

## Campos personalizados al crear y actualizar

Los campos personalizados de productos requieren un plan Max o Enterprise. Primero consultá `GET /api/v1/products/metafield-definitions`: la respuesta publica claves estables, tipos, validaciones y opciones configuradas, sin IDs internos. Las definiciones y opciones deben existir antes de crear el producto.

```typescript theme={null}
const definitions = await fetch(
  "https://api.lapyme.com.ar/api/v1/products/metafield-definitions",
  { headers: { Authorization: `Bearer ${process.env.LAPYME_API_KEY}` } },
).then((response) => response.json());

const genesis = await lapyme.products.create({
  idempotencyKey: crypto.randomUUID(),
  body: {
    name: "Genesis",
    sku: "GENESIS",
    price: 1250000,
    metafields: [{ key: "MARCA", value: "vicus" }],
  },
});

console.log(definitions.data.definitions);
console.log(genesis.result.data.product.metafields);
// [{ key: "marca", value: "Vicus" }]
```

La clave se compara sin distinguir mayúsculas y minúsculas. Los valores `select` también se comparan así y la respuesta devuelve la opción con su escritura configurada. Los valores pertenecen al grupo: todas las variantes comparten los mismos campos. El listado de productos no los incluye; consultá el detalle para leerlos.

Para cambiar o borrar valores después de crear, usá únicamente `PATCH /api/v1/products/{product_id}/metafields`. Un string asigna el valor, `null` lo borra y las claves omitidas no cambian. Un string vacío es inválido; un campo obligatorio no se puede borrar.

```typescript theme={null}
await fetch(
  `https://api.lapyme.com.ar/api/v1/products/${genesis.result.data.product.id}/metafields`,
  {
    method: "PATCH",
    headers: {
      Authorization: `Bearer ${process.env.LAPYME_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      entries: [
        { key: "marca", value: "Otra" },
        { key: "temporada", value: null },
      ],
    }),
  },
);
```

`PUT /api/v1/products/{product_id}` no acepta `metafields`. Las etiquetas siguen teniendo su endpoint separado.

## Crear un producto con variantes

Enviá entre una y tres opciones y hasta 250 variantes. Cada `optionValues` debe incluir exactamente un valor para cada nombre declarado en `options`. Los SKU y las combinaciones deben ser únicos dentro de la request y de la organización.

```typescript theme={null}
const shoe = await lapyme.products.create({
  idempotencyKey: crypto.randomUUID(),
  body: {
    name: "Zapatilla clásica",
    productType: "product",
    options: ["Material", "Color", "Talle"],
    variants: [
      {
        optionValues: {
          Material: "Cuero",
          Color: "Negro",
          Talle: "40",
        },
        sku: "ZAP-CUE-NEG-40",
        cost: 700000,
        price: 1250000,
        currency: "PES",
        warehouseStocks: [
          {
            warehouseId: "550e8400-e29b-41d4-a716-446655440101",
            quantity: 5,
          },
        ],
      },
      {
        optionValues: {
          Material: "Lona",
          Color: "Blanco",
          Talle: "41",
        },
        sku: "ZAP-LON-BLA-41",
        cost: 650000,
        price: 1150000,
        currency: "PES",
      },
    ],
  },
});

console.log(shoe.result.data.product.variantGroupId);
```

La respuesta mantiene el contrato de creación existente y devuelve en `data.product` la primera variante creada. Usá `variantGroupId` para identificar el producto que agrupa toda la matriz.

## Actualizar precio

```typescript theme={null}
import { Lapyme } from "lapyme";

const lapyme = new Lapyme({
  bearerAuth: process.env["LAPYME_API_KEY"] ?? "",
});

const updated = await lapyme.products.update({
  productId: "9c692e8b-0f9a-4f7c-8b99-061a2eb188ae",
  body: {
    price: 1390000,
  },
});

console.log(updated.result.data.product.price);
```

## Ajuste masivo

Usá `lapyme.productBulkAdjustments.create` para cambios masivos de precios o costos. Es una operación de escritura: mandá `idempotencyKey`.

```typescript theme={null}
import { Lapyme } from "lapyme";

const lapyme = new Lapyme({
  bearerAuth: process.env["LAPYME_API_KEY"] ?? "",
});

const adjustment = await lapyme.productBulkAdjustments.create({
  idempotencyKey: crypto.randomUUID(),
  body: {
    target: "price",
    operationType: "increase",
    adjustmentType: "percentage",
    adjustmentValue: 10,
    selection: {
      type: "specific",
      ids: ["9c692e8b-0f9a-4f7c-8b99-061a2eb188ae"],
    },
  },
});

console.log(adjustment.result.data.productBulkAdjustment.updated);
```

<Info>
  La forma exacta de `selection` y los campos disponibles para ajustes masivos están en la referencia de `POST /api/v1/products/bulk-adjustments`.
</Info>
