Saltar al contenido principal

Change Plan API

Full API docs for updating subscriptions.

Plan Change Preview

See charge amounts before changing plans.

Integration Guide

Step-by-step subscription setup.

What is a subscription upgrade or downgrade?

Changing plans lets you move a customer between subscription tiers or quantities. Use it to:
  • Align pricing with usage or features
  • Move from monthly to annual (or vice versa)
  • Adjust quantity for seat-based products
Plan changes can trigger an immediate charge depending on the proration mode you choose.

When to use plan changes

  • 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
For detailed setup instructions, see our Integration Guide.

Step-by-Step Implementation Guide

Follow this comprehensive guide to implement subscription plan changes in your application:
1

Understand Plan Change Requirements

Before implementing, determine:
  • 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
Test plan changes thoroughly in test mode before implementing in production.
2

Choose Your Proration Strategy

Select the billing approach that aligns with your business needs:
Best for: SaaS applications wanting to charge fairly for unused time
  • Calculates exact prorated amount based on remaining cycle time
  • Charges a prorated amount based on unused time remaining in the cycle
  • Provides transparent billing to customers
3

Implement the Change Plan API

Use the Change Plan API to modify subscription details:
subscription_id
string
requerido
The ID of the active subscription to modify.
product_id
string
requerido
The new product ID to change the subscription to.
quantity
integer
predeterminado:"1"
Number of units for the new plan (for seat-based products).
proration_billing_mode
string
requerido
How to handle immediate billing: prorated_immediately, full_immediately, difference_immediately, or do_not_bill.
addons
array
Optional addons for the new plan. Leaving this empty removes any existing addons.
on_payment_failure
string
Controls behavior when the plan change payment fails:
  • prevent_change: Keep subscription on current plan until payment succeeds
  • apply_change (default): Apply plan change immediately regardless of payment outcome
If not specified, uses the business-level default setting.
discount_codes
array
Códigos de descuento apilados opcionales para aplicar al nuevo plan (máx. 20, aplicado en el orden del array). El comportamiento depende de lo que pases:
  • No proporcionado / null — los descuentos existentes con preserve_on_plan_change=true se conservan si son aplicables al nuevo producto.
  • [] (array vacío) — elimina todos los descuentos existentes de la suscripción.
  • ["CODE_A", "CODE_B", ...] — reemplaza cualquier descuento existente con este conjunto apilado.
discount_code
string
obsoleto
Obsoleto — se prefiere discount_codes para nuevas integraciones. Este campo sigue funcionando para compatibilidad con versiones anteriores, pero no puede combinarse con discount_codes en la misma solicitud.
effective_at
string
predeterminado:"immediately"
Cuándo aplicar el cambio de plan:
  • immediately (por defecto): Aplicar el cambio de plan de inmediato
  • next_billing_date: Programar el cambio para la próxima fecha de facturación. El cliente conserva su plan actual hasta que finalice el período de facturación.
Usa next_billing_date para degradaciones para que los clientes mantengan los beneficios de su plan actual hasta el final del período de facturación.
4

Handle Webhook Events

Configurar el manejo de webhooks para rastrear los resultados del cambio de plan:
  • subscription.active: Cambio de plan exitoso, suscripción actualizada
  • subscription.plan_changed: Plan de suscripción cambiado (mejora/degradación/actualización de complemento)
  • subscription.on_hold: Fallo al cobrar el cambio de plan, suscripción pausada
  • payment.succeeded: Cargo inmediato por cambio de plan exitoso
  • payment.failed: Fallo en el cargo inmediato
Siempre verifica las firmas de los webhooks e implementa el procesamiento idempotente de eventos.
5

Update Your Application State

Basado en eventos de webhooks, actualiza tu aplicación:
  • Otorgar/revocar funciones según el nuevo plan
  • Actualizar el panel de control del cliente con los detalles del nuevo plan
  • Enviar correos electrónicos de confirmación sobre los cambios de plan
  • Registrar cambios de facturación para fines de auditoría
6

