Suscripciones y Trials

Gestiona planes, suscripciones y períodos de prueba. Soporte para trials individuales y corporativos (B2B).

Planes

Un plan define el precio, duración y acceso de una suscripción:

CampoDescripción
nameNombre visible (ej: "Plan Mensual")
slugIdentificador único (ej: "plan_mensual")
pricePrecio en centavos (ej: 2990000 = $29,900 COP)
currencyMoneda (COP, USD)
intervalPeríodo: monthly, quarterly, yearly, 4-week (28 días exactos, ver abajo)
trial_daysDías de prueba gratis (0 = sin trial)
featuresLista de features incluidos

Estados de Suscripción

EstadoDescripciónAcceso
TRIALEn período de prueba✅ Sí
ACTIVEPago al día✅ Sí
PAUSEDPausada temporalmente❌ No
CANCELLEDCancelada por usuario❌ No
EXPIREDVenció sin renovar❌ No

Trial Individual

Período de prueba gratuito para usuarios individuales:

  • Duración configurable por plan (ej: 7 días)
  • No requiere tarjeta de crédito
  • Acceso completo durante el trial
  • Notificación antes de expirar
  • Conversión automática a pago si agrega tarjeta

Trial Corporativo (B2B)

Trials especiales para empresas con políticas personalizadas:

CaracterísticaIndividualCorporativo
DuraciónFija por planConfigurable por empresa
VerificaciónEmail personalDominio corporativo
Límite usuarios1Ilimitado o por cuota
FacturaciónIndividualConsolidada a empresa

Configurar Trial Corporativo

  1. Crea una Corporate Policy en el dashboard
  2. Define el dominio (ej: @empresa.com)
  3. Configura duración y límites
  4. Usuarios con ese dominio obtienen trial especial

Precio por Fases (Precio de Introducción)

Un plan puede tener un precio de introducción que dura N ciclos de cobro y después pasa a la siguiente fase (o al precio de lista si es la última) — por ejemplo, "50% off los primeros 3 meses, luego precio completo". Cada fase se configura desde el dashboard del tenant (Suscripciones → Planes → Precio por fases): tipo de descuento (porcentaje o precio fijo) y cuántos ciclos de cobro dura.

Un plan sin fases configuradas siempre cobra su precio de lista — la funcionalidad es aditiva, no cambia el comportamiento de planes existentes.

Consultar el precio vigente (checkout del cliente)

Endpoint público, sin autenticación, para que el frontend del cliente sepa qué precio y mensaje de promoción mostrar sin hardcodearlo a mano:

GET https://engine.paywl.io/edge/plans?domain=<su-dominio>
[
  {
    "id": "plan-uuid",
    "name": "Plan Mensual",
    "price_cents": 2990000,
    "currency": "COP",
    "billing_interval": "monthly",
    "phases": [
      {
        "phase_order": 1,
        "discount_type": "percentage",
        "discount_value": 50,
        "duration_periods": 3,
        "effective_price_cents": 1495000
      }
    ]
  }
]

Un plan sin precio por fases devuelve phases: []. effective_price_cents ya viene calculado (precio de lista menos el descuento de esa fase) — no hace falta que el frontend haga la cuenta.

Aviso al suscriptor: 7 días antes de que termine la fase vigente de una suscripción, se envía un email automático avisando el cambio de precio que viene.

Período de Facturación Personalizado (4 semanas)

Además de los intervalos calendario estándar (mensual, trimestral, anual), un plan puede usar interval: "4-week": un ciclo de cobro de exactamente 28 días, no "un mes calendario". Pensado para medios que quieren un cobro semanal-consistente en vez del corrimiento típico de los ciclos mensuales (ej: el 31 de enero cobra distinto que el 28 de febrero).

Encadenamiento: tanto la activación inicial como cada renovación automática calculan la siguiente fecha de cobro sumando 28 días exactos a partir del período vigente (setDate(+28), no setMonth(+1)) — el ciclo nunca se desalinea con el día de la semana en que empezó.

Códigos de Descuento (Cupones)

Motor de cupones administrable desde el dashboard del tenant (Suscripciones → Cupones), con validación en dos tiempos: una vista previa antes de tokenizar la tarjeta, y la validación autoritativa real al momento del cobro.

CampoDescripción
codeCódigo que el usuario escribe en el checkout (único por tenant)
discount_typepercentage (1–100) o fixed_amount (en centavos)
applies_tofirst_period (solo el primer cobro) o recurring (todos los cobros mientras el código siga vigente)
audiencenew, renewal, o both — a qué tipo de checkout aplica
plan_idsLista opcional de planes a los que aplica; null = todos los planes
max_uses_total / max_uses_per_userLímites de redención, opcionales
valid_from / valid_untilVigencia opcional del código

Paso previo (opcional): previsualizar el descuento

Antes de montar el widget de Wompi, se puede validar el código que el usuario escribió para mostrarle el descuento en pantalla sin comprometerse todavía:

POST https://engine.paywl.io/edge/validate-discount-code
Content-Type: application/json

{
  "domain": "<su-dominio>",
  "code": "BIENVENIDA20",
  "plan_id": "<uuid del plan>"
}
// Válido
{ "valid": true, "discount_type": "percentage", "discount_value": 20, "discount_preview_cents": 598000 }

// Inválido (código no encontrado, expirado, agotado, etc.)
{ "valid": false, "reason": "Código expirado" }

Aplicarlo en el checkout

Se agrega el mismo code como campo discount_code al formulario de checkout de Wompi (ver Pagos con Wompi, Paso 2) — la validación se repite del lado del servidor al momento de cobrar, así que el preview nunca es la única fuente de verdad.

