Saltar al contenido
Tienda online

Carrito

Crea el carrito, agrega artículos, aplica un código y elige el envío con Storefront API.

Andrea compra dos polos desde Miraflores, en Lima. Usa el código BIENVENIDA10 y pide delivery para el jueves a las 10:00. Esta guía arma ese carrito hasta el checkout.

Requisitos

  • El slug de la tienda o un dominio configurado, en x-Store-Domain. No necesitas token de acceso.
  • Una variante publicada y métodos de envío activos. Ver Tienda headless y Zonas y tarifas.

Crea el carrito

POST /v1/carts crea un carrito en la moneda de la tienda. Guarda token: identifica el carrito en todas las llamadas.

curl -X POST https://storefront.ecomiq.pe/v1/carts \
  -H "x-Store-Domain: mi-tienda" \
  -H "Content-Type: application/json" \
  -d '{ "email": "andrea.ramos@example.com" }'
Respuesta (extracto)
{
  "token": "kP3vX9qL2mT7wR4nB8sD1A",
  "cartNumber": "C-04325176",
  "currencyCode": "PEN",
  "status": "inProgress"
}

Los ejemplos siguientes reutilizan API, headers y cart.

  • email es opcional. También va con los datos del comprador.
  • Si el cliente inició sesión, crea el carrito con su X-Customer-Session. Así usa sus precios y sus códigos reservados. Ver Cuentas de clientes.

Lee el carrito

GET /v1/carts/{cartToken} devuelve el carrito completo. Úsalo al recargar la página.

curl https://storefront.ecomiq.pe/v1/carts/<cart-token> \
  -H "x-Store-Domain: mi-tienda"
  • Un carrito sin actividad pasa a abandoned. Leerlo o cambiarlo lo reabre.
  • Un carrito completed o cancelled ya no acepta cambios. Crea otro.

Agrega artículos

POST /v1/carts/{cartToken}/items agrega una variante. Esta y las demás operaciones devuelven el carrito recalculado.

curl -X POST https://storefront.ecomiq.pe/v1/carts/<cart-token>/items \
  -H "x-Store-Domain: mi-tienda" \
  -H "Content-Type: application/json" \
  -d '{ "variantId": "7204558912004325377", "quantity": 2 }'
Respuesta (extracto)
{
  "items": [
    {
      "id": "7204558912004325450",
      "title": "Polo de algodón",
      "quantity": 2,
      "unitPrice": 79
    }
  ],
  "totals": {
    "subtotal": 158,
    "discountTotal": 0,
    "shippingTotal": 0,
    "total": 158
  }
}
  • Agregar la misma variante suma a su línea.
  • El stock se valida con la cantidad total de esa variante en el carrito.
  • Agregar, cambiar o quitar un artículo con envío borra el envío elegido de su grupo. Elige el envío al final.

Cambia la cantidad

PATCH /v1/carts/{cartToken}/items/{cartItemId} fija la cantidad de una línea. Usa el id del artículo, no el de la variante. Con 0, quita la línea.

curl -X PATCH https://storefront.ecomiq.pe/v1/carts/<cart-token>/items/7204558912004325450 \
  -H "x-Store-Domain: mi-tienda" \
  -H "Content-Type: application/json" \
  -d '{ "quantity": 3 }'

Quita un artículo

DELETE /v1/carts/{cartToken}/items/{cartItemId} quita la línea.

curl -X DELETE https://storefront.ecomiq.pe/v1/carts/<cart-token>/items/7204558912004325450 \
  -H "x-Store-Domain: mi-tienda"

Aplica un código

POST /v1/carts/{cartToken}/promotion-codes aplica un cupón. Da igual si viene en minúsculas: se guarda en mayúsculas.

curl -X POST https://storefront.ecomiq.pe/v1/carts/<cart-token>/promotion-codes \
  -H "x-Store-Domain: mi-tienda" \
  -H "Content-Type: application/json" \
  -d '{ "code": "bienvenida10" }'

El código queda en promotionCodes. Con 10 % sobre S/ 158, totals.discountTotal queda en -15.8 y totals.total, en 142.2.

  • Si el carrito no cumple las condiciones del cupón, el código se guarda igual, pero no descuenta hasta que las cumpla.

