Transiciones de oferta del Merchant
Administra las reglas de facturación por par para cambios de plan desde el dashboard del Merchant — lista, crea, actualiza y elimina transiciones de oferta con una sesión del dashboard.
Una transición de oferta es una regla de facturación por par para cambios de plan. Fija un movimiento específico from_offer_id → to_offer_id — una mejora, una degradación o un cambio de plan dentro de la misma familia de productos — a una regla de facturación (change_charge_behavior) y a un conmutador de encendido/apagado (is_active). Cuando una suscripción cambia entre ese par exacto de ofertas, la regla de la transición tiene prioridad sobre el valor predeterminado de la familia de productos.
Estos endpoints son la superficie detrás de las pantallas de catálogo del dashboard: la tabla de transiciones, el diálogo de creación y los controles de activar/desactivar y eliminar. Operan sobre las mismas filas de transición subyacentes que la API pública de transiciones de oferta — una regla creada aquí es visible de inmediato allí, y viceversa.
Los endpoints del Dashboard alimentan la Tokeflow Dashboard UI. Están autenticados por sesión: inicia sesión para obtener un JWT y envíalo como token bearer. No aceptan claves de API sk_ ni pk_ — para automatización programática del catálogo, usa la API pública de transiciones de oferta en su lugar.
Todos los endpoints de esta página también requieren el header x-merchant-id:
| Header | Tipo | Obligatorio | Descripción |
|---|---|---|---|
x-merchant-id | string | Sí | El Merchant cuyo catálogo estás gestionando, con el prefijo mrc_. Selecciona el contexto de Merchant activo cuando tu cuenta pertenece a más de un Merchant. |
Cómo entra en vigor una transición
Crear, desactivar o eliminar una transición cambia qué regla de facturación se aplica la próxima vez que una suscripción se traslada entre el par:
Una transición inactiva o eliminada nunca bloquea un cambio de plan — el movimiento simplemente recurre al change_charge_behavior predeterminado de la familia de productos. Desactivar (PATCH) es reversible; eliminar no lo es.
El motor de transiciones ejecuta los tres comportamientos — next_renew, prorated y override. El change_charge_behavior que definas en un par es el que se aplica cuando una suscripción se traslada entre esas ofertas.
El objeto de transición de oferta
| Field | Type | Description |
|---|---|---|
id | string | Identificador único, con el prefijo oft_. |
from_offer_id | string | La oferta de la que se traslada la suscripción. Con el prefijo ofr_. |
to_offer_id | string | La oferta a la que se traslada la suscripción. Con el prefijo ofr_. Debe pertenecer a la misma familia de productos que from_offer_id. |
change_charge_behavior | enum | null | Anulación por par del change_charge_behavior de la familia de productos — next_renew, prorated u override. null significa recurrir al valor predeterminado de la familia. |
is_active | boolean | Si la transición está activa (elegible para procesamiento). Las transiciones inactivas se ignoran y se aplica el valor predeterminado de la familia. |
created_at | string | Marca de tiempo de creación ISO 8601 UTC. |
updated_at | string | Marca de tiempo de última actualización ISO 8601 UTC. |
Los tres valores de change_charge_behavior:
| Value | Meaning |
|---|---|
next_renew | Aplica el cambio en la siguiente renovación — el nuevo precio entra en vigor en el ciclo de facturación posterior. |
prorated | Prorratea la diferencia para el ciclo actual. |
override | Reemplaza el cargo actual con los términos de la nueva oferta de inmediato. |
Los endpoints del Dashboard devuelven el objeto directamente — no hay un envoltorio success/data alrededor de las respuestas de un solo recurso.
Endpoints
GET/api/v1/merchant/offer-transitions
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Devuelve una lista paginada de las transiciones de oferta del Merchant. Esta es la consulta detrás de la tabla de transiciones del dashboard, incluidos sus filtros de oferta y estado.
Parámetros de consulta
| Field | Type | Required | Description |
|---|---|---|---|
page | number | No | Número de página, indexado desde 1. Predeterminado 1. |
limit | number | No | Elementos por página. Predeterminado 20, mín. 1, máx. 100. |
from_offer_id | string | No | Filtra las transiciones originadas en una oferta específica. |
to_offer_id | string | No | Filtra las transiciones dirigidas a una oferta específica. |
is_active | boolean | No | Filtra solo las transiciones activas (envía true). |
change_charge_behavior | string | No | Filtra por regla de facturación — next_renew, prorated u override. |
Ejemplo de solicitud
curl -G https://api.tokeflow.com/api/v1/merchant/offer-transitions \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs…" \
-H "x-merchant-id: mrc_123" \
--data-urlencode "page=1" \
--data-urlencode "limit=20" \
--data-urlencode "is_active=true"Ejemplo de respuesta — 200 OK
{
"data": [
{
"id": "oft_a1b2c3d4e5",
"from_offer_id": "ofr_3hk9d2",
"to_offer_id": "ofr_7pq4m1",
"change_charge_behavior": "next_renew",
"is_active": true,
"created_at": "2026-05-19T12:00:00Z",
"updated_at": "2026-05-19T12:00:00Z"
},
{
"id": "oft_f6g7h8i9j0",
"from_offer_id": "ofr_7pq4m1",
"to_offer_id": "ofr_3hk9d2",
"change_charge_behavior": null,
"is_active": true,
"created_at": "2026-06-02T15:45:00Z",
"updated_at": "2026-06-02T15:45:00Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 2,
"total_pages": 1,
"has_next": false,
"has_prev": false
}
}La segunda transición del ejemplo establece change_charge_behavior como null — la fila existe por su conmutador is_active, y la regla de facturación recurre al valor predeterminado de la familia.
Metadatos de paginación
| Field | Type | Description |
|---|---|---|
page | number | Número de página actual. |
limit | number | Número de elementos por página. |
total | number | Número total de elementos. |
total_pages | number | Número total de páginas. |
has_next | boolean | Si hay una página siguiente. |
has_prev | boolean | Si hay una página anterior. |
POST/api/v1/merchant/offer-transitions
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Crea una transición de oferta para un par from_offer_id → to_offer_id. Ambas ofertas deben pertenecer a la misma familia de productos.
Campos de la solicitud
| Field | Type | Required | Description |
|---|---|---|---|
from_offer_id | string | Sí | Oferta de la que se traslada la suscripción, con el prefijo ofr_. |
to_offer_id | string | Sí | Oferta a la que se traslada la suscripción, con el prefijo ofr_. Debe pertenecer a la misma familia de productos que from_offer_id. |
change_charge_behavior | string | No | Anula el change_charge_behavior de la familia de productos para este par — next_renew, prorated u override. Omítelo o envía null para recurrir al valor predeterminado de la familia. El motor procesa los tres comportamientos. |
is_active | boolean | No | Si esta transición está activa (elegible para procesamiento). El valor predeterminado es true. |
Ejemplo de solicitud
curl -X POST https://api.tokeflow.com/api/v1/merchant/offer-transitions \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs…" \
-H "x-merchant-id: mrc_123" \
-H "Content-Type: application/json" \
-d '{
"from_offer_id": "ofr_3hk9d2",
"to_offer_id": "ofr_7pq4m1",
"change_charge_behavior": "next_renew",
"is_active": true
}'Ejemplo de respuesta — 201 Created
{
"id": "oft_a1b2c3d4e5",
"from_offer_id": "ofr_3hk9d2",
"to_offer_id": "ofr_7pq4m1",
"change_charge_behavior": "next_renew",
"is_active": true,
"created_at": "2026-05-19T12:00:00Z",
"updated_at": "2026-05-19T12:00:00Z"
}Se devuelve un 400 cuando to_offer_id no pertenece a la misma familia de productos que from_offer_id, o cuando change_charge_behavior no es uno de los tres valores permitidos.
GET/api/v1/merchant/offer-transitions/:id
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Recupera una única transición de oferta por ID. Devuelve el objeto de transición de oferta.
Ejemplo de solicitud
curl https://api.tokeflow.com/api/v1/merchant/offer-transitions/oft_a1b2c3d4e5 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs…" \
-H "x-merchant-id: mrc_123"Ejemplo de respuesta — 200 OK
{
"id": "oft_a1b2c3d4e5",
"from_offer_id": "ofr_3hk9d2",
"to_offer_id": "ofr_7pq4m1",
"change_charge_behavior": "next_renew",
"is_active": true,
"created_at": "2026-05-19T12:00:00Z",
"updated_at": "2026-05-19T12:00:00Z"
}Se devuelve un 404 si la transición no existe o no pertenece al Merchant en x-merchant-id.
PATCH/api/v1/merchant/offer-transitions/:id
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Actualiza una transición de oferta. El payload es un objeto parcial — envía solo los campos que quieras cambiar. Las actualizaciones más comunes son alternar is_active (el control de activar/desactivar del dashboard) y ajustar change_charge_behavior, incluido establecerlo en null para recurrir al valor predeterminado de la familia.
Para redirigir una regla a un par de ofertas distinto, es preferible eliminar la transición y crear una nueva — el par from_offer_id → to_offer_id es la identidad de la transición.
Ejemplo de solicitud — desactivar una transición
curl -X PATCH https://api.tokeflow.com/api/v1/merchant/offer-transitions/oft_a1b2c3d4e5 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs…" \
-H "x-merchant-id: mrc_123" \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'Ejemplo de respuesta — 200 OK
{
"id": "oft_a1b2c3d4e5",
"from_offer_id": "ofr_3hk9d2",
"to_offer_id": "ofr_7pq4m1",
"change_charge_behavior": "next_renew",
"is_active": false,
"created_at": "2026-05-19T12:00:00Z",
"updated_at": "2026-08-12T09:30:00Z"
}Mientras is_active sea false, el par se factura según el change_charge_behavior predeterminado de la familia de productos. Reactívalo en cualquier momento con { "is_active": true }.
DELETE/api/v1/merchant/offer-transitions/:id
Auth: Dashboard session (JWT bearer). Se requiere membresía del Merchant.
Elimina una transición de oferta. A partir de entonces, los cambios de plan entre el par siguen el change_charge_behavior predeterminado de la familia de productos.
La eliminación es permanente. Si solo quieres pausar una regla — conservando su configuración para más adelante — desactívala con PATCH y { "is_active": false } en su lugar.
Ejemplo de solicitud
curl -X DELETE https://api.tokeflow.com/api/v1/merchant/offer-transitions/oft_a1b2c3d4e5 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs…" \
-H "x-merchant-id: mrc_123"Ejemplo de respuesta — 204 No Content
La respuesta no tiene cuerpo.
Errores
| HTTP | Causa típica |
|---|---|
400 | Cuerpo o consulta inválidos — to_offer_id fuera de la familia de productos de from_offer_id, o un valor de change_charge_behavior desconocido. |
401 | Token de sesión ausente, inválido o expirado — inicia sesión de nuevo. |
403 | La cuenta de la sesión no es miembro del Merchant en x-merchant-id. |
404 | No hay ninguna transición con ese id para este Merchant. |
Consulta Errores para conocer el formato de error usado en toda la API.
Relacionados
- Transiciones de oferta (API pública) — el mismo recurso mediante claves de API
sk_, con el modelo completo de precedencia. - Familias de productos — donde vive el
change_charge_behaviorpredeterminado. - Ofertas — los pares que conecta una transición, incluido el resolutor de effective-behavior.
- Suscripciones — los cambios de plan que estas reglas gobiernan.