Test and Monitor

Prueba a fondo tu implementación:
  • Prueba todos los modos de prorrateo con diferentes escenarios
  • Verifica que el manejo de webhooks funcione correctamente
  • Monitorea las tasas de éxito de cambios de plan
  • Configura alertas para cambios de plan fallidos
Tu implementación de cambio de plan de suscripción está ahora lista para su uso en producción.

Previsualizar Cambios de Plan

Antes de comprometerse con un cambio de plan, utiliza la API de Vista Previa para mostrar a los clientes exactamente lo que se les cobrará:
const preview = await client.subscriptions.previewChangePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately'
});

// Show customer the charge before confirming
console.log('Immediate charge:', preview.immediate_charge.summary);
console.log('New plan details:', preview.new_plan);
Utiliza la API de vista previa para construir cuadros de diálogo de confirmación que muestren a los clientes la cantidad exacta que se les cobrará antes de que confirmen un cambio de plan.

API de Cambio de Plan

Utiliza la API de Cambio de Plan para modificar el producto, la cantidad y el comportamiento de prorrateo para una suscripción activa.

Ejemplos de inicio rápido

import DodoPayments from 'dodopayments';

const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'test_mode', // defaults to 'live_mode'
});

async function changePlan() {
  const result = await client.subscriptions.changePlan('sub_123', {
    product_id: 'prod_new',
    quantity: 3,
    proration_billing_mode: 'prorated_immediately',
    on_payment_failure: 'prevent_change', // Optional: control behavior on payment failure
  });
  console.log(result.status, result.invoice_id, result.payment_id);
}

changePlan();
Success
{
  "status": "processing",
  "subscription_id": "sub_123",
  "invoice_id": "inv_789",
  "payment_id": "pay_456",
  "proration_billing_mode": "prorated_immediately"
}
Campos como invoice_id y payment_id se devuelven solo cuando se crea un cargo y/o factura inmediato durante el cambio de plan. Siempre confía en los eventos de webhooks (por ejemplo, payment.succeeded, subscription.plan_changed) para confirmar resultados.
Si el cargo inmediato falla, la suscripción puede moverse a subscription.on_hold hasta que el pago tenga éxito.

Gestión de Complementos

Al cambiar los planes de suscripción, también puedes modificar los complementos:
// Add addons to the new plan
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_new',
  quantity: 1,
  proration_billing_mode: 'difference_immediately',
  addons: [
    { addon_id: 'addon_123', quantity: 2 }
  ]
});

// Remove all existing addons
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_new',
  quantity: 1,
  proration_billing_mode: 'difference_immediately',
  addons: [] // Empty array removes all existing addons
});
Los complementos están incluidos en el cálculo de prorrateo y se cobrarán de acuerdo con el modo de prorrateo seleccionado.

Aplicar Códigos de Descuento

Puedes aplicar uno o más códigos de descuento apilados al cambiar los planes de suscripción (máx. 20, aplicado en el orden del array). Esto es útil para ofrecer precios promocionales en actualizaciones o migraciones.
// Apply stacked discount codes during plan change
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately',
  discount_codes: ['UPGRADE20']
});

Comportamiento del descuento en el cambio de plan

Valor de discount_codesComportamiento
No proporcionado / nullLos descuentos existentes con preserve_on_plan_change=true se conservan automáticamente si son aplicables al nuevo producto.
[] (array vacío)Se eliminan todos los descuentos existentes de la suscripción.
["CODE_A", "CODE_B", ...]Reemplaza cualquier descuento existente con este conjunto apilado, validado y aplicado en el orden del array.
El campo singular discount_code en este endpoint está obsoleto pero aún funciona para la compatibilidad con versiones anteriores: las integraciones existentes no necesitan cambiarse de inmediato. No puede combinarse con discount_codes en la misma solicitud. Migra a la forma de array cuando sea conveniente.
Usa la API de Vista Previa de Cambios de Plan con discount_codes para mostrar a los clientes exactamente cuánto ahorrarán antes de confirmar el cambio de plan.

