Suscripciones y estados de acceso
Estados de una suscripción, el campo access_status con el que decides si tu usuario tiene acceso, reintentos de pagos rechazados y cómo cancelar, pausar o cambiar de plan.
Paygumi te dice qué hacer con tu usuario en un solo campo: access_status. Viene en cada webhook de suscripción y de pago, y lo puedes consultar en cualquier momento. Con él no tienes que reimplementar reglas de mora, días de gracia ni cancelaciones.
Estado de acceso
access_status | Qué hacer |
|---|---|
| GRANTED | Dar acceso. Dura hasta access_until (fin del periodo, de la prueba o de la gracia). |
| RESTRICTED | El pago está vencido y ya pasaron los días de gracia: limita el acceso y pide actualizar la tarjeta. |
| REVOKED | Sin acceso. |
En la API el valor va en mayúsculas (GRANTED); en el cuerpo de los webhooks, en minúsculas (granted). El motivo viene en access_reason: ACTIVE, TRIAL, GRACE_PERIOD, PAYMENT_FAILED, UNPAID, PAUSED, CANCELED o NO_SUBSCRIPTION.
Estados de la suscripción
| Estado | Acceso | Significado |
|---|---|---|
| TRIALING | GRANTED | Periodo de prueba, sin cobro. |
| ACTIVE | GRANTED | El periodo actual está pagado (o su primer cobro está en curso). |
| PAST_DUE | GRANTED durante la gracia, luego RESTRICTED | Un cobro fue rechazado y hay reintentos pendientes. |
| UNPAID | REVOKED | Se agotaron los reintentos. La suscripción sigue viva: si el cliente paga, se reactiva. |
| PAUSED | REVOKED | Pausada; no se generan cobros. |
| CANCELED | REVOKED | Terminada. |
Una cancelación programada (cancel_at_period_end: true) mantiene el acceso hasta el fin del periodo y luego pasa a CANCELED.
Pagos rechazados y reintentos
Cuando el cobro de un periodo es rechazado, la suscripción pasa a PAST_DUE y Paygumi lo reintenta según la política de tu cuenta (configurable en el panel). La política por defecto:
| Paso | Cuándo | Estado | Acceso |
|---|---|---|---|
| Intento 1 | Día de cobro | ACTIVE → PAST_DUE si falla | GRANTED (gracia) |
| Reintento 1 | +1 día | PAST_DUE | GRANTED (gracia) |
| Reintento 2 | +3 días | PAST_DUE | RESTRICTED (gracia de 3 días vencida) |
| Reintento 3 | +5 días | PAST_DUE | RESTRICTED |
| Agotado | — | UNPAID o CANCELED, según tu política | REVOKED |
Cada paso te llega por webhook (payment.declined trae next_retry_at, payment.uncollectible cuando se agotan). Si el cliente actualiza su tarjeta con una sesión setup o desde el portal, se reintenta de inmediato.
Consultar el acceso
El webhook es la fuente principal, pero puedes consultar el acceso calculado en este momento (por ejemplo, en el login de tu usuario o para reconciliar):
curl https://api.paygumi.com/v1/customers/by-external-id/user_42/access \
-H "Authorization: Bearer pgm_test_..."
{
"access_status": "GRANTED",
"access_until": "2026-12-01T05:00:00Z",
"subscription_id": "sub_01JB86R800ABCDEFGHJKMNPQRS",
"subscription_status": "ACTIVE",
"last_payment_status": "PAID",
"reason": "ACTIVE"
}
Si el usuario no existe o no tiene suscripciones, la respuesta es 200 con access_status: REVOKED y reason: NO_SUBSCRIPTION. Con varias suscripciones se devuelve la de mejor acceso; filtra con ?plan_id= si necesitas un plan concreto. Por id de suscripción: GET /v1/subscriptions/{id}/access.
Crear una suscripción sin página de pago
Si el cliente ya registró su tarjeta, suscríbelo directamente:
curl https://api.paygumi.com/v1/subscriptions \
-H "Authorization: Bearer pgm_test_..." \
-H "Idempotency-Key: 9b1f6c2e-4d3a-4c8e-8f0a-2e7d5b1c9a33" \
-H "Content-Type: application/json" \
-d '{ "customer_id": "cus_01JB86R800ABCDEFGHJKMNPQRS", "plan_id": "pln_01JB86R800ABCDEFGHJKMNPQRS" }'
Si no tiene tarjeta, usa una sesión de checkout en modo subscription.
Cancelar, pausar y cambiar de plan
| Acción | Ruta | Notas |
|---|---|---|
| Cancelar ya | POST /v1/subscriptions/{id}/cancel | Pasa a CANCELED con acceso REVOKED y anula el cobro abierto. |
| Cancelar al final del periodo | POST /v1/subscriptions/{id}/cancel con {"at_period_end": true} | Mantiene el acceso hasta current_period_end. Se deshace con POST /v1/subscriptions/{id}/undo-cancel. |
| Pausar | POST /v1/subscriptions/{id}/pause | Solo ACTIVE o PAST_DUE. Sin cobros ni acceso. resume_at opcional programa la reanudación. |
| Reanudar | POST /v1/subscriptions/{id}/resume | Empieza un periodo desde hoy con cobro inmediato. |
| Cambiar de plan | POST /v1/subscriptions/{id}/change-plan | timing: NEXT_PERIOD (por defecto) al cierre del periodo, o IMMEDIATE con un cobro del plan nuevo completo (sin prorrateo). |
Todos los detalles en la referencia de suscripciones.