Quita un código

DELETE /v1/carts/{cartToken}/promotion-codes/{code} quita el código y recalcula el total.

curl -X DELETE https://storefront.ecomiq.pe/v1/carts/<cart-token>/promotion-codes/BIENVENIDA10 \
  -H "x-Store-Domain: mi-tienda"

Agrega los datos del comprador

PATCH /v1/carts/{cartToken}/buyer guarda el contacto y el documento del comprador.

curl -X PATCH https://storefront.ecomiq.pe/v1/carts/<cart-token>/buyer \
  -H "x-Store-Domain: mi-tienda" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "andrea.ramos@example.com", "phone": "+51987654321",
    "firstName": "Andrea", "lastName": "Ramos",
    "identificationType": "DNI", "identificationNumber": "45678912"
  }'
  • Envía todos los datos en cada llamada: los que omitas quedan vacíos. Solo invoiceType se conserva si no lo envías.
  • Para factura, envía invoiceType: "invoice", el RUC en entityTaxId y la razón social en entityName.

Arma el formulario de dirección

Los selectores de departamento, provincia y distrito salen del catálogo de ubigeos. Pide cada nivel con el code del anterior: departments, provinces y districts.

curl https://storefront.ecomiq.pe/v1/geo/departments -H "x-Store-Domain: mi-tienda"
curl "https://storefront.ecomiq.pe/v1/geo/provinces?departmentCode=15" -H "x-Store-Domain: mi-tienda"
curl "https://storefront.ecomiq.pe/v1/geo/districts?provinceCode=1501" -H "x-Store-Domain: mi-tienda"

Cada área trae id, code y name, por ejemplo 150122 y Miraflores. En Perú, code es el ubigeo del INEI y source vale inei.

  • Sin countryCode, usa PE. Cada lista llega ordenada por nombre, con hasta 200 áreas.
  • Para precargar una dirección guardada, resuelve su ubigeo con GET /v1/geo/resolve. Envía countryCode=PE, source=inei y el ubigeo en code.

Guarda la dirección

PATCH /v1/carts/{cartToken}/addresses guarda la dirección de envío. Si no envías billingAddress, el checkout usa la de envío.

curl -X PATCH https://storefront.ecomiq.pe/v1/carts/<cart-token>/addresses \
  -H "x-Store-Domain: mi-tienda" \
  -H "Content-Type: application/json" \
  -d '{
    "shippingAddress": {
      "name": "Andrea Ramos", "phone": "+51987654321",
      "address1": "Av. Larco 1234", "address2": "Dpto. 501",
      "department": "Lima", "departmentCode": "15",
      "province": "Lima", "provinceCode": "1501",
      "district": "Miraflores", "districtCode": "150122",
      "city": "Lima", "postalCode": "15074", "countryCode": "PE"
    }
  }'
  • En Perú, department, province y district son obligatorios, además de name, address1, city y countryCode.
  • Si envías códigos, envía los tres. Cada uno empieza por el anterior: 15, 1501, 150122. Las cotizaciones y los horarios usan esos códigos.
  • Cada PATCH reemplaza la dirección: sin códigos, se borran los que tenía.
  • Si ya elegiste envío, cambiar la dirección lo vuelve a cotizar. Si ya no aplica o cambió de precio, se quita.

Lista las opciones de envío

GET /v1/carts/{cartToken}/shipping-options cotiza el envío con la dirección del carrito. Agrupa los artículos por vendedor y perfil de envío.

curl https://storefront.ecomiq.pe/v1/carts/<cart-token>/shipping-options \
  -H "x-Store-Domain: mi-tienda"
Respuesta (extracto)
{
  "groups": [
    {
      "sellerId": "7204558912004325305",
      "shippingProfileId": "7204558912004329819",
      "rates": [
        {
          "shippingMethodId": "7204558912004325207",
          "rateId": "7204558912004322088",
          "name": "Delivery Lima",
          "type": "localDelivery",
          "target": "location",
          "targetId": "7204558912004325563",
          "price": 10,
          "serviceCode": null
        }
      ]
    }
  ]
}
  • Elige una tarifa por grupo.
  • Si ningún artículo requiere envío, groups llega vacío.
  • Sin dirección, puedes cotizar con ?postalCode=15074.