Modos de Prorrateo

Elige cómo facturar al cliente al cambiar de plan:

prorated_immediately

  • Cargos por la diferencia parcial en el ciclo actual
  • Si está en prueba, cobra inmediatamente y cambia al nuevo plan ahora
  • Degradación: puede generar un crédito prorrateado aplicado a futuras renovaciones

full_immediately

  • Cobra el monto completo del nuevo plan inmediatamente
  • Ignora el tiempo restante del plan antiguo
Los créditos creados por degradaciones usando difference_immediately están limitados a la suscripción y son distintos de los derechos de Facturación Basada en Créditos. Se aplican automáticamente a futuras renovaciones de la misma suscripción y no son transferibles entre suscripciones.

difference_immediately

  • Mejora: cobra de inmediato la diferencia de precio entre los planes viejo y nuevo
  • Degradación: añade el valor restante como crédito interno a la suscripción y se aplica automáticamente en las renovaciones

do_not_bill

  • No se calculan cargos ni créditos
  • El cliente cambia al nuevo plan inmediatamente sin ningún ajuste de facturación
  • El ciclo de facturación permanece sin cambios
  • Ideal para migraciones de cortesía, cambios de plan gratuitos o absorción de diferencias de costo
Featureprorated_immediatelydifference_immediatelyfull_immediatelydo_not_bill
Upgrade chargeDiferencia prorrateada por los días restantesDiferencia del precio completo entre planesPrecio completo del nuevo planSin cargo
Downgrade creditCrédito prorrateado por los días restantesDiferencia de precio completo como créditoSin créditoSin crédito
Billing cycleSe restablece a hoySe restablece a hoySe restablece a hoySin cambios
Trial behaviorTermina el periodo de prueba, se cobra inmediatamenteTermina el periodo de prueba, se cobra inmediatamenteTermina el periodo de prueba, se cobra el monto completoTermina el periodo de prueba, sin cargo
Best forFacturación justa basada en el tiempoMatemáticas simples de actualización/degradaciónRestablecer ciclos de facturaciónMigraciones gratuitas o cambios de cortesía
ComplexityMedia (cálculo de días)Baja (resta simple)Baja (cobro completo)Ninguna

Escenarios de Ejemplo

Usa estos números canónicos de manera consistente:
  • Plan actual: Básico a $30/mes
  • Objetivo de mejora: Pro a $80/mes
  • Objetivo de degradación (de Pro): Starter a $20/mes
  • Ciclo de facturación: 30 días, comenzado el 1 de enero
  • El cambio de plan ocurre el 16 de enero (15 días restantes, 15 días usados)
Step 1: Calculate unused credit from current plan
  Unused days = 15 out of 30 days
  Credit = $30 × (15/30) = $15.00

Step 2: Calculate prorated cost of new plan
  Remaining days = 15 out of 30 days
  New plan cost = $80 × (15/30) = $40.00

Step 3: Calculate immediate charge
  Charge = New plan cost − Credit
  Charge = $40.00 − $15.00 = $25.00

→ Customer pays $25.00 now
→ Billing cycle resets to today (January 16)
→ Next renewal (Feb 15): $80.00/month
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately'
})
Step 1: Calculate unused credit from current plan
  Unused days = 15 out of 30 days
  Credit = $80 × (15/30) = $40.00

Step 2: Calculate prorated cost of new plan
  Remaining days = 15 out of 30 days
  New plan cost = $20 × (15/30) = $10.00

Step 3: Calculate credit balance
  Credit = $40.00 − $10.00 = $30.00

→ No charge — $30.00 credit added to subscription
→ Billing cycle resets to today (January 16)
→ Credit auto-applies to future renewals
→ Next renewal (Feb 15): $20.00 − $20.00 (from credit) = $0.00 ($10.00 credit remaining)
→ Following renewal (Mar 15): $20.00 − $10.00 remaining credit = $10.00
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_starter',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately'
})
Immediate charge = New plan price − Old plan price
                 = $80 − $30
                 = $50.00

