Ir al contenido principal
API para mentores

Checkouts

Arma páginas de pago con uno o varios productos, bumps, descuentos, diseño e imágenes.

Escrito por Jacobo

Última actualización Hace 23 días

Un checkout es una página de venta que agrupa uno o varios de tus productos publicados, con su propio precio, bumps (productos adicionales), descuento y diseño.

MétodoRutaQué hace
POST/checkoutsCrea un borrador
GET/checkoutsLista tus checkouts (paginado)
GET/checkouts?external_ref=…Busca un checkout por tu identificador
GET/checkouts/{id}Devuelve el checkout y su estado
PATCH/checkouts/{id}Edita el borrador
POST/checkouts/{id}/publishPublica y genera el checkout_url
POST/checkouts/{id}/unpublishLo retira y vuelve a borrador
POST / DELETE / PATCH/checkouts/{id}/imagesGestiona las imágenes (ver abajo)

Los checkouts no tienen historial de versiones: version_id siempre es null y no existe la ruta /versions. Archivar un checkout solo se puede hacer desde el Hub; un checkout archivado responde 404 en la API.

Body

CampoDescripción
external_refTu identificador para este checkout
nameNombre interno del checkout
slugParte final del link de pago (/c/{slug}). Requerido para publicar
product_idsIds de programas / programas externos incluidos
bootcamp_idsIds de talleres incluidos
bonus_idsIds de productos de regalo
commercialPrecio, cuotas o suscripciones (ver Configuración comercial)
discount{ "type": "fixed", "amount": 99 } o { "type": "percentage", "percentage": 20 }
bumpsLista de { enabled, product_id, price }
designOpciones de diseño, p. ej. thank_you: { enabled, title }
coproductionLista de { mentor_id, percentage }

Reglas importantes:

  • Los productos incluidos (product_ids, bootcamp_ids) y los de los bumps deben estar publicados y ser tuyos. Un borrador, un producto ajeno o un id desconocido se rechazan.
  • discount.type: "fixed": amount es el precio total a pagar (en la moneda base), no un monto a restar. discount.type: "percentage" sí es un descuento porcentual.
  • bumps: cada bump lleva su propio price en la moneda base.
  • Un checkout vende o un pago único (precio, descuento, cuotas) o una lista de planes de suscripción, no ambos.
  • El body no acepta URLs de imagen (design es estricto: un thumbnail_url devuelve 400). Las imágenes se suben aparte.

Al crear, la API ya rechaza con 422 una coproducción inválida o un precio mayor a la suma de los productos incluidos. Al editar (PATCH), name es obligatorio y los demás campos que omitas conservan su valor.

Un borrador puede estar incompleto. Para publicar necesita: slug, al menos un producto, miniatura, un precio cobrable mayor a cero y una coproducción válida.

Lo que la API no expone (testimonios, temporizador, captura de teléfono, diseño avanzado de hero/lateral) arranca vacío y se puede completar después desde el Hub.

Ejemplo — crear un borrador

POST /api/ext/checkouts
Authorization: Bearer sk_<tu-api-key>
Content-Type: application/json

{
  "external_ref": "mi-plataforma-oferta-42",
  "name": "Oferta Black Friday",
  "slug": "black-friday",
  "product_ids": ["6ab8...f001"],
  "bonus_ids": ["6ab8...b001"],
  "commercial": {
    "base_currency": "USD",
    "pricing": [{ "currency": "USD", "value": 149.0 }]
  },
  "discount": { "type": "fixed", "amount": 99.0 },
  "bumps": [{ "enabled": true, "product_id": "6ab8...f002", "price": 19.0 }],
  "design": { "thank_you": { "enabled": true, "title": "¡Gracias por tu compra!" } }
}

Respuesta 201 Created:

{
  "id": "6ab8...c001",
  "type": "checkout",
  "external_ref": "mi-plataforma-oferta-42",
  "state": "draft",
  "version_id": null,
  "checkout_url": null,
  "created_at": "2026-01-01T00:00:00Z",
  "updated_at": "2026-01-01T00:00:00Z"
}

Estados y checkout_url

EstadoSignificado
draftBorrador editable. checkout_url es null
publishedActivo. checkout_url = https://<dominio-de-checkout>/c/{slug}

Al despublicar, el checkout sale de línea y vuelve a borrador (state: "draft"), listo para editarse y publicarse de nuevo.

Imágenes del checkout

Las imágenes se suben como archivo (multipart/form-data) al borrador. Si el checkout ya está publicado, el cambio queda en un borrador y llega al comprador cuando vuelvas a publicar.

POST   /checkouts/{id}/images                 multipart; el NOMBRE DEL CAMPO es el slot
DELETE /checkouts/{id}/images?slot=&index=
PATCH  /checkouts/{id}/images                 JSON { "slot", "order": [...] }

SlotTipoOperaciones
thumbnailúnicoPOST (reemplaza)
offer_headerúnicoPOST (reemplaza)
offer_midúnicoPOST (reemplaza)
offer_footerúnicoPOST (reemplaza)
offer_sidelista (máx. 6)POST agrega / reemplaza, DELETE, PATCH reordena
carousellista (máx. 10)POST agrega / reemplaza, DELETE, PATCH reordena

  • Una imagen por request. Formatos JPEG, PNG o WEBP, máximo 10 MB.
  • alt (opcional, cualquier slot): texto alternativo / pie de imagen.
  • Slots únicos: solo el archivo (y alt). No aceptan index.
  • Slots de lista: POST sin index agrega al final; con index=<n> reemplaza esa posición. DELETE ?slot=&index=<n> elimina una. PATCH { "slot", "order" } reordena; order debe ser una permutación de los índices actuales.
  • Video de YouTube en el carrusel: en lugar de un archivo, envía el campo carousel como texto con el link de YouTube (o el id de 11 caracteres). Solo carousel acepta video.

Ejemplo:

curl -X POST https://hub.grou.com/api/ext/checkouts/6ab8...c001/images \
  -H "Authorization: Bearer sk_<tu-api-key>" \
  -F "carousel=@slide.png" \
  -F "alt=Vista del curso"

Respuesta 200 OK:

{
  "media": {
    "slot": "carousel",
    "url": "https://storage.googleapis.com/.../slide-<uuid>.png",
    "content_type": "image/png",
    "index": 0
  },
  "resource": { "id": "6ab8...c001", "type": "checkout", "state": "draft", "version_id": null, "checkout_url": null }
}

media.index solo aparece en los slots de lista.