Consulta los horarios

GET /v1/carts/{cartToken}/shipping-methods/{shippingMethodId}/slots devuelve los horarios de un día. Envía target, targetId y rateId de la tarifa, y la fecha en date.

curl -G https://storefront.ecomiq.pe/v1/carts/<cart-token>/shipping-methods/7204558912004325207/slots \
  -H "x-Store-Domain: mi-tienda" \
  -d target=location -d targetId=7204558912004325563 \
  -d rateId=7204558912004322088 -d date=2026-10-08
Respuesta (extracto)
{
  "date": "2026-10-08",
  "capacity": 30,
  "scheduledCount": 12,
  "slots": ["10:00:00", "12:00:00"]
}
  • Solo pickup y localDelivery tienen horarios.
  • Las horas son locales de la tienda. capacity es el cupo del día y scheduledCount, lo ya reservado.
  • Si el día está cerrado o lleno, slots llega vacío. Prueba otra fecha.

Elige el envío

PUT /v1/carts/{cartToken}/shipping-method guarda la tarifa elegida. Copia shippingMethodId, rateId, target, targetId y serviceCode de la tarifa, y sellerId y shippingProfileId del grupo. En el código, shippingOptions es la respuesta de las opciones de envío.

curl -X PUT https://storefront.ecomiq.pe/v1/carts/<cart-token>/shipping-method \
  -H "x-Store-Domain: mi-tienda" \
  -H "Content-Type: application/json" \
  -d '{
    "shippingProfileId": "7204558912004329819",
    "shippingMethodId": "7204558912004325207", "rateId": "7204558912004322088",
    "target": "location", "targetId": "7204558912004325563",
    "scheduledDate": "2026-10-08", "scheduledTime": "10:00:00"
  }'

La respuesta trae el envío en shippingMethods. totals.shippingTotal vale 10 y totals.total, 152.2.

  • Con target: "automatic", targetId va en null.
  • scheduledDate y scheduledTime van juntos o no van. La hora es la de slots, sin zona horaria.

Quita el envío

DELETE /v1/carts/{cartToken}/shipping-method quita el envío elegido de todos los grupos. Con sellerId o shippingProfileId, solo el de ese grupo.

curl -X DELETE "https://storefront.ecomiq.pe/v1/carts/<cart-token>/shipping-method?shippingProfileId=7204558912004329819" \
  -H "x-Store-Domain: mi-tienda"

Pasa al checkout

El checkout pide artículos, correo, dirección de envío y un envío por cada grupo con artículos que se envían. Sigue en Checkout y pago.

El checkout vuelve a calcular los descuentos. Si un código dejó de aplicar, responde 409 con Promotions.CodeNoLongerApplies; si se agotó una promoción automática, con Promotions.NoLongerApplies.

Errores

Lee code en el cuerpo del error.

codeEstadoQué hacer
Carts.NotFound404El token no existe en la tienda. Crea otro carrito.
Carts.NotActive400El carrito ya se compró o se canceló. Crea otro.
Checkout.InProgress409Hay un checkout en curso. Espera y lee el carrito.
Common.Validation400Falta un campo o tiene otro formato. Revisa errors.
Catalog.VariantNotFound404La variante no existe o no está publicada en la tienda.
Catalog.InsufficientStock400No hay stock para esa cantidad. Bájala.
Promotions.CodeNotFound400El código no existe.
Promotions.CodeLimitReached400El cupón se agotó.
Promotions.CodeInactive400El cupón está inactivo, aún no empieza o venció.
ShippingMethods.RateNotFound400La tarifa ya no aplica. Lista las opciones otra vez.
ShippingMethods.GroupRequired400Envía sellerId y shippingProfileId del grupo.
ShippingMethods.InvalidSchedule400El horario no está disponible. Consulta los horarios.

Con un token que no existe, las demás operaciones responden 404 sin cuerpo. Más códigos de cupón en Promociones y cupones.

Siguientes pasos

Última actualización:

En esta página