→ Customer pays $50.00 now (regardless of cycle position)
→ Billing cycle resets to today (January 16)
→ Next renewal (Feb 15): $80.00/month
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'difference_immediately'
})
Credit = Old plan price − New plan price
       = $80 − $20
       = $60.00

→ No charge — $60.00 credit added to subscription
→ Credit auto-applies to future renewals
→ Next renewal: $20.00 − $20.00 (from credit) = $0.00
→ Following renewal: $20.00 − $20.00 (from credit) = $0.00
→ Third renewal: $20.00 − $20.00 (from remaining credit) = $0.00
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_starter',
  quantity: 1,
  proration_billing_mode: 'difference_immediately'
})
Immediate charge = Full new plan price = $80.00

→ Customer pays $80.00 now
→ No credit for unused time on old plan
→ Billing cycle resets to today (January 16)
→ Next renewal: February 16 at $80.00/month
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'full_immediately'
})
Current: Basic plan ($30/month), no add-ons
New: Pro plan ($80/month) + Extra Seats add-on ($10/seat × 3 seats = $30/month)
Change on day 16 of 30 (15 days remaining)

Step 1: Credit from current plan
  Credit = $30 × (15/30) = $15.00

Step 2: Prorated cost of new plan + add-ons
  New plan = $80 × (15/30) = $40.00
  Add-ons = $30 × (15/30) = $15.00
  Total new = $55.00

Step 3: Immediate charge
  Charge = $55.00 − $15.00 = $40.00

→ Customer pays $40.00 now
→ Next renewal: $80.00 + $30.00 = $110.00/month
await client.subscriptions.changePlan('sub_123', {
  product_id: 'prod_pro',
  quantity: 1,
  proration_billing_mode: 'prorated_immediately',
  addons: [
    { addon_id: 'addon_seats', quantity: 3 }
  ]
})

Cómo cada modo procesa la facturación

Elige prorated_immediately para contabilidad de tiempo justo; selecciona full_immediately para reiniciar la facturación; usa difference_immediately para mejoras simples y crédito automático en degradaciones; o usa do_not_bill para cambiar de plan sin ningún ajuste de facturación.

Manejo de Fallos de Pago

Controla lo que sucede cuando falla el pago de un cambio de plan usando el parámetro on_payment_failure.

Modos de Fallo de Pago

Si no se especifica, el parámetro on_payment_failure utiliza la configuración predeterminada a nivel empresarial configurada en el panel de control.

Cuándo Usar Cada Modo

EscenarioModo RecomendadoRazón
Mejora a funciones premiumprevent_changeAsegura el pago antes de otorgar acceso
Aumento de cantidad (más asientos)prevent_changeEvita el uso sin pago
Degradación de planesapply_changeEl cliente está reduciendo el gasto
Clientes empresariales de confianzaapply_changeMenor riesgo de incumplimiento de pago
Conversión de prueba a pagoprevent_changeMomento crítico de pago

Valores predeterminados de Negocio y Colección

En lugar de pasar parámetros de prorrateo en cada cambio de plan, puedes configurar el comportamiento de actualización y degradación predeterminado una vez a nivel de negocio. Estos valores predeterminados se aplican a todos los cambios de plan en el portal del cliente y se pueden sobrescribir por colección de productos. Existen valores predeterminados separados para actualizaciones y degradaciones:
ConfiguraciónCampo (actualización / degradación)Predeterminado (actualización)Predeterminado (degradación)
Cuándo comienza el nuevo planeffective_at_on_upgrade / effective_at_on_downgradeimmediatelynext_billing_date
Cómo se cobra al clienteproration_billing_mode_on_upgrade / proration_billing_mode_on_downgradedifference_immediatelydifference_immediately
Si el pago del cliente fallaon_payment_failureapply_changeapply_change
Configura los predeterminados de negocio en Ajustes → Suscripciones y los reemplazos de colección en cada colección de productos. Cada campo de colección es independiente: déjalo sin configurar para heredar del valor predeterminado del negocio, o establece un valor para sobrescribirlo solo para esa colección.

