Skip to content

Suscripciones

Una suscripción cobra a un cliente con una cadencia fija usando un token de pago previamente guardado. Genius Checkout es dueño del calendario — cobramos en cada renovación, reintentamos rechazos y emitimos webhooks. No necesitas un cron.

Una suscripción siempre necesita dos cosas: un customer_id (devuelto por cualquier checkout previo) y un token_id (pt_…). Ambos están aislados por comercio.

Ciclo de vida

trial ─▶ active ─▶ past_due ─▶ cancelled
                  └▶ suspended ─▶ active
                                └▶ cancelled
        └▶ expired   (se alcanzó total_cycles)
EstadoSignificado
trialCreada con trial_period_days. Aún no hay cobro — el primer cargo es al terminar el periodo de prueba.
activeFacturando según el calendario. Cada ciclo emite subscription.charged en caso de éxito.
past_dueLa renovación más reciente falló. El job de dunning reintenta según el calendario del comercio.
suspendedPausada por el comercio vía POST /subscriptions/{id}/pause. No se cobran ciclos hasta resumir.
cancelledTerminal. No habrá más cobros. Se establece vía POST /subscriptions/{id}/cancel.
expiredTerminal. Se alcanzó total_cycles (suscripciones de duración fija).

Crear una suscripción

http
POST /api/v1/subscriptions
CampoTipoRequeridoDescripción
customer_idstringID externo del cliente (cus_…)
token_idstringID externo del token (pt_…). Debe estar active.
amountintegerMonto por ciclo en unidades menores (ver Monedas)
currencystringCódigo alfa ISO 4217
intervalstringday, week, month, year
interval_countintegerNoMultiplicador de interval. Defecto 1. Rango 1–365.
trial_period_daysintegerNoSi se define, el primer cobro ocurre tras la prueba.
setup_feeintegerNoCargo único cobrado al crearse.
total_cyclesintegerNoSuscripción de duración fija. El estado pasa a expired tras el último ciclo.
start_datedateNoFecha ISO 8601 en el futuro. Por defecto, hoy.
metadataobjectNoSe replica en cada webhook subscription.*.
bash
curl -X POST https://app.geniuscheckout.com/api/v1/subscriptions \
  -H "Authorization: Bearer gc_test_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "customer_id": "cus_abc123",
    "token_id": "pt_xyz789",
    "amount": 2999,
    "currency": "USD",
    "interval": "month",
    "trial_period_days": 14,
    "metadata": {"plan": "pro"}
  }'

Respuesta (201)

json
{
  "id": "sub_abc123",
  "status": "trial",
  "amount": 2999,
  "currency": "USD",
  "interval": "month",
  "interval_count": 1,
  "setup_fee": null,
  "trial_ends_at": "2026-06-05T12:00:00+00:00",
  "current_period_start": "2026-05-22T12:00:00+00:00",
  "current_period_end": "2026-06-22T12:00:00+00:00",
  "next_charge_at": "2026-06-05T12:00:00+00:00",
  "total_cycles": null,
  "completed_cycles": 0,
  "dunning_attempts": 0,
  "cancelled_at": null,
  "cancel_reason": null,
  "customer": {"id": "cus_abc123", "name": "Jane Doe", "email": "[email protected]"},
  "payment_method": {"id": "pt_xyz789", "brand": "Visa", "last4": "0071"},
  "created_at": "2026-05-22T12:00:00+00:00"
}

Listar suscripciones

http
GET /api/v1/subscriptions?status=active&limit=20&offset=0

Filtros: status, customer_id. Paginación con limit/offset (máx limit=100). Ver Paginación.

json
{
  "data": [ /* objetos suscripción */ ],
  "total": 142,
  "limit": 20,
  "offset": 0
}

Recuperar una suscripción

http
GET /api/v1/subscriptions/{id}

Devuelve el objeto completo más un array events con los eventos de ciclo recientes (status_changed, charged, charge_failed).

Cancelar

http
POST /api/v1/subscriptions/{id}/cancel
json
{ "reason": "Solicitud del cliente", "immediate": true }

Cuando immediate es false, la cancelación se programa al current_period_end (el cliente conserva acceso hasta entonces). Por defecto es true.

Pausar / reanudar

http
POST /api/v1/subscriptions/{id}/pause
POST /api/v1/subscriptions/{id}/resume

Pausar cambia el estado a suspended y detiene todos los cobros futuros. Reanudar vuelve a active y recalcula next_charge_at.

Actualizar método de pago

http
PUT /api/v1/subscriptions/{id}/payment-method
json
{ "token_id": "pt_new_card" }

El nuevo token debe estar active y pertenecer al mismo comercio. Úsalo cuando una tarjeta expire y el cliente agregue otra desde tu portal.

Webhooks

Cada ciclo y cada transición de estado emite un webhook — ver Webhooks para la lista completa. Los más comunes:

  • subscription.created — creada (en trial o active)
  • subscription.charged — renovación exitosa
  • subscription.charge_failed — renovación rechazada; el dunning reintenta
  • subscription.cancelled — cancelación terminal
  • subscription.updated — cambió el método de pago o el calendario

Ejemplos de código

js
// Node — crear suscripción con prueba de 14 días
const res = await fetch('https://app.geniuscheckout.com/api/v1/subscriptions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.GC_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({
    customer_id: 'cus_abc123',
    token_id: 'pt_xyz789',
    amount: 2999,
    currency: 'USD',
    interval: 'month',
    trial_period_days: 14,
  }),
})
const subscription = await res.json()
php
// PHP (Guzzle) — cancelar al final del periodo
$client = new \GuzzleHttp\Client();
$client->post("https://app.geniuscheckout.com/api/v1/subscriptions/{$id}/cancel", [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('GC_API_KEY'),
        'Content-Type'  => 'application/json',
    ],
    'json' => [
        'reason'    => 'Solicitud del cliente',
        'immediate' => false,
    ],
]);

Siguiente

Released under the proprietary Genius Checkout license.