El límite por usuario no se aplica en el preview: /edge/validate-discount-code no conoce todavía quién es el usuario en ese punto del flujo, así que max_uses_per_user solo se verifica en la validación real durante la activación — un código puede pasar el preview y aun así ser rechazado al cobrar si ese usuario ya lo usó el máximo de veces permitido.

Monto Variable (Precio Elegido por el Suscriptor)

Un plan puede configurarse con pricing_type: "variable": en vez de un precio fijo, el suscriptor elige cuánto quiere pagar en el checkout, sujeto a un mínimo. Pensado para modelos tipo membresía/donación recurrente (ej. "Círculo Cambio" en Revista Cambio) — mecanismo genérico disponible para cualquier tenant, no exclusivo de un cliente.

CampoDescripción
pricing_typefixed (default, comportamiento normal) o variable
price_centsEn un plan variable, deja de ser "el precio" y pasa a ser el mínimo permitido
custom_amount_centsMonto que el suscriptor eligió, persistido en la suscripción — el billing cron cobra ese mismo monto en cada renovación
Piso real de Wompi: el monto elegido debe ser mayor o igual tanto al mínimo configurado en el plan como al mínimo real que permite Wompi procesar — el checkout valida ambos antes de tokenizar la tarjeta.

La capacidad de crear planes de monto variable se activa por tenant — desde el admin root de Paywl (override puntual) o porque el plan de licencia del tenant la incluye por defecto. Si el plan factura contra Siigo y necesita un código de producto específico (siigo_product_code_override), el dashboard del tenant muestra una alerta mientras no esté configurado; hasta que se configure, ese plan simplemente no se ofrece en el checkout público — no bloquea el resto de la plataforma ni genera facturación incorrecta.

Verificación de Estudiantes y Docentes

Precio especial para suscriptores que verifican pertenecer a un dominio de correo académico configurado por el tenant (ej. @universidad.edu.co). La verificación es anual — vence automáticamente y se le pide al suscriptor volver a confirmar su dominio académico cada año.

  • Lista de dominios académicos válidos, configurable por tenant desde el dashboard
  • Precio especial asociado al plan de estudiante, distinto del precio de lista
  • Re-verificación anual automática — no es un descuento permanente sin control

Códigos de Regalo (2x1 / Bono Canjeable)

Un código de regalo activa una suscripción a $0, sin tocar Wompi en absoluto (sin card_token, sin cobro) — reusa el resto del flujo normal de activación (colisión de identidad, entitlement, notificación a HubSpot/Siigo). El plan se resuelve del propio código, no hace falta pasar plan_id.

UsoDescripción
2x1Un suscriptor activo comparte un código con otra persona, que obtiene la suscripción gratis por el mismo período
Bono/gift card B2BCódigos canjeables entregados en bloque (ej. como beneficio corporativo o promoción de marca)
Mutuamente excluyente con discount_code (cupón) y con el monto variable — no tiene sentido combinar "elijo mi propio precio" o un cupón con una activación a $0.

Oferta de Retención al Cancelar

Antes de cancelar de verdad, se le puede preguntar al suscriptor el motivo — y si el tenant configuró una oferta para ese motivo (desde Suscripciones → Ofertas de Retención en el dashboard), mostrarla como alternativa a la cancelación.

MotivoTipo de oferta posible
too_expensive (es muy caro)Descuento en la renovación
not_enough_time (no tengo tiempo de leer)Pausar la suscripción N días
content_not_relevant (el contenido no me interesa)Cambiar a un plan más económico
other (otro)Ninguna — cancela directo siempre, por diseño

Paso 1: previsualizar la oferta

Antes de mostrarle la pantalla de cancelación al usuario, se puede consultar si hay una oferta configurada para el motivo que seleccionó:

POST https://engine.paywl.io/edge/cancellation-offer
Content-Type: application/json

{
  "domain": "<su-dominio>",
  "user_token": "<token de sesión del usuario>",
  "subscription_id": "<uuid>",
  "reason": "too_expensive"
}
// Hay oferta configurada
{ "offer": { "type": "discount", "discount_percent": 20, "pause_days": null, "downgrade_plan_id": null } }

// No hay oferta para ese motivo (incluye siempre "other")
{ "offer": null }

Paso 2: confirmar (aceptar la oferta, o cancelar de verdad)

POST https://engine.paywl.io/edge/cancel-subscription
Content-Type: application/json

{
  "domain": "<su-dominio>",
  "user_token": "<token de sesión del usuario>",
  "subscription_id": "<uuid>",
  "reason": "too_expensive",
  "accept_offer": true
}

Con accept_offer: true (y una oferta configurada para ese motivo), la suscripción no se cancela — sigue activa con el beneficio aplicado. Con accept_offer: false, o si no hay ninguna oferta configurada, se cancela de verdad. En ambos casos se guarda la respuesta de la encuesta para análisis posterior.

Descuento de retención: se aplica sobre cada renovación mientras la suscripción siga activa, sin fecha de fin — y se combina con el precio por fases si el suscriptor todavía está en una fase de introducción (ambos beneficios aplican a la vez).
Pausa temporal: la suscripción no cobra durante los días pausados y se reactiva sola al vencer el plazo — no hace falta ninguna acción del usuario ni del tenant para que vuelva a activarse.
Downgrade: no hay reembolso ni prorrateo del período ya pagado — el cambio de plan aplica desde la siguiente renovación.

Ciclo de Vida

1 Usuario inicia trial
2 Trial activo (N días)
3 Expira trial
4 Usuario paga → ACTIVE

Ejemplo: Crear Suscripción

curl -X POST https://engine.paywl.io/subscriptions/activate \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "subscriber_id": "user-123",
    "plan_id": "plan_mensual",
    "payment_reference": "WOMPI-TXN-456"
  }'