Orden de resolución

Para cualquier cambio de plan, cada configuración se resuelve en este orden:
per-request value (Change Plan API) → collection field (if set) → business field → system default
Un valor pasado explícitamente a la API de Cambio de Plan siempre prevalecerá. Los valores predeterminados de negocio y colección solo entran en efecto cuando no se proporciona un valor explícito, lo cual ocurre en todos los cambios de plan iniciados desde el portal del cliente.
Una configuración común: mantén las actualizaciones immediately + difference_immediately para que los clientes paguen la diferencia y obtengan acceso de inmediato, y mantén las degradaciones en next_billing_date para que los clientes conserven su plan actual hasta que termine el ciclo.

Manejo de webhooks

Rastrea el estado de la suscripción a través de webhooks para confirmar cambios de plan y pagos.

Tipos de eventos a manejar

  • subscription.active: suscripción activada
  • subscription.plan_changed: plan de suscripción cambiado (cambios de actualización/degradación/addon)
  • subscription.on_hold: cargo fallido, suscripción pausada
  • subscription.renewed: renovación exitosa
  • payment.succeeded: pago por cambio de plan o renovación exitoso
  • payment.failed: pago fallido
Recomendamos dirigir la lógica empresarial a partir de eventos de suscripción y usar eventos de pago para confirmación y conciliación.

Verificar firmas y manejar intenciones

import { NextRequest, NextResponse } from 'next/server';

export async function POST(req) {
  const webhookId = req.headers.get('webhook-id');
  const webhookSignature = req.headers.get('webhook-signature');
  const webhookTimestamp = req.headers.get('webhook-timestamp');
  const secret = process.env.DODO_WEBHOOK_SECRET;

  const payload = await req.text();
  // verifySignature is a placeholder – in production, use a Standard Webhooks library
  const { valid, event } = await verifySignature(
    payload,
    { id: webhookId, signature: webhookSignature, timestamp: webhookTimestamp },
    secret
  );
  if (!valid) return NextResponse.json({ error: 'Invalid signature' }, { status: 400 });

  switch (event.type) {
    case 'subscription.active':
      // mark subscription active in your DB
      break;
    case 'subscription.plan_changed':
      // refresh entitlements and reflect the new plan in your UI
      break;
    case 'subscription.on_hold':
      // notify user to update payment method
      break;
    case 'subscription.renewed':
      // extend access window
      break;
    case 'payment.succeeded':
      // reconcile payment for plan change
      break;
    case 'payment.failed':
      // log and alert
      break;
    default:
      // ignore unknown events
      break;
  }

  return NextResponse.json({ received: true });
}
Para esquemas de carga útil detallados, consulta Cargas útiles de webhook de suscripción y Cargas útiles de webhook de pago.

Mejores Prácticas

Sigue estas recomendaciones para cambios confiables en los planes de suscripción:

Estrategia de Cambio de Plan

  • Prueba a fondo: Siempre prueba los cambios de plan en modo de prueba antes de producción
  • Elige el prorrateo con cuidado: Selecciona el modo de prorrateo que se alinea con tu modelo de negocio
  • Maneja fallas con gracia: Implementa un manejo adecuado de errores y lógica de reintento
  • Monitorea tasas de éxito: Rastrea las tasas de éxito/falla de cambios de plan e investiga problemas

Implementación de Webhook

  • Verifica firmas: Valida siempre las firmas de los webhooks para asegurar su autenticidad
  • Implementa idempotencia: Lidia con los eventos de webhook duplicados con gracia
  • Procesa asincrónicamente: No bloquees las respuestas de webhook con operaciones pesadas
  • Registra todo: Mantén registros detallados para depuración y auditoría

Experiencia del Usuario

  • Comunica claramente: Informa a los clientes sobre los cambios de facturación y el tiempo
  • Proporciona confirmaciones: Envía confirmaciones por correo electrónico para cambios de plan exitosos
  • Maneja casos extremos: Considera períodos de prueba, prorrateos y pagos fallidos
  • Actualiza la interfaz de usuario inmediatamente: Refleja los cambios de plan en la interfaz de tu aplicación

