Suscripciones
Lee y gestiona suscripciones recurrentes — lista y recupera suscripciones, inspecciona el historial de cambios de oferta, cancela, pausa, reanuda, cambia de oferta y actualiza el instrumento de pago de la facturación.
Una suscripción es una relación de facturación de larga duración entre uno de tus clientes y una oferta. Tokeflow rastrea su ciclo de vida, impulsa las renovaciones según el ciclo de facturación de la oferta, reintenta los cobros fallidos (dunning) y registra cada cambio de estado como una transición inmutable.
Tokeflow orquesta cada cobro de renovación a través de los proveedores de pago que conectas; no procesa ni liquida fondos por sí mismo. La liquidación la realiza el proveedor conectado. Tokeflow normaliza el resultado y hace avanzar la suscripción en consecuencia.
Las suscripciones son creadas por el motor de facturación, no mediante una llamada directa a la API. El primer cobro recurrente exitoso contra una oferta acuña el registro de la suscripción. A partir de ahí, la lees y la gestionas a través de los endpoints de esta página.
Cómo encajan las suscripciones
Cada suscripción permanece dentro de una única familia de productos. Los cambios de oferta solo se permiten entre ofertas de la misma familia; moverse entre familias se modela como una cancelación más una nueva suscripción.
El objeto suscripción
Una suscripción es una instantánea desnormalizada del plan del cliente más el estado de facturación en vivo que el motor necesita para impulsarlo.
| Field | Type | Description |
|---|---|---|
id | string | Identificador único, con prefijo sub_. |
merchant_id | string | Merchant propietario de la suscripción (mrc_). |
customer_id | string | Cliente suscrito (cust_). |
customer_name | string | null | Nombre resuelto del cliente. |
customer_email | string | null | Correo electrónico resuelto del cliente. |
current_offer_id | string | Oferta que se factura actualmente (ofr_). |
offer_name | string | Nombre resuelto de la oferta. |
product_id | string | Producto de la oferta actual (prd_). |
product_name | string | Nombre resuelto del producto. |
product_family_id | string | Familia de productos a la que está vinculada la suscripción (pfa_). |
billing_cycle | enum | Uno de daily, biweekly, monthly, quarterly, half_yearly, yearly, custom, none. Copiado de la oferta en el momento de la creación. |
currency | string | Moneda ISO 4217, p. ej. BRL. |
current_amount | integer | Importe cobrado en cada ciclo, en unidades menores (centavos). |
current_period_start | string | Inicio ISO 8601 del período de facturación actual. |
current_period_end | string | Fin ISO 8601 del período de facturación actual. |
next_billing_at | string | null | Cuándo se dispara la próxima renovación. null cuando billing_cycle es none (bajo demanda). |
billing_anchor_day | integer | null | Día del mes (1–31) usado para resolver las fechas de renovación en ciclos mensuales o superiores. En un mes más corto, la renovación cae en el último día del mes, y la siguiente vuelve al día de anclaje. Consulta Fechas de facturación. |
trial_start | string | null | Inicio de la prueba, establecido después de que se confirma el cobro de configuración de la prueba. |
trial_end | string | null | Fin de la prueba. Coincide con la fecha del primer cobro real. |
dunning_started_at | string | null | Cuándo la suscripción entró por primera vez en dunning. |
dunning_attempt_count | integer | Número de reintentos de dunning ejecutados. Se restablece a 0 tras un cobro exitoso. |
dunning_next_retry_at | string | null | Cuándo está programado el próximo reintento de dunning. |
cycles_completed | integer | Recuento de ciclos facturados con éxito. |
cycle_limit | integer | null | Máximo de ciclos. null significa facturar hasta que se cancele. |
status | enum | Estado del ciclo de vida — consulta Ciclo de vida. |
cancel_at_period_end | boolean | Cuando es true, la suscripción se cancela en current_period_end en lugar de inmediatamente. |
cancelled_at | string | null | Cuándo surtió efecto la cancelación. |
cancellation_reason | string | null | Motivo persistido en la cancelación. |
payment_instrument_id | string | Instrumento de pago que se cobra en la renovación (pi_). |
preferred_connector_name | string | Nombre resuelto de la conexión a la que se enrutan las renovaciones. |
preferred_installments | integer | Número de cuotas heredado del cobro inicial. 1 es un cobro único. |
created_at | string | Marca de tiempo ISO 8601 de creación. |
updated_at | string | Marca de tiempo ISO 8601 de la última actualización. |
current_amount y currency están desnormalizados en la suscripción para que las renovaciones sean deterministas. Se actualizan cuando cambias la oferta.
Ciclo de vida
Una suscripción pasa por seis estados. El motor de facturación impulsa la mayoría de las transiciones; el resto las impulsas tú a través de los endpoints de abajo.
| Status | Meaning |
|---|---|
trialing | En una prueba gratuita. Aún no se ha cobrado ningún importe recurrente. |
active | Facturando normalmente según lo programado. |
dunning | Un cobro de renovación falló; el motor está reintentando. Consulta Dunning. |
paused | La facturación está suspendida. No se disparan renovaciones hasta que se reanude. |
cancelled | Terminada. Sin más facturación. Terminal. |
expired | Alcanzó su límite de ciclos y terminó. Terminal. |
Fechas de facturación
Los ciclos mensuales, trimestrales, semestrales y anuales se renuevan en billing_anchor_day. Cuando el mes de destino es más corto que el día de anclaje, la renovación cae en el último día de ese mes — una suscripción anclada el día 31 se renueva el 28 de febrero (29 en un año bisiesto) y luego el 31 de marzo —, de modo que no se salta ningún mes. current_period_end siempre es igual a la fecha de renovación anclada (next_billing_at), así que la fecha pagada hasta la que se muestra en la API, en los webhooks y al cancelar nunca se queda corta. Un cambio de plan conserva el anclaje existente de la suscripción. Los ciclos basados en días (daily, biweekly) y los planes bajo demanda no están anclados.
Dunning
Cuando un cobro de renovación falla, la suscripción entra en dunning en lugar de cancelarse de inmediato. El motor programa reintentos en dunning_next_retry_at, incrementando dunning_attempt_count en cada intento.
Una renovación nunca se reintenta dentro de la misma solicitud, y la forma de tratar un rechazo depende de su motivo de rechazo, igual para todos los proveedores. Un motivo que indica que la tarjeta no podrá volver a cobrarse nunca — perdida o robada, cuenta cerrada, autorización revocada, fraude confirmado, un emisor que indica no reintentar nunca — cancela la suscripción de inmediato. Cualquier otro rechazo, incluida una tarjeta caducada o datos de tarjeta incorrectos, pasa a dunning para que el cliente pueda actualizar la tarjeta.
- Un reintento que tiene éxito devuelve la suscripción a
activey restablece los contadores de dunning. - Si los reintentos se agotan, la suscripción se cancela.
- Mientras está en dunning, el cliente puede solucionar el problema cambiando a una tarjeta que funcione — consulta Cambiar el instrumento de pago.
Si usas la capacidad de Account Updater, una actualización de tarjeta enviada por el emisor sobre un instrumento en dunning puede acelerar automáticamente el próximo reintento — sin necesidad de una llamada adicional.
Retenciones de facturación (billing hold)
Una renovación solo se cobra cuando el merchant tiene un conector activo para enrutarla, el proveedor todavía acepta las credenciales de ese conector y la oferta de la suscripción sigue disponible. Si falta cualquiera de estas condiciones en el momento de la renovación, el motor coloca la renovación en una retención de facturación temporal, en lugar de cobrar sobre una configuración inválida: no se intenta ningún cobro, el cliente no pasa a dunning y la suscripción no se cancela. Las renovaciones se reanudan automáticamente en cuanto se corrige la configuración — un conector activo, una oferta válida o credenciales nuevas guardadas en un conector cuya clave rechazó el proveedor. Cuando un merchant retenido vuelve a estar operativo, el período de facturación se reancla, de modo que la próxima renovación se programa a partir de ese punto, en lugar de retroactivarse sobre el intervalo.
Una suscripción viva por plan
Un cliente puede mantener solo una suscripción viva por plan a la vez. Una suscripción programada para cancelarse al final de su período (cancel_at_period_end: true) sigue contando como viva. Iniciar una segunda suscripción para un plan que el cliente ya posee se rechaza con 409 (conflict_error); la respuesta apunta a la reactivación como la forma de mantener la suscripción existente en lugar de crear un duplicado.
Endpoints
Todas las rutas de suscripción están anidadas bajo un merchant:
/api/v1/merchants/:merchant_id/subscriptionsLos endpoints de suscripción requieren una clave con alcance de Merchant. El :merchant_id de la ruta debe coincidir con el merchant de la clave. Las claves de Organization no direccionan directamente estas rutas anidadas bajo merchant — emite una clave de merchant para el merchant de destino durante el onboarding en el Dashboard de Tokeflow.
Las mutaciones están protegidas por el alcance subscriptions:write; las lecturas requieren subscriptions:read.
GET/api/v1/merchants/:merchant_id/subscriptions
Lista las suscripciones de un merchant, las más recientes primero. Admite paginación y filtrado.
Auth: clave de Merchant (subscriptions:read)
Parámetros de consulta
| Field | Type | Required | Description |
|---|---|---|---|
page | integer | No | Número de página, con índice base 1. Predeterminado 1. |
limit | integer | No | Elementos por página. Predeterminado 20, máximo 100. |
customer_id | string | No | Filtrar por cliente (cust_). |
status | enum | No | Filtrar por estado (trialing, active, dunning, paused, cancelled, expired). |
current_offer_id | string | No | Filtrar por oferta actual (ofr_). |
product_family_id | string | No | Filtrar por familia de productos (pfa_). |
curl -G "https://api.tokeflow.com/api/v1/merchants/mrc_8a1c2d/subscriptions" \
-H "Authorization: Bearer sk_live_mer_…" \
-d page=1 \
-d limit=20 \
-d status=activeRespuesta 200 OK
{
"success": true,
"data": [
{
"id": "sub_3f9a7c2e1b",
"merchant_id": "mrc_8a1c2d",
"customer_id": "cust_5b2e9f",
"customer_name": "Ana Souza",
"customer_email": "ana@example.com",
"current_offer_id": "ofr_premium_monthly",
"offer_name": "Premium — Monthly",
"product_id": "prd_7d4a1c",
"product_name": "Premium Plan",
"product_family_id": "pfa_streaming",
"billing_cycle": "monthly",
"currency": "BRL",
"current_amount": 4990,
"current_period_start": "2026-06-25T00:00:00.000Z",
"current_period_end": "2026-07-25T00:00:00.000Z",
"next_billing_at": "2026-07-25T00:00:00.000Z",
"billing_anchor_day": 25,
"trial_start": null,
"trial_end": null,
"dunning_started_at": null,
"dunning_attempt_count": 0,
"dunning_next_retry_at": null,
"cycles_completed": 3,
"cycle_limit": null,
"status": "active",
"cancel_at_period_end": false,
"cancelled_at": null,
"cancellation_reason": null,
"payment_instrument_id": "pi_9c3f2a",
"preferred_connector_name": "acquirer_a",
"preferred_installments": 1,
"created_at": "2026-03-25T12:00:00.000Z",
"updated_at": "2026-06-25T00:00:01.000Z"
}
],
"meta": {
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"total_pages": 3,
"has_next": true,
"has_prev": false
}
},
"request_id": "req_8f3c2a1b",
"timestamp": "2026-06-25T12:30:00.000Z"
}GET/api/v1/merchants/:merchant_id/subscriptions/:subscription_id
Recupera una única suscripción por id.
Auth: clave de Merchant (subscriptions:read)
curl "https://api.tokeflow.com/api/v1/merchants/mrc_8a1c2d/subscriptions/sub_3f9a7c2e1b" \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 200 OK
{
"success": true,
"data": {
"id": "sub_3f9a7c2e1b",
"merchant_id": "mrc_8a1c2d",
"customer_id": "cust_5b2e9f",
"current_offer_id": "ofr_premium_monthly",
"product_family_id": "pfa_streaming",
"billing_cycle": "monthly",
"currency": "BRL",
"current_amount": 4990,
"current_period_start": "2026-06-25T00:00:00.000Z",
"current_period_end": "2026-07-25T00:00:00.000Z",
"next_billing_at": "2026-07-25T00:00:00.000Z",
"billing_anchor_day": 25,
"trial_start": null,
"trial_end": null,
"dunning_started_at": null,
"dunning_attempt_count": 0,
"dunning_next_retry_at": null,
"cycles_completed": 3,
"cycle_limit": null,
"status": "active",
"cancel_at_period_end": false,
"cancelled_at": null,
"cancellation_reason": null,
"payment_instrument_id": "pi_9c3f2a",
"preferred_installments": 1,
"created_at": "2026-03-25T12:00:00.000Z",
"updated_at": "2026-06-25T00:00:01.000Z"
},
"request_id": "req_8f3c2a1b",
"timestamp": "2026-06-25T12:30:00.000Z"
}Un id inexistente o fuera de alcance devuelve 404 (not_found_error).
GET/api/v1/merchants/:merchant_id/subscriptions/:subscription_id/transitions
Lista el historial de transiciones de la suscripción — un registro de auditoría de solo adición de cada cambio de estado y de oferta, los más recientes primero. Cada transición registra qué cambió, quién lo activó y la orden que lo causó (cuando corresponde). Este es el sistema de registro para el historial de cambios de oferta.
Auth: clave de Merchant (subscriptions:read)
Objeto transición
| Field | Type | Description |
|---|---|---|
id | string | Id de la transición (sbt_). |
subscription_id | string | Suscripción propietaria (sub_). |
transition_type | enum | creation, upgrade, downgrade, reactivation, cancellation, trial_start, trial_conversion, payment_method_change, dunning_entry, dunning_retry, dunning_cancelled, expiration, cycle_limit_renewed, pause, resume. |
from_offer_id | string | null | Oferta antes del cambio (ofr_). null en la creación. |
to_offer_id | string | null | Oferta después del cambio (ofr_). null en la cancelación. |
from_status | enum | null | Estado antes del cambio. null en el primer evento (creación). |
to_status | enum | Estado después del cambio. |
triggered_by | enum | customer, system o admin. |
actor | object | null | Para una transición activada por admin, una instantánea del usuario del Dashboard que realizó la acción, tomada en el momento en que ocurrió: { "id", "type", "name", "email" }. null para transiciones activadas por customer y system. |
order_id | string | null | Orden que activó la transición (ord_), si la hay. |
reason | string | null | Motivo legible por humanos, cuando se proporciona. |
metadata | object | null | Contexto adicional, p. ej. el change_charge_behavior resuelto para un cambio de oferta. |
created_at | string | Marca de tiempo ISO 8601. |
curl "https://api.tokeflow.com/api/v1/merchants/mrc_8a1c2d/subscriptions/sub_3f9a7c2e1b/transitions" \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 200 OK
{
"success": true,
"data": [
{
"id": "sbt_2b7e1a",
"subscription_id": "sub_3f9a7c2e1b",
"transition_type": "upgrade",
"from_offer_id": "ofr_basic_monthly",
"to_offer_id": "ofr_premium_monthly",
"from_status": "active",
"to_status": "active",
"triggered_by": "customer",
"actor": null,
"order_id": null,
"reason": null,
"metadata": { "change_charge_behavior": "next_renew" },
"created_at": "2026-06-01T09:14:00.000Z"
},
{
"id": "sbt_1a9c4d",
"subscription_id": "sub_3f9a7c2e1b",
"transition_type": "creation",
"from_offer_id": null,
"to_offer_id": "ofr_basic_monthly",
"from_status": null,
"to_status": "active",
"triggered_by": "system",
"actor": null,
"order_id": "ord_5e2f8b",
"reason": null,
"metadata": null,
"created_at": "2026-03-25T12:00:00.000Z"
}
],
"request_id": "req_8f3c2a1b",
"timestamp": "2026-06-25T12:30:00.000Z"
}POST/api/v1/merchants/:merchant_id/subscriptions/:subscription_id/cancel
Cancela una suscripción, ya sea de inmediato o al final del período actual.
Auth: clave de Merchant (subscriptions:write)
Cuerpo
| Field | Type | Required | Description |
|---|---|---|---|
at_period_end | boolean | Sí | true aplaza la cancelación hasta current_period_end (el cliente conserva el acceso hasta entonces). false cancela de inmediato. |
reason | string | No | Motivo legible por humanos, persistido en la suscripción. Máximo 500 caracteres. |
Cuando at_period_end es true, la suscripción se marca (cancel_at_period_end: true) y el cambio real de estado ocurre en el próximo tic de renovación — todavía no se registra ninguna transición, porque nada ha cambiado de estado. Cuando es false, el estado cambia a cancelled de inmediato y se registra una transición cancellation.
curl -X POST "https://api.tokeflow.com/api/v1/merchants/mrc_8a1c2d/subscriptions/sub_3f9a7c2e1b/cancel" \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{ "at_period_end": true, "reason": "customer no longer needs the service" }'Respuesta 200 OK — el objeto suscripción actualizado. Con at_period_end: true:
{
"success": true,
"data": {
"id": "sub_3f9a7c2e1b",
"status": "active",
"cancel_at_period_end": true,
"cancellation_reason": "customer no longer needs the service",
"current_period_end": "2026-07-25T00:00:00.000Z",
"next_billing_at": "2026-07-25T00:00:00.000Z"
},
"request_id": "req_8f3c2a1b",
"timestamp": "2026-06-25T12:30:00.000Z"
}Cancelar una suscripción que ya está cancelled o expired devuelve 400 (validation_error) — los estados terminales no pueden volver a cancelarse.
POST/api/v1/merchants/:merchant_id/subscriptions/:subscription_id/admin-cancel
Auth: clave de Organization (con merchant_id) o clave de Merchant.
Variante privilegiada de cancel, registrada como iniciada por el merchant. Requiere el alcance subscriptions:admin y no forma parte de la API pública.
Parámetros de ruta
| Field | Type | Required | Description |
|---|---|---|---|
merchant_id | string | Sí | — |
subscription_id | string | Sí | — |
Campos de la solicitud
| Field | Type | Required | Description |
|---|---|---|---|
at_period_end | boolean | Sí | Cuando es true, aplaza la cancelación hasta la próxima renovación; false cancela de inmediato. |
reason | string | No | Motivo opcional legible por humanos, persistido en la suscripción. |
Ejemplo de solicitud
curl -X POST https://api.tokeflow.com/api/v1/merchants/mrc_8a3f12d9/subscriptions/sub_6d80b3a2/admin-cancel \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{
"at_period_end": true,
"reason": "customer no longer needs the service"
}'Ejemplo de respuesta — 200
{
"id": "sub_123",
"merchant_id": "mrc_123",
"customer_id": "cust_123",
"customer_name": "Acme Store",
"customer_email": "jane@example.com",
"current_offer_id": "off_123",
"offer_name": "Acme Store",
"product_id": "prd_9b1e6c05",
"product_name": "Acme Store",
"product_family_id": "pfam_123",
"billing_cycle": "monthly",
"currency": "BRL",
"current_amount": 4990,
"current_period_start": "2026-05-25T00:00:00Z",
"current_period_end": "2026-06-25T00:00:00Z",
"next_billing_at": "2026-06-25T00:00:00Z",
"billing_anchor_day": 25,
"trial_start": "2026-05-25T00:00:00Z",
"trial_end": "2026-06-08T00:00:00Z",
"dunning_started_at": "2026-01-15T12:30:00.000Z",
"dunning_attempt_count": 0,
"dunning_next_retry_at": "2026-01-15T12:30:00.000Z",
"cycles_completed": 3,
"cycle_limit": 12,
"status": "active",
"cancel_at_period_end": false
}POST/api/v1/merchants/:merchant_id/subscriptions/:subscription_id/change-offer
Mueve la suscripción a una oferta diferente (un upgrade o un downgrade) dentro de la misma familia de productos. Tokeflow clasifica el cambio como upgrade o downgrade a partir del orden de niveles de las ofertas y registra la transición correspondiente.
Auth: clave de Merchant (subscriptions:write)
Cuerpo
| Field | Type | Required | Description |
|---|---|---|---|
to_offer_id | string | Sí | Oferta de destino (ofr_). Debe pertenecer a la misma familia de productos que la oferta actual y tener un precio en la moneda de la suscripción. |
Cómo se resuelve el comportamiento de cobro
Cada par de ofertas puede declarar un change_charge_behavior que rige cómo se maneja el dinero cuando cambia el plan:
| Behavior | Meaning |
|---|---|
next_renew | El nuevo importe surte efecto en la próxima renovación. Sin cobro inmediato, sin prorrateo. |
prorated | Se cobra (o se acredita) al cliente la diferencia prorrateada por el resto del período. |
override | Se cobra un importe personalizado definido para la transición. |
El comportamiento efectivo para un par dado (from_offer → to_offer) se resuelve en orden:
- Si existe una transición de oferta activa para el par con un comportamiento explícito, ese valor prevalece.
- De lo contrario, recurre al valor predeterminado de la familia de productos.
El motor de facturación procesa los tres comportamientos. next_renew aplica el nuevo current_amount a partir del próximo ciclo, sin cobro inmediato ni prorrateo; prorated cobra o acredita la diferencia prorrateada por el resto del período actual; y override cobra el importe personalizado definido para la transición. Puedes resolver el comportamiento efectivo con antelación por par de ofertas en el recurso Offers.
curl -X POST "https://api.tokeflow.com/api/v1/merchants/mrc_8a1c2d/subscriptions/sub_3f9a7c2e1b/change-offer" \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{ "to_offer_id": "ofr_premium_monthly" }'Respuesta 200 OK — la suscripción con el nuevo current_offer_id, el current_amount actualizado y el billing_cycle re-sincronizado con el ciclo de la nueva oferta. El período actual conserva sus fechas: next_billing_at y los campos de enrutamiento permanecen sin cambios, y el nuevo ciclo rige las renovaciones a partir de la próxima fecha de facturación.
{
"success": true,
"data": {
"id": "sub_3f9a7c2e1b",
"current_offer_id": "ofr_premium_monthly",
"current_amount": 4990,
"billing_cycle": "monthly",
"next_billing_at": "2026-07-25T00:00:00.000Z",
"status": "active"
},
"request_id": "req_8f3c2a1b",
"timestamp": "2026-06-25T12:30:00.000Z"
}Errores comunes:
400(validation_error) — la oferta de destino es la actual, la suscripción estácancelled/expired, no existe una transición de oferta activa para el par, la oferta de destino carece de un precio en la moneda de la suscripción, o las ofertas están en familias diferentes (maneja un movimiento entre familias como una cancelación más una nueva suscripción).
POST/api/v1/merchants/:merchant_id/subscriptions/:subscription_id/change-payment-instrument
Cambia la suscripción a un instrumento de pago diferente para las renovaciones futuras. Esta es la ruta de recuperación para salir de dunning.
Auth: clave de Merchant (subscriptions:write)
Cuerpo
| Field | Type | Required | Description |
|---|---|---|---|
payment_instrument_id | string | Sí | El instrumento a cobrar en adelante (pi_). |
El instrumento ya debe tener un cobro confirmado iniciado por el cliente, para que Tokeflow pueda enrutar las renovaciones futuras a través de la conexión correcta. Si no lo tiene, la llamada devuelve 422 (business_rule_error).
Un cambio de instrumento de pago solo es válido mientras la suscripción está en dunning. Al tener éxito, la suscripción vuelve a active, los contadores de dunning se restablecen y el período de facturación se reancla hacia adelante un ciclo (sin facturación retroactiva por el hueco de dunning). Llamar a esto en una suscripción que no está en dunning devuelve 400 (validation_error).
curl -X POST "https://api.tokeflow.com/api/v1/merchants/mrc_8a1c2d/subscriptions/sub_3f9a7c2e1b/change-payment-instrument" \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{ "payment_instrument_id": "pi_new1234" }'Respuesta 200 OK
{
"success": true,
"data": {
"id": "sub_3f9a7c2e1b",
"status": "active",
"payment_instrument_id": "pi_new1234",
"dunning_attempt_count": 0,
"dunning_started_at": null,
"dunning_next_retry_at": null,
"current_period_end": "2026-07-25T00:00:00.000Z",
"next_billing_at": "2026-07-25T00:00:00.000Z"
},
"request_id": "req_8f3c2a1b",
"timestamp": "2026-06-25T12:30:00.000Z"
}POST/api/v1/merchants/:merchant_id/subscriptions/:subscription_id/pause
Suspende la facturación. Mientras está pausada, no se disparan renovaciones. Se registra una transición pause.
Auth: clave de Merchant (subscriptions:write)
Cuerpo
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | No | Motivo legible por humanos, persistido en la transición. Máximo 500 caracteres. |
Una suscripción solo puede pausarse desde active o trialing. Pausar desde cualquier otro estado devuelve 409 (conflict_error).
curl -X POST "https://api.tokeflow.com/api/v1/merchants/mrc_8a1c2d/subscriptions/sub_3f9a7c2e1b/pause" \
-H "Authorization: Bearer sk_live_mer_…" \
-H "Content-Type: application/json" \
-d '{ "reason": "customer travelling for 6 weeks" }'Respuesta 200 OK
{
"success": true,
"data": {
"id": "sub_3f9a7c2e1b",
"status": "paused"
},
"request_id": "req_8f3c2a1b",
"timestamp": "2026-06-25T12:30:00.000Z"
}POST/api/v1/merchants/:merchant_id/subscriptions/:subscription_id/resume
Reanuda una suscripción pausada. Vuelve a active, o a trialing si la prueba sigue en curso. Si la próxima fecha de facturación se desplazó al pasado mientras estaba pausada, el período se adelanta para comenzar desde ahora — pausar detiene el reloj en lugar de saltarse un ciclo, por lo que cycles_completed no se incrementa. Se registra una transición resume. Sin cuerpo de solicitud.
Auth: clave de Merchant (subscriptions:write)
Solo una suscripción paused puede reanudarse. Reanudar desde cualquier otro estado devuelve 409 (conflict_error).
curl -X POST "https://api.tokeflow.com/api/v1/merchants/mrc_8a1c2d/subscriptions/sub_3f9a7c2e1b/resume" \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 200 OK
{
"success": true,
"data": {
"id": "sub_3f9a7c2e1b",
"status": "active",
"current_period_start": "2026-06-25T00:00:00.000Z",
"current_period_end": "2026-07-25T00:00:00.000Z",
"next_billing_at": "2026-07-25T00:00:00.000Z"
},
"request_id": "req_8f3c2a1b",
"timestamp": "2026-06-25T12:30:00.000Z"
}POST/api/v1/merchants/:merchant_id/subscriptions/:subscription_id/reactivate
Cancela una cancelación programada y mantiene la suscripción en su plan actual. La reactivación vuelve a poner cancel_at_period_end en false y registra una transición reactivation. No cambia la oferta, el importe ni las fechas de facturación — solo cancela la cancelación pendiente.
Úsala cuando un cliente que había programado una cancelación decide continuar, y como remedio para el 409 que se devuelve cuando un cliente intenta comprar un plan que ya posee (consulta Una suscripción viva por plan).
Auth: Merchant key (subscriptions:write)
La reactivación se aplica a una suscripción viva — active, trialing o dunning. Una suscripción en dunning permanece en dunning y su escalera de reintentos no se ve afectada; cancelar la cancelación es independiente del problema de pago. Sin cuerpo de solicitud.
La reactivación actúa sobre una suscripción viva que tiene una cancelación programada. Una suscripción paused no puede reactivarse — reanúdala con resume — y una suscripción terminal (cancelled o expired) se rechaza. Ambos devuelven 409 (conflict_error).
curl -X POST "https://api.tokeflow.com/api/v1/merchants/mrc_8a1c2d/subscriptions/sub_3f9a7c2e1b/reactivate" \
-H "Authorization: Bearer sk_live_mer_…"Respuesta 200 OK
{
"success": true,
"data": {
"id": "sub_3f9a7c2e1b",
"status": "active",
"cancel_at_period_end": false
},
"request_id": "req_8f3c2a1b",
"timestamp": "2026-06-25T12:30:00.000Z"
}Errores
Los endpoints de suscripción usan el envoltorio de error estándar. Los casos más comunes:
| HTTP | Type | When |
|---|---|---|
400 | validation_error | Cancelación/cambio en una suscripción terminal, cambio de oferta entre familias, change-payment-instrument fuera de dunning, sin transición de oferta activa. |
403 | authorization_error | La clave carece de subscriptions:read / subscriptions:write. |
404 | not_found_error | Suscripción no encontrada o no propiedad del merchant. |
409 | conflict_error | Pausa desde un estado no pausable, reanudación desde un estado no pausado, reactivación de una suscripción pausada o terminal, o inicio de una suscripción para un plan que el cliente ya posee. |
422 | business_rule_error | El instrumento de pago de destino no tiene un cobro previo confirmado desde el cual enrutar. |
Relacionado
- Offers — define ciclos de facturación, precios, pruebas y transiciones de oferta.
- Orders — la orden acuñada en cada renovación.
- Transactions — el cobro subyacente y los instrumentos de pago.
- Resumen de la referencia de la API — envoltorios, paginación, IDs y convenciones de dinero.