Productos
Crea y gestiona productos: los artículos y planes vendibles de tu catálogo de Tokeflow, agrupados en familias y con precios definidos a través de ofertas.
Un producto es algo vendible: un artículo de pago único como un curso, o un plan recurrente como un nivel de suscripción. Los productos son la capa intermedia del catálogo. Pertenecen a una familia de productos y sus precios se definen a través de una o más ofertas.
Usa los productos para modelar qué vendes. Usa las ofertas para modelar cómo se compra y se factura.
Un producto tiene un type (one_time o recurring) y un status (active o archived). Cuando un producto pertenece a una familia, su tier_order lo posiciona dentro de esa familia —un valor mayor significa un plan superior— lo que impulsa las rutas de mejora (upgrade) y degradación (downgrade) entre planes recurrentes.
Tokeflow es una plataforma de orquestación de pagos, no un procesador de pagos. El catálogo modela tus precios; la autorización, captura y liquidación reales de cualquier cargo ocurren en el proveedor de pagos conectado. Los objetos del catálogo nunca mueven dinero.
El objeto producto
{
"id": "prd_a1b2c3d4e5",
"merchant_id": "mrc_a1b2c3d4e5",
"product_family_id": "pfa_a1b2c3d4e5",
"name": "Plano Light",
"description": "Plano com recursos essenciais",
"type": "recurring",
"tier_order": 1,
"status": "active",
"metadata": {
"source": "dashboard"
},
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T12:00:00.000Z"
}| Field | Type | Description |
|---|---|---|
id | string | ID único del producto, con el prefijo prd_. Opaco: nunca lo analices. |
merchant_id | string | El Merchant propietario del producto (mrc_). |
product_family_id | string | null | Familia a la que pertenece este producto (pfa_), o null si es independiente. |
name | string | Nombre legible por humanos, p. ej. "Plano Light". |
description | string | null | Descripción más larga opcional. |
type | enum | one_time o recurring. |
tier_order | integer | null | Posición dentro de la familia (mayor = plan superior). null cuando el producto no tiene familia. |
status | enum | active o archived. |
metadata | object | null | Datos clave/valor arbitrarios que adjuntas. Se devuelven tal cual. |
created_at | string | Marca de tiempo de creación en ISO 8601 UTC. |
updated_at | string | Marca de tiempo de la última actualización en ISO 8601 UTC. |
Enumeraciones
| Enum | Values |
|---|---|
type | one_time, recurring |
status | active, archived |
tier_order es obligatorio siempre que se establezca product_family_id, y debe ser único dentro de la familia. Se utiliza para ordenar los planes en mejoras (upgrades) y degradaciones (downgrades). Para un producto independiente (sin familia), déjalo sin establecer.
Crear un producto
POST/api/v1/products
Auth: clave de Organization (con merchant_id) o clave de Merchant. Ámbito: products:write.
Crea un producto bajo un Merchant. Combina esta creación con una clave de idempotencia cuando sean posibles los reintentos.
Parámetros del cuerpo
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Sí | Nombre del producto. |
type | enum | Sí | one_time o recurring. |
status | enum | Sí | active o archived. |
product_family_id | string | No | Familia bajo la cual agrupar el producto (pfa_). Obligatorio para productos recurrentes que participan en flujos de mejora/degradación. |
tier_order | integer | Condicional | Posición dentro de la familia (mín. 0, mayor = superior). Obligatorio cuando se establece product_family_id. |
description | string | No | Descripción opcional. |
metadata | object | No | Metadatos arbitrarios a adjuntar. |
Con una clave de Organization, incluye merchant_id en el cuerpo de la solicitud para dirigirte a un Merchant. Con una clave de Merchant, el Merchant se infiere a partir de la clave: omítelo.
curl -X POST https://api.tokeflow.com/api/v1/products \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9b1f7e0a-2c3d-4e5f-8a9b-0c1d2e3f4a5b" \
-d '{
"name": "Plano Light",
"type": "recurring",
"status": "active",
"product_family_id": "pfa_a1b2c3d4e5",
"description": "Plano com recursos essenciais",
"tier_order": 1,
"metadata": { "source": "dashboard" }
}'Respuesta 201 Created
{
"success": true,
"data": {
"id": "prd_a1b2c3d4e5",
"merchant_id": "mrc_a1b2c3d4e5",
"product_family_id": "pfa_a1b2c3d4e5",
"name": "Plano Light",
"description": "Plano com recursos essenciais",
"type": "recurring",
"tier_order": 1,
"status": "active",
"metadata": { "source": "dashboard" },
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T12:00:00.000Z"
},
"request_id": "req_8f3c…",
"timestamp": "2026-05-19T12:00:00.000Z"
}tier_order debe ser único dentro de una familia. Reutilizar un tier_order ya ocupado por otro producto de la misma familia devuelve 409 (conflict_error).
Listar productos
GET/api/v1/products
Auth: clave de Organization (con merchant_id) o clave de Merchant. Ámbito: products:read.
Devuelve una lista paginada de productos del Merchant, los más recientes primero. Todos los filtros son opcionales y se combinan con AND.
Parámetros de consulta
| Field | Type | Required | Description |
|---|---|---|---|
page | integer | No | Número de página, indexado desde 1. Predeterminado 1. |
limit | integer | No | Elementos por página. Predeterminado 20, máximo 100. |
type | enum | No | Filtra por one_time o recurring. |
status | enum | No | Filtra por active o archived. |
product_family_id | string | No | Restringe a una sola familia (pfa_). |
name | string | No | Coincidencia parcial, sin distinción de mayúsculas y minúsculas, en el nombre del producto. |
date_from | string | No | Solo productos creados en o después de esta marca de tiempo ISO 8601. |
date_to | string | No | Solo productos creados en o antes de esta marca de tiempo ISO 8601. |
merchant_id | string | Condicional | Obligatorio con una clave de Organization para dirigirse a un Merchant. |
curl "https://api.tokeflow.com/api/v1/products?page=1&limit=20&type=recurring&status=active&product_family_id=pfa_a1b2c3d4e5&name=Pro&date_from=2026-01-01T00:00:00Z&date_to=2026-12-31T23:59:59Z" \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 200 OK
{
"success": true,
"data": [
{
"id": "prd_a1b2c3d4e5",
"merchant_id": "mrc_a1b2c3d4e5",
"product_family_id": "pfa_a1b2c3d4e5",
"name": "Plano Light",
"description": "Plano com recursos essenciais",
"type": "recurring",
"tier_order": 1,
"status": "active",
"metadata": { "source": "dashboard" },
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T12:00:00.000Z"
},
{
"id": "prd_f6e5d4c3b2",
"merchant_id": "mrc_a1b2c3d4e5",
"product_family_id": "pfa_a1b2c3d4e5",
"name": "Plano Pro",
"description": "Plano com recursos avançados",
"type": "recurring",
"tier_order": 2,
"status": "active",
"metadata": null,
"created_at": "2026-05-19T12:05:00.000Z",
"updated_at": "2026-05-19T12:05:00.000Z"
}
],
"meta": {
"pagination": {
"page": 1,
"limit": 20,
"total": 2,
"total_pages": 1,
"has_next": false,
"has_prev": false
}
},
"request_id": "req_8f3c…",
"timestamp": "2026-05-19T12:30:00.000Z"
}Consulta Paginación y filtrado para conocer las convenciones compartidas.
Obtener un producto
GET/api/v1/products/:id
Auth: clave de Organization (con merchant_id) o clave de Merchant. Ámbito: products:read.
Recupera un único producto por su ID.
curl https://api.tokeflow.com/api/v1/products/prd_a1b2c3d4e5 \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 200 OK
{
"success": true,
"data": {
"id": "prd_a1b2c3d4e5",
"merchant_id": "mrc_a1b2c3d4e5",
"product_family_id": "pfa_a1b2c3d4e5",
"name": "Plano Light",
"description": "Plano com recursos essenciais",
"type": "recurring",
"tier_order": 1,
"status": "active",
"metadata": { "source": "dashboard" },
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T12:00:00.000Z"
},
"request_id": "req_8f3c…",
"timestamp": "2026-05-19T12:30:00.000Z"
}Un ID desconocido devuelve 404 (not_found_error).
Actualizar un producto
PATCH/api/v1/products/:id
Auth: clave de Organization (con merchant_id) o clave de Merchant. Ámbito: products:write.
Actualización parcial. Envía solo los campos que quieras cambiar; los campos omitidos se dejan intactos.
Parámetros del cuerpo
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Nombre nuevo. |
type | enum | No | one_time o recurring. |
status | enum | No | active o archived. |
product_family_id | string | No | Mueve el producto a otra familia. |
tier_order | integer | No | Nueva posición dentro de la familia. |
description | string | No | Nueva descripción. |
metadata | object | No | Reemplaza el objeto de metadatos almacenado. |
curl -X PATCH https://api.tokeflow.com/api/v1/products/prd_a1b2c3d4e5 \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Plano Light Plus",
"tier_order": 2
}'Respuesta 200 OK
{
"success": true,
"data": {
"id": "prd_a1b2c3d4e5",
"merchant_id": "mrc_a1b2c3d4e5",
"product_family_id": "pfa_a1b2c3d4e5",
"name": "Plano Light Plus",
"description": "Plano com recursos essenciais",
"type": "recurring",
"tier_order": 2,
"status": "active",
"metadata": { "source": "dashboard" },
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T13:00:00.000Z"
},
"request_id": "req_8f3c…",
"timestamp": "2026-05-19T13:00:00.000Z"
}metadata se reemplaza, no se combina. Para conservar las claves existentes, envía el objeto completo que quieras almacenar.
Eliminar un producto
DELETE/api/v1/products/:id
Auth: clave de Organization (con merchant_id) o clave de Merchant. Ámbito: products:write.
Elimina un producto de forma lógica (soft-delete). El registro se conserva por trazabilidad y puede recuperarse con restaurar. Un producto eliminado de forma lógica ya no aparece en los resultados de la lista.
curl -X DELETE https://api.tokeflow.com/api/v1/products/prd_a1b2c3d4e5 \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 204 No Content
Una eliminación exitosa devuelve un cuerpo vacío con el estado 204.
La eliminación lógica (soft delete) y el archivado son diferentes. Archivar mantiene el producto en tu catálogo con status: archived (visible, no vendible). Eliminar lo quita del catálogo (recuperable mediante restauración). Usa archivar para retirar un plan al que aún quieras hacer referencia; usa eliminar para sacar un producto por completo.
Restaurar un producto
POST/api/v1/products/:id/restore
Auth: clave de Organization (con merchant_id) o clave de Merchant. Ámbito: products:write.
Restaura un producto eliminado de forma lógica, devolviéndolo al catálogo con sus atributos anteriores.
curl -X POST https://api.tokeflow.com/api/v1/products/prd_a1b2c3d4e5/restore \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 201 Created
{
"success": true,
"data": {
"id": "prd_a1b2c3d4e5",
"merchant_id": "mrc_a1b2c3d4e5",
"product_family_id": "pfa_a1b2c3d4e5",
"name": "Plano Light",
"description": "Plano com recursos essenciais",
"type": "recurring",
"tier_order": 1,
"status": "active",
"metadata": { "source": "dashboard" },
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T14:00:00.000Z"
},
"request_id": "req_8f3c…",
"timestamp": "2026-05-19T14:00:00.000Z"
}Archivar un producto
POST/api/v1/products/:id/archive
Auth: clave de Organization (con merchant_id) o clave de Merchant. Ámbito: products:write.
Establece status en archived. El producto permanece en tu catálogo e historial, pero ya no se ofrece para nuevas compras.
curl -X POST https://api.tokeflow.com/api/v1/products/prd_a1b2c3d4e5/archive \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 201 Created
{
"success": true,
"data": {
"id": "prd_a1b2c3d4e5",
"merchant_id": "mrc_a1b2c3d4e5",
"product_family_id": "pfa_a1b2c3d4e5",
"name": "Plano Light",
"description": "Plano com recursos essenciais",
"type": "recurring",
"tier_order": 1,
"status": "archived",
"metadata": { "source": "dashboard" },
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T15:00:00.000Z"
},
"request_id": "req_8f3c…",
"timestamp": "2026-05-19T15:00:00.000Z"
}Desarchivar un producto
POST/api/v1/products/:id/unarchive
Auth: clave de Organization (con merchant_id) o clave de Merchant. Ámbito: products:write.
Vuelve a establecer status en active, devolviendo un producto archivado a un estado vendible.
curl -X POST https://api.tokeflow.com/api/v1/products/prd_a1b2c3d4e5/unarchive \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 201 Created
{
"success": true,
"data": {
"id": "prd_a1b2c3d4e5",
"merchant_id": "mrc_a1b2c3d4e5",
"product_family_id": "pfa_a1b2c3d4e5",
"name": "Plano Light",
"description": "Plano com recursos essenciais",
"type": "recurring",
"tier_order": 1,
"status": "active",
"metadata": { "source": "dashboard" },
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T16:00:00.000Z"
},
"request_id": "req_8f3c…",
"timestamp": "2026-05-19T16:00:00.000Z"
}Obtener la oferta predeterminada
GET/api/v1/products/:id/default-offer
Auth: clave de Organization (con merchant_id) o clave de Merchant. Ámbito: products:read.
Devuelve la oferta predeterminada del producto: la que utiliza un checkout cuando no se nombra ninguna oferta específica. Responde con data: null cuando el producto no tiene una oferta predeterminada.
curl https://api.tokeflow.com/api/v1/products/prd_a1b2c3d4e5/default-offer \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 200 OK — existe una oferta predeterminada
{
"success": true,
"data": {
"id": "ofr_a1b2c3d4e5",
"product_id": "prd_a1b2c3d4e5",
"name": "Mensal",
"slug": "mensal",
"description": "Plano mensal padrão",
"billing_cycle": "monthly",
"custom_billing_days": null,
"cycle_limit": 12,
"free_trial": false,
"trial_days": null,
"setup_charge": false,
"renew_after_cycle_limit": false,
"renewal_offer_id": null,
"is_default": true,
"status": "active",
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T12:00:00.000Z",
"prices": [
{
"id": "opr_b1c2d3e4f5",
"offer_id": "ofr_a1b2c3d4e5",
"currency": "BRL",
"amount": 9900,
"first_charge_amount": null,
"is_default": true,
"created_at": "2026-05-19T12:00:00.000Z",
"updated_at": "2026-05-19T12:00:00.000Z"
}
]
},
"request_id": "req_8f3c…",
"timestamp": "2026-05-19T12:30:00.000Z"
}Respuesta 200 OK — sin oferta predeterminada
{
"success": true,
"data": null,
"request_id": "req_8f3c…",
"timestamp": "2026-05-19T12:30:00.000Z"
}Los importes en los precios de las ofertas son enteros en unidades menores (centavos). 9900 con la moneda BRL es R$99.00. Consulta Ofertas y Precios de ofertas para conocer el modelo de precios completo.
Errores
Los productos utilizan el sobre de error estándar. Casos comunes:
| Status | type | When |
|---|---|---|
| 400 | validation_error | Campo faltante o inválido, p. ej. type o status desconocido. |
| 401 | authentication_error | Clave de API faltante o inválida. |
| 403 | authorization_error | La clave carece del ámbito products:read / products:write requerido. |
| 404 | not_found_error | No hay ningún producto con ese ID para el Merchant. |
| 409 | conflict_error | tier_order ya utilizado por otro producto de la familia. |
Consulta el catálogo de errores completo para conocer los códigos y su manejo.
Relacionado
- Familias de productos — el grupo al que pertenece un producto.
- Ofertas — configuraciones comprables y facturables de un producto.
- Precios de ofertas — variantes de importe y moneda de una oferta.
- Suscripciones — facturación recurrente impulsada por ofertas.