Problemas Comunes y Soluciones

Resuelve problemas típicos encontrados durante los cambios de plan de suscripción:
Síntomas: La llamada a la API tiene éxito, pero la suscripción permanece en el plan antiguoCausas comunes:
  • El procesamiento del webhook falló o se retrasó
  • El estado de la aplicación no se actualizó después de recibir webhooks
  • Problemas de transacciones en la base de datos durante la actualización del estado
Soluciones:
  • Implementa un manejo robusto de webhooks con lógica de reintento
  • Usa operaciones idempotentes para actualizaciones de estado
  • Agrega monitoreo para detectar y alertar sobre eventos de webhook perdidos
  • Verifica que la URL del webhook sea accesible y responda correctamente
Síntomas: El cliente se degrada pero no ve saldo de créditoCausas comunes:
  • Expectativas del modo de prorrateo: las degradaciones acreditan la diferencia de precio completo del plan con difference_immediately, mientras que prorated_immediately crea un crédito prorrateado basado en el tiempo restante en el ciclo
  • Los créditos son específicos de suscripción y no se transfieren entre suscripciones
  • Saldo de crédito no visible en el panel del cliente
Soluciones:
  • Usa difference_immediately para 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 un portal del cliente para mostrar saldos de crédito
  • Verifica la vista previa de la próxima factura para ver los créditos aplicados
Síntomas: Eventos de webhook rechazados debido a una firma inválidaCausas comunes:
  • Clave secreta del webhook incorrecta
  • Cuerpo de la solicitud cruda modificado antes de la verificación de la firma
  • Algoritmo de verificación de firma incorrecto
Soluciones:
  • Verifica que estás usando el correcto DODO_WEBHOOK_SECRET desde el panel
  • Lee el cuerpo de la solicitud cruda 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 webhooks en el entorno de desarrollo
Síntomas: La API devuelve un error 422 Unprocessable EntityCausas comunes:
  • ID de suscripción o producto inválido
  • Suscripción no está en estado activo
  • Faltan parámetros requeridos
  • Producto no disponible para cambios de plan
Soluciones:
  • Verifica que la suscripción existe y está activa
  • Comprueba que el ID del producto sea válido y esté disponible
  • Asegúrate de que todos los parámetros requeridos están proporcionados
  • Revisa la documentación de la API para los requisitos de los parámetros
Síntomas: El cambio de plan se inicia pero el cobro inmediato fallaCausas comunes:
  • Fondos insuficientes en el método de pago del cliente
  • Método de pago vencido o inválido
  • El banco rechazó la transacción
  • La detección de fraude bloqueó el cargo
Soluciones:
  • Maneja eventos de webhook payment.failed apropiadamente
  • Notifica al cliente para actualizar el método de pago
  • Implementa lógica de reintento para fallas temporales
  • Considera permitir cambios de plan con cargos inmediatos fallidos
Síntomas: Falla el cobro del cambio de plan y la suscripción se mueve a estado on_holdQué sucede: Cuando falla un cobro de cambio de plan, la suscripción se coloca automáticamente en 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 fallo en el cambio de plan:
  1. Actualiza el método de pago usando la API de Actualización de Método de Pago
  2. Creación automática de cargos: La API crea automáticamente un cargo por los adeudos pendientes
  3. Generación de factura: Se genera una factura por el cargo
  4. Procesamiento de pagos: El pago se procesa usando el nuevo método de pago
  5. Reactivación: Una vez realizado el pago con éxito, la suscripción se reactiva al estado active
// Reactivate subscription from on_hold after failed plan change
async function reactivateAfterFailedPlanChange(subscriptionId) {
  // Update payment method - automatically creates charge for remaining dues
  const response = await client.subscriptions.updatePaymentMethod(subscriptionId, {
    type: 'new',
    return_url: 'https://example.com/return'
  });
  
  if (response.payment_id) {
    console.log('Charge created for remaining dues:', response.payment_id);
    console.log('Payment link:', response.payment_link);
    
    // Redirect customer to payment_link to complete payment
    // Monitor webhooks for:
    // 1. payment.succeeded - charge succeeded
    // 2. subscription.active - subscription reactivated
  }
  
  return response;
}

// Or use existing payment method if available
async function reactivateWithExistingPaymentMethod(subscriptionId, paymentMethodId) {
  const response = await client.subscriptions.updatePaymentMethod(subscriptionId, {
    type: 'existing',
    payment_method_id: paymentMethodId
  });
  
  // Monitor webhooks for payment.succeeded and subscription.active
  return response;
}
Eventos de webhook a monitorear:
  • subscription.on_hold: Suscripción en espera (recibido cuando falla el cobro del cambio de plan)
  • payment.succeeded: Pago exitoso de adeudos pendientes (después de actualizar el método de pago)
  • subscription.active: Suscripción reactivada tras pago exitoso
Mejores prácticas:
  • Notifica a los clientes inmediatamente cuando falla un cobro de cambio de plan
  • Proporciona instrucciones claras sobre cómo actualizar su método de pago
  • Monitorea eventos de webhook para rastrear el estado de reactivación
  • Considera implementar lógica de reintento automático para fallos temporales de pago

Update Payment Method API Reference

Consulta la documentación completa de la API para actualización de métodos de pago y reactivación de suscripciones.

Probando Tu Implementación

Sigue estos pasos para probar exhaustivamente la implementación del cambio de plan de suscripción:
1

Set up test environment

  • Usa claves de API de prueba y productos de prueba
  • Crea suscripciones de prueba con diferentes tipos de plan
  • Configura el endpoint de webhook de prueba
  • Configura monitoreo y registros
2

Test different proration modes

  • Prueba prorated_immediately con varias posiciones del ciclo de facturación
  • Prueba difference_immediately para actualizaciones y degradaciones
  • Prueba full_immediately para restablecer ciclos de facturación
  • Prueba do_not_bill para cambios de plan sin cargo/sin crédito
  • Verifica que los cálculos de crédito sean correctos
3

Test webhook handling

  • Verifica que se reciban todos los eventos de webhook relevantes
  • Prueba la verificación de firmas de los webhooks
  • Maneja eventos de webhook duplicados con gracia
  • Prueba escenarios de fallos en el procesamiento de webhooks
4

Test error scenarios

  • Prueba con IDs de suscripción inválidos
  • Prueba con métodos de pago vencidos
  • Prueba fallos de red y tiempos de espera
  • Prueba con fondos insuficientes
5

Monitor in production

  • Configura alertas para cambios de plan fallidos
  • Monitorea los tiempos de procesamiento de webhooks
  • Rastrea las tasas de éxito de los cambios de plan
  • Revisa los tickets de soporte al cliente por problemas de cambio de plan

Manejo de Errores

Maneja con gracia los errores comunes de la API en tu implementación:

Códigos de Estado HTTP

Solicitud de cambio de plan procesada exitosamente. La suscripción está siendo actualizada y el procesamiento de pagos ha comenzado.
Parámetros de solicitud inválidos. Verifica que todos los campos requeridos estén proporcionados y correctamente formateados.
Clave de API inválida o faltante. Verifica que tu DODO_PAYMENTS_API_KEY sea correcta y tenga los permisos adecuados.
ID de suscripción no encontrada o no pertenece a tu cuenta.
La suscripción no puede ser cambiada (por ejemplo, ya cancelada, producto no disponible, etc.).
Ocurrió un error en el servidor. Reintenta la solicitud después de un breve retraso.

Formato de Respuesta de Error

{
  "error": {
    "code": "subscription_not_found",
    "message": "The subscription with ID 'sub_123' was not found",
    "details": {
      "subscription_id": "sub_123"
    }
  }
}

Próximos pasos

Última modificación el 18 de junio de 2026