Change Plan API
Plan Change Preview
Integration Guide
¿Qué es una actualización o degradación de una suscripción?
Cambia el plan de suscripción de un cliente para moverlo entre niveles, ajustar la cantidad de productos basados en asientos o migrarlo a un producto nuevo. La API calcula automáticamente los prorrateos y los cargos según el modo de facturación elegido.Cuándo usar cambios de plan
- Upgrade when a customer needs more features, usage, or seats
- Downgrade when usage decreases
- Migrate users to a new product or price without cancelling their subscription
Plan Change Flow
Prerequisites
Before implementing subscription plan changes, ensure you have:- A Dodo Payments merchant account with active subscription products
- API credentials (API key and webhook secret key) from the dashboard
- An existing active subscription to modify
- Webhook endpoint configured to handle subscription events
Step-by-Step Implementation Guide
Follow this comprehensive guide to implement subscription plan changes in your application:Understand Plan Change Requirements
- Which subscription products can be changed to which others
- What proration mode fits your business model
- How to handle failed plan changes gracefully
- Which webhook events to track for state management
Choose Your Proration Strategy
- prorated_immediately
- difference_immediately
- full_immediately
- do_not_bill
- Acredita la parte no utilizada del ciclo actual, prorrateada según el tiempo restante
- Después cobra un ciclo completo del plan nuevo; el precio del plan nuevo nunca se prorratea
- Cargo neto = ciclo nuevo completo − (fracción restante × ciclo anterior completo)
Implement the Change Plan API
prorated_immediately, full_immediately, difference_immediately, or do_not_bill.null o enviar un array vacío elimina cualquier complemento existente, por lo que debes incluir los complementos actuales para conservarlos.prevent_change: Keep subscription on current plan until payment succeedsapply_change(default): Apply plan change immediately regardless of payment outcome
allow_plan_change_via_payment_link (Settings → Subscriptions → Collect Plan Change Payments by Payment Link), effective_at: immediately y on_payment_failure: prevent_change. Consulta Cobrar pagos mediante un enlace de Checkout. La ruta de vista previa lo ignora.- No proporcionado /
null— los descuentos existentes conpreserve_on_plan_change=truese conservan si son aplicables al producto nuevo. [](array vacío) — elimina todos los descuentos existentes de la suscripción.["CODE_A", "CODE_B", ...]— reemplaza los descuentos existentes por este conjunto apilado.
discount_codes. Este campo sigue funcionando por compatibilidad con versiones anteriores, pero no se puede combinar con discount_codes en la misma solicitud.immediately(predeterminado): aplica el cambio de plan de inmediatonext_billing_date: programa el cambio para la próxima fecha de facturación. El cliente conserva su plan actual hasta que finaliza el período de facturación. Úsalo para degradaciones, de modo que los clientes mantengan los beneficios de su plan actual hasta el final del período de facturación.
Handle Webhook Events
subscription.active: cambio de plan exitoso, suscripción actualizadasubscription.plan_changed: plan de suscripción cambiado (actualización/degradación/actualización de addon)subscription.on_hold: falló el cargo del cambio de plan, renovaciones detenidaspayment.succeeded: el cargo inmediato del cambio de plan se realizó correctamentepayment.failed: falló el cargo inmediato
Update Your Application State
- Concede o revoca funciones según el plan nuevo
- Actualiza el panel del cliente con los detalles del plan nuevo
- Envía correos electrónicos de confirmación sobre los cambios de plan
- Registra los cambios de facturación para fines de auditoría
Test and Monitor
- Prueba todos los modos de prorrateo con diferentes escenarios
- Verifica que el manejo de webhooks funcione correctamente
- Supervisa las tasas de éxito de los cambios de plan
- Configura alertas para los cambios de plan fallidos
Vista previa de cambios de plan
Antes de confirmar un cambio de plan, usa la API de vista previa para mostrar a los clientes exactamente cuánto se les cobrará:- Node.js SDK
- Python SDK
API de cambio de plan
Usa la API de cambio de plan para modificar el producto, la cantidad y el comportamiento del prorrateo de una suscripción activa.Ejemplos de inicio rápido
- Node.js SDK
- Python SDK
- Go SDK
- HTTP
200 OK inmediatamente, antes de que se liquide realmente cualquier cargo. El contenido del cuerpo (ChangePlanResponse) depende de cómo se haya cobrado el cambio:
collect_via_payment_link, la suscripción conserva su plan actual hasta que el cliente complete el pago.Confirma el resultado mediante un webhook (payment.succeeded, payment.failed, subscription.plan_changed) o volviendo a leer la suscripción con GET /subscriptions/{subscription_id}. Consulta Qué ocurre mientras el enlace no está pagado para el caso de un enlace de pago.Cobrar mediante un enlace de Checkout
De forma predeterminada, un cambio de plan inmediato cobra directamente al método de pago guardado de la suscripción. Establececollect_via_payment_link: true para enviar al cliente a una página de Checkout alojada; resulta útil cuando no hay un método de pago guardado o cuando deseas que el cliente confirme activamente el precio nuevo.
Requisitos
collect_via_payment_link: true solo funciona correctamente cuando se cumplen todas las condiciones siguientes; de lo contrario, la solicitud falla con 422:
- La empresa tiene habilitada la capacidad
allow_plan_change_via_payment_link(Settings → Subscriptions → Collect Plan Change Payments by Payment Link). effective_atesimmediately(el valor predeterminado). Un cambio programado (next_billing_date) nunca necesita una página de Checkout.- El
on_payment_failureefectivo se resuelve enprevent_change. No tienes que enviarlo explícitamente: si el valor predeterminado de tu empresa ya esprevent_change, omitir el campo cumple este requisito. Unapply_changeexplícito falla con422.
collect_via_payment_link se aplica a cualquier cambio inmediato que genere un cargo, incluidas las degradaciones, siempre que se cumplan los requisitos anteriores.payment_link y los demás campos de Checkout devuelven null, y el cambio se aplica inmediatamente. Esto no es un 422. Llama primero a Vista previa del cambio de plan para comprobar el importe antes de solicitar un enlace.
- Node.js SDK
- Python SDK
- HTTP
Qué ocurre mientras el enlace no está pagado
- La suscripción conserva su plan actual;
product_id,recurring_pre_tax_amountenext_billing_datepermanecen sin cambios hasta que se paga el enlace. - Una solicitud adicional de
change-planse rechaza con409 PendingPlanChangeExistsmientras el enlace está pendiente. Cancela un cambio programado conDELETE /subscriptions/{subscription_id}/change-plan/scheduledsi es necesario, pero ese endpoint no cancela un cambio de enlace de pago pendiente; solo un pago exitoso o el vencimiento pueden hacerlo. - El cliente puede volver a intentar pagar con tarjeta en la misma sesión de Checkout después de un rechazo; una nueva llamada a
change-planno es el método para reintentar. - Si el enlace nunca se paga, deja de funcionar después de
expires_on; la suscripción vuelve a estar disponible automáticamente para aceptar una nueva solicitud de cambio de plan poco después. - Si ya existía un cambio programado y lo reemplazas con
cancel_scheduled_change_plan: true, la programación original permanece mientras el enlace no se haya pagado y solo se cancela cuando se paga el enlace, en la misma transacción que aplica el plan nuevo.
Gestión de addons
Al cambiar los planes de suscripción, también puedes modificar los addons:Aplicación de códigos de descuento
Aplica uno o más códigos de descuento apilados al cambiar los planes de suscripción (máximo 20, aplicados en el orden del array):- Node.js SDK
- Python SDK
- HTTP
Comportamiento de los descuentos al cambiar de plan
discount_code de este endpoint está obsoleto, pero sigue funcionando por compatibilidad con versiones anteriores; las integraciones existentes no necesitan cambiar de inmediato. No se puede combinar con discount_codes en la misma solicitud. Migra al formato de array cuando te resulte conveniente.Modos de prorrateo
Elige cómo cobrar al cliente al cambiar de plan:prorated_immediately
- Acredita la parte no utilizada del ciclo actual —plan base, cantidad y addons— prorrateada según el tiempo restante
- Después cobra un ciclo completo del plan, la cantidad y los addons nuevos. El cargo en sí nunca se prorratea
- Cargo inmediato neto = (ciclo nuevo completo) − (fracción restante × ciclo anterior completo)
- Si el crédito supera el cargo del ciclo nuevo, algo habitual en las degradaciones, la diferencia se conserva como crédito asociado a la suscripción para futuras renovaciones
- Si está en período de prueba, cobra inmediatamente y cambia al plan nuevo ahora
full_immediately
- Cobra inmediatamente el importe completo del plan nuevo
- Ignora el tiempo restante del plan anterior; no hay crédito por el ciclo actual
prorated_immediately y por degradaciones que usan difference_immediately están asociados a la suscripción y son distintos de las asignaciones de Credit-Based Billing. Se aplican automáticamente a futuras renovaciones de la misma suscripción y no se pueden transferir entre suscripciones.difference_immediately
- Actualización: cobra inmediatamente la diferencia de precio entre los planes anterior y nuevo
- Degradación: añade el valor restante como crédito interno a la suscripción y lo aplica automáticamente en las renovaciones
do_not_bill
- No se calculan cargos ni créditos
- El cliente cambia inmediatamente al plan nuevo sin ningún ajuste de facturación
- El ciclo de facturación no cambia
- Ideal para migraciones de cortesía, cambios a planes gratuitos o para absorber diferencias de costo
Ejemplos de escenarios
Usa estos valores canónicos de forma coherente:- Plan actual: Basic a $30/mes
- Objetivo de actualización: Pro a $80/mes
- Objetivo de degradación (desde Pro): Starter a $20/mes
- Ciclo de facturación: 30 días, iniciado el 1 de enero
- El cambio de plan ocurre el 16 de enero (quedan 15 días y se han utilizado 15 días)
Upgrade: Basic ($30) → Pro ($80) with prorated_immediately
Upgrade: Basic ($30) → Pro ($80) with prorated_immediately
Downgrade: Pro ($80) → Starter ($20) with prorated_immediately
Downgrade: Pro ($80) → Starter ($20) with prorated_immediately
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Upgrade: Basic ($30) → Pro ($80) with difference_immediately
Downgrade: Pro ($80) → Starter ($20) with difference_immediately
Downgrade: Pro ($80) → Starter ($20) with difference_immediately
Upgrade: Basic ($30) → Pro ($80) with full_immediately
Upgrade: Basic ($30) → Pro ($80) with full_immediately
Mid-cycle upgrade with add-ons using prorated_immediately
Mid-cycle upgrade with add-ons using prorated_immediately
Cómo procesa la facturación cada modo
Gestión de fallos de pago
Controla qué ocurre cuando falla el pago de un cambio de plan mediante el parámetroon_payment_failure.
Modos de fallo de pago
- prevent_change (Recommended for critical upgrades)
- apply_change (Default)
- El cambio de plan se marca como “pending”
- El cliente conserva el acceso a su plan actual
- La suscripción pasa al estado
activesolo después de que el pago se realice correctamente - Es útil cuando deseas asegurarte de recibir el pago antes de conceder funciones actualizadas
on_payment_failure usa la configuración predeterminada de tu empresa establecida en el dashboard.Cuándo usar cada modo
Valores predeterminados de empresa y cobro
Establece el comportamiento predeterminado de las actualizaciones y degradaciones a nivel de empresa en Settings → Subscriptions. Estos valores se aplican a todos los cambios de plan del portal del cliente y se pueden sustituir por colección de productos. Existen valores predeterminados independientes para actualizaciones y degradaciones:Orden de resolución
Para cualquier cambio de plan, cada configuración se resuelve en este orden:Gestión de webhooks
Realiza un seguimiento del estado de las suscripciones mediante webhooks para confirmar los cambios de plan y los pagos.Tipos de eventos que se deben gestionar
subscription.active: suscripción activadasubscription.plan_changed: plan de suscripción cambiado (actualizaciones/degradaciones/cambios de addons)subscription.on_hold: cargo fallido, renovaciones detenidassubscription.renewed: renovación exitosapayment.succeeded: pago del cambio de plan o de la renovación realizado correctamentepayment.failed: pago fallido
Verificación de firmas y gestión de intents
- Next.js Route Handler
- Express.js
Prácticas recomendadas
Estrategia de cambio de plan
- Prueba exhaustivamente: prueba siempre los cambios de plan en modo de prueba antes de usarlos en producción
- Elige el prorrateo con cuidado: selecciona el modo de prorrateo que se ajuste a tu modelo de negocio
- Gestiona los fallos correctamente: implementa un manejo de errores y una lógica de reintentos adecuados
- Supervisa las tasas de éxito: realiza un seguimiento de las tasas de éxito y fallo de los cambios de plan e investiga los problemas
Implementación de webhooks
- Verifica las firmas: valida siempre las firmas de los webhooks para garantizar su autenticidad
- Implementa la idempotencia: gestiona correctamente los eventos de webhook duplicados
- Procesa de forma asíncrona: no bloquees las respuestas de los webhooks con operaciones pesadas
- Regístralo todo: mantén registros detallados para la depuración y la auditoría
Experiencia de usuario
- Comunica con claridad: informa a los clientes sobre los cambios de facturación y sus fechas
- Proporciona confirmaciones: envía correos electrónicos de confirmación para los cambios de plan exitosos
- Gestiona los casos extremos: considera los períodos de prueba, los prorrateos y los pagos fallidos
- Actualiza la interfaz de inmediato: refleja los cambios de plan en la interfaz de tu aplicación
Problemas comunes y soluciones
Resuelve los problemas habituales que surgen durante los cambios de plan de suscripción:Charge created but subscription not updated
Charge created but subscription not updated
- El procesamiento del webhook falló o se retrasó
- El estado de la aplicación no se actualizó después de recibir los webhooks
- Problemas con la transacción de la base de datos durante la actualización del estado
- Implementa el manejo de webhooks con lógica de reintentos
- Usa operaciones idempotentes para las actualizaciones de estado
- Añade supervisión para detectar y alertar sobre eventos de webhook omitidos
- Verifica que el endpoint del webhook sea accesible y responda correctamente
Credits not applied after downgrade
Credits not applied after downgrade
- Expectativas sobre el modo de prorrateo: las degradaciones acreditan la diferencia de precio completa del plan con
difference_immediately, mientras queprorated_immediatelyacredita el tiempo no utilizado del ciclo anterior y después cobra un ciclo completo del plan nuevo; por eso, solo queda un saldo de crédito cuando ese crédito supera el precio del plan nuevo - Los créditos son específicos de la suscripción y no se transfieren entre suscripciones
- El saldo de crédito no es visible en el panel del cliente
- Usa
difference_immediatelypara las degradaciones cuando quieras créditos automáticos - Explica a los clientes que los créditos se aplican a futuras renovaciones de la misma suscripción
- Implementa el portal del cliente para mostrar los saldos de crédito
- Consulta la vista previa de la próxima factura para ver los créditos aplicados
Webhook signature verification fails
Webhook signature verification fails
- Clave secreta de webhook incorrecta
- El cuerpo sin procesar de la solicitud se modificó antes de verificar la firma
- Algoritmo de verificación de firma incorrecto
- Verifica que estés usando el
DODO_PAYMENTS_WEBHOOK_KEYcorrecto del dashboard - Lee el cuerpo sin procesar de la solicitud antes de cualquier middleware de análisis JSON
- Usa la biblioteca estándar de verificación de webhooks para tu plataforma
- Prueba la verificación de firmas de webhook en el entorno de desarrollo
Plan change fails with 422 error
Plan change fails with 422 error
- ID de suscripción o ID de producto no válido
- La suscripción no está activa
- Faltan parámetros obligatorios
- El producto no está disponible para cambios de plan
- Verifica que la suscripción exista y esté activa
- Comprueba que el ID de producto sea válido y esté disponible
- Asegúrate de proporcionar todos los parámetros obligatorios
- Consulta la documentación de la API para conocer los requisitos de los parámetros
Immediate charge fails during plan change
Immediate charge fails during plan change
- Fondos insuficientes en el método de pago del cliente
- Método de pago vencido o no válido
- El banco rechazó la transacción
- La detección de fraude bloqueó el cargo
- Gestiona correctamente los eventos de webhook
payment.failed - Notifica al cliente que actualice su método de pago
- Implementa una lógica de reintentos para fallos temporales
- Considera permitir cambios de plan con cargos inmediatos fallidos
Subscription on hold after plan change
Subscription on hold after plan change
on_holdQué ocurre:
Cuando falla el cargo de un cambio de plan, la suscripción pasa automáticamente al estado on_hold. La suscripción no se renovará automáticamente hasta que se actualice el método de pago.Solución: actualiza el método de pago para reactivar la suscripciónPara reactivar una suscripción desde el estado on_hold después de un cambio de plan fallido:- Actualiza el método de pago mediante la API de actualización del método de pago
- Creación automática del cargo: la API crea automáticamente un cargo por los importes pendientes
- Generación de la factura: se genera una factura para el cargo
- Procesamiento del pago: el pago se procesa usando el método de pago nuevo
- Reactivación: tras un pago exitoso, la suscripción se reactiva al estado
active
subscription.on_hold: suscripción puesta en espera (se recibe cuando falla el cargo del cambio de plan)payment.succeeded: pago de los importes pendientes realizado correctamente (después de actualizar el método de pago)subscription.active: suscripción reactivada después de un pago exitoso
- Notifica inmediatamente a los clientes cuando falle un cargo de cambio de plan
- Proporciona instrucciones claras sobre cómo actualizar el método de pago
- Supervisa los eventos de webhook para realizar un seguimiento del estado de reactivación
- Considera implementar una lógica de reintentos automáticos para fallos de pago temporales
Update Payment Method API Reference
Prueba de tu implementación
Prueba exhaustivamente tu implementación de cambios de plan de suscripción:Set up test environment
- Usa API keys de prueba y productos de prueba
- Crea suscripciones de prueba con distintos tipos de planes
- Configura el endpoint de webhook de prueba
- Configura la supervisión y el registro
Test different proration modes
- Prueba
prorated_immediatelycon distintas posiciones del ciclo de facturación - Prueba
difference_immediatelypara actualizaciones y degradaciones - Prueba
full_immediatelypara reiniciar los ciclos de facturación - Prueba
do_not_billpara cambios de plan sin cargo ni crédito - Verifica que los cálculos de crédito sean correctos
Test webhook handling
- Verifica que se reciban todos los eventos de webhook relevantes
- Prueba la verificación de firmas de webhook
- Gestiona correctamente los eventos de webhook duplicados
- Prueba escenarios de fallos en el procesamiento de webhooks
Test error scenarios
- Prueba con IDs de suscripción no válidos
- Prueba con métodos de pago vencidos
- Prueba fallos de red y tiempos de espera agotados
- Prueba con fondos insuficientes
Monitor in production
- Configura alertas para los cambios de plan fallidos
- Supervisa los tiempos de procesamiento de webhooks
- Realiza un seguimiento de las tasas de éxito de los cambios de plan
- Revisa los tickets de soporte al cliente relacionados con problemas de cambios de plan
Gestión de errores
Gestiona correctamente los errores comunes de la API en tu implementación:Códigos de estado HTTP
200 OK
200 OK
ChangePlanResponse con payment_id, payment_link, client_secret e expires_on. Los cuatro valores aceptan null, por lo que el cuerpo se serializa como {} para un cambio normal fuera de sesión; se rellenan para una solicitud collect_via_payment_link exitosa, que devuelve identificadores de Checkout. Consulta Cobrar mediante un enlace de Checkout. Si on_payment_failure=prevent_change, el cambio de plan permanece pendiente hasta que se complete el pago.400 Bad Request
400 Bad Request
409 Conflict
409 Conflict
PendingPlanChangeExists). Para un cambio programado, cancélalo con DELETE /subscriptions/{subscription_id}/change-plan/scheduled antes de enviar uno nuevo. Para un cambio de enlace de pago pendiente, no existe ningún endpoint de cancelación; la suscripción acepta una nueva solicitud de cambio de plan cuando el cliente paga o el enlace vence.422 Unprocessable Entity
422 Unprocessable Entity
collect_via_payment_link: la empresa no tiene habilitada la capacidad, effective_at no es immediately o on_payment_failure no es prevent_change. Consulta Requisitos. Un ID de suscripción que no existe o no pertenece a tu cuenta devuelve 404 con el código NOT_FOUND.500 Internal Server Error
500 Internal Server Error
Formato de respuesta de error
Los errores devuelven un cuerpo JSON con uncode y un message legible para las personas:
Próximos pasos
- Revisa la API de cambio de plan
- Explora Credit-Based Billing
- Implementa alertas para
subscription.on_hold - Consulta la Guía de integración de webhooks