Productos del Merchant
Gestiona los productos de un Merchant desde el Dashboard: los artículos vendibles por los que pagan los clientes, únicos o recurrentes.
Un producto es algo que un Merchant vende. Pertenece a una familia de productos y se vende a través de una o más ofertas que establecen los términos de cobro. Estos endpoints respaldan la pantalla de productos del Dashboard: crear, listar, actualizar, eliminar (soft delete) y restaurar.
Un producto es one_time o recurring; el tipo determina qué ofertas y precios tienen sentido para él. Los productos se eliminan con soft delete para que los pedidos históricos sigan resolviéndose a un registro real.
Estos endpoints impulsan la interfaz del Tokeflow Dashboard. Están autenticados por sesión (JWT bearer) — el token proviene de iniciar sesión en el Dashboard, no de una clave de API sk_/pk_. Las solicitudes también incluyen el header x-merchant-id, que identifica al Merchant en contexto, y el usuario que inició sesión debe ser miembro con acceso a él.
El objeto producto
Devuelto por los endpoints de listado y recuperación de esta página.
| Campo | Tipo | Descripción |
|---|---|---|
id | string | — |
merchant_id | string | — |
product_family_id | string | null | — |
name | string | — |
description | string | null | — |
type | string | Uno de one_time, recurring. |
tier_order | number | null | — |
status | string | Uno de active, archived. |
metadata | object | null | — |
created_at | string | (ISO 8601 UTC). |
updated_at | string | (ISO 8601 UTC). |
Endpoints
GET/api/v1/merchant/products
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Lista los productos.
Parámetros de consulta
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
page | number | No | Número de página (indexado desde 1). Predeterminado 1, mín. 1. |
limit | number | No | Cantidad de elementos por página. Predeterminado 20, mín. 1, máx. 100. |
type | string | No | Uno de one_time, recurring. |
status | string | No | Uno de active, archived. |
product_family_id | string | No | Filtra los productos a una única familia |
name | string | No | Filtro de coincidencia parcial por el nombre del producto |
date_from | string | No | Filtra productos creados después de esta fecha (ISO 8601) |
date_to | string | No | Filtra productos creados antes de esta fecha (ISO 8601) |
Ejemplo de solicitud
curl -G https://api.tokeflow.com/api/v1/merchant/products \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9" \
--data-urlencode "page=1" \
--data-urlencode "limit=20" \
--data-urlencode "type=recurring" \
--data-urlencode "status=active"Ejemplo de respuesta — 200
{
"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:00Z",
"updated_at": "2026-05-19T12:00:00Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 42,
"total_pages": 3,
"has_next": true,
"has_prev": false
}
}POST/api/v1/merchant/products
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Crea un producto.
Campos de la solicitud
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
product_family_id | string | No | ID opcional de familia de productos para agrupar productos relacionados. Obligatorio para recurrentes con upgrade/downgrade. |
name | string | Sí | — |
description | string | No | — |
type | string | Sí | Uno de one_time, recurring. |
tier_order | number | No | Posición en la familia. Mayor = plan superior. Obligatorio cuando product_family_id está definido. |
status | string | Sí | Uno de active, archived. |
metadata | object | No | Metadatos arbitrarios (jsonb). |
Ejemplo de solicitud
curl -X POST https://api.tokeflow.com/api/v1/merchant/products \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9" \
-H "Content-Type: application/json" \
-d '{
"product_family_id": "pfa_12345",
"name": "Plano Light",
"description": "Plano com recursos essenciais",
"type": "recurring",
"tier_order": 1,
"status": "active",
"metadata": {
"source": "dashboard"
}
}'Ejemplo de respuesta — 201
{
"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:00Z",
"updated_at": "2026-05-19T12:00:00Z"
}DELETE/api/v1/merchant/products/:id
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Rechaza con 409 mientras cualquier oferta (activa) o suscripción (cualquier estado, a través de la oferta) haga referencia al producto. Elimina primero las ofertas; los productos referenciados por suscripciones se conservan para el historial de cobro.
Parámetros de ruta
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | — |
Ejemplo de solicitud
curl -X DELETE https://api.tokeflow.com/api/v1/merchant/products/obj_1a2b3c4d \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"Ejemplo de respuesta — 204 No Content
Se devuelve un cuerpo vacío en caso de éxito.
GET/api/v1/merchant/products/:id
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Obtiene un producto por ID.
Parámetros de ruta
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | — |
Ejemplo de solicitud
curl https://api.tokeflow.com/api/v1/merchant/products/obj_1a2b3c4d \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"Ejemplo de respuesta — 200
{
"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:00Z",
"updated_at": "2026-05-19T12:00:00Z"
}PATCH/api/v1/merchant/products/:id
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Actualiza un producto.
Parámetros de ruta
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | — |
Ejemplo de solicitud
curl -X PATCH https://api.tokeflow.com/api/v1/merchant/products/obj_1a2b3c4d \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9" \
-H "Content-Type: application/json" \
-d '{}'Ejemplo de respuesta — 200
{
"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:00Z",
"updated_at": "2026-05-19T12:00:00Z"
}POST/api/v1/merchant/products/:id/archive
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Archiva un producto (status = archived).
Parámetros de ruta
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | — |
Ejemplo de solicitud
curl -X POST https://api.tokeflow.com/api/v1/merchant/products/obj_1a2b3c4d/archive \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"Ejemplo de respuesta — 201
{
"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:00Z",
"updated_at": "2026-05-19T12:00:00Z"
}GET/api/v1/merchant/products/:id/default-offer
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Obtiene la oferta predeterminada de un producto (null si no hay ninguna).
Parámetros de ruta
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | — |
Ejemplo de solicitud
curl https://api.tokeflow.com/api/v1/merchant/products/obj_1a2b3c4d/default-offer \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"Ejemplo de respuesta — 200
{}POST/api/v1/merchant/products/:id/restore
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Restaura un producto eliminado con soft delete.
Parámetros de ruta
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | — |
Ejemplo de solicitud
curl -X POST https://api.tokeflow.com/api/v1/merchant/products/obj_1a2b3c4d/restore \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"Ejemplo de respuesta — 201
{
"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:00Z",
"updated_at": "2026-05-19T12:00:00Z"
}POST/api/v1/merchant/products/:id/unarchive
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Desarchiva un producto (status = active).
Parámetros de ruta
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
id | string | Sí | — |
Ejemplo de solicitud
curl -X POST https://api.tokeflow.com/api/v1/merchant/products/obj_1a2b3c4d/unarchive \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"Ejemplo de respuesta — 201
{
"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:00Z",
"updated_at": "2026-05-19T12:00:00Z"
}Errores
Los errores usan el envelope estándar. Los casos más comunes aquí:
| HTTP | Significado |
|---|---|
400 | Parámetros inválidos o un estado que no permite esta operación. |
401 | Token de sesión del Dashboard ausente, expirado o inválido. |
403 | Autenticado, pero el usuario que inició sesión no tiene acceso a esta entidad. |
404 | El registro no existe o no es visible para esta entidad. |