• Precios
  • Blog
Iniciar sesiónAgendá una demo
Introducción

Inicio rápido

Aprender

Administrar suscripcionesUpgrade y Downgrade de Planes

Recursos

Referencia del SDKVersionado de APIManejo de erroresTestingCLI

Plugins

Better Auth
DocumentaciónRecursosConstruir con AIAPI ReferenceWebhooks

Administrar suscripciones

Creá, consultá, cancelá, revertí y reactivá suscripciones con el SDK v9.

Instalá la Skill de Commet para que tu agente implemente el ciclo de vida actual de suscripciones y verifique el resultado.

npx skills add commet-labs/skills --skill commet

Las suscripciones conectan un customer con un plan y controlan checkout, invoices, acceso a features, uso y renovaciones.

Ciclo de vida

Los estados persistidos son:

EstadoSignificado
draftCreada pero todavía no lista para facturar
pending_paymentEsperando checkout
trialingEl acceso de prueba está activo
activeFacturación normal
past_dueFalló la renovación y dunning está activo
canceledFinalizaron la facturación y el acceso

Commet no expone estados de suscripción paused ni expired.

Crear

import { Commet } from "@commet/node";const commet = new Commet({ apiKey: "ck_xxx" });const createdSubscription = await commet.subscriptions.create({  customerId: "user_123",  planId: "pln_xxx",});
from commet import Commetcommet = Commet("ck_xxx")created_subscription = commet.subscriptions.create(    customer_id="user_123",    plan_id="pln_xxx",)
client, err := commet.New("ck_xxx")if err != nil {	log.Fatal(err)}ctx := context.Background()createdSubscription, err := client.Subscriptions.Create(ctx, &commet.CreateSubscriptionParams{	CustomerID: "user_123",	PlanID: func(value string) *string { return &value }("pln_xxx"),})if err != nil {	log.Fatal(err)}
import co.commet.Commet;import co.commet.params.CreateSubscriptionParams;var commet = Commet.builder().apiKey("ck_xxx").build();var createdSubscription = commet.subscriptions().create(    CreateSubscriptionParams.builder("user_123").planId("pln_xxx").build());
use Commet\Commet;$commet = new Commet('ck_xxx');$createdSubscription = $commet->subscriptions->create(    customerId: 'user_123',    planId: 'pln_xxx',);

Para un plan pago, redirigí al customer a checkoutUrl. Los planes gratuitos pueden activarse sin checkout y devolver checkoutUrl: null.

El flujo normal solo necesita customerId y planCode o planId. Los campos opcionales de selección son:

CampoCuándo enviarlo
billingIntervalEl customer eligió un intervalo que no es el default
priceIdEl customer eligió una variante concreta de precio
offerIdTu aplicación seleccionó una Offer directamente; reemplaza la selección introductoria automática
promoCodeEl customer ingresó un Promo Code
initialSeatsConocés las cantidades iniciales de seats
skipTrial o customTrialDaysQuerés reemplazar intencionalmente la prueba configurada

Omitir priceId conserva la resolución por defecto de precio y Market. Omitir offerId conserva la selección automática de la Introductory Offer.

Un checkout pending_payment compatible puede reutilizarse. Una selección pendiente incompatible puede reemplazarse sin duplicar una suscripción pagada.

Consultar estado actual o histórico

import { Commet } from "@commet/node";const commet = new Commet({ apiKey: "ck_xxx" });const subscription = await commet.subscriptions.getActive({ customerId: "user_123" });
from commet import Commetcommet = Commet("ck_xxx")subscription = commet.subscriptions.get_active(customer_id="user_123")
client, err := commet.New("ck_xxx")if err != nil {	log.Fatal(err)}ctx := context.Background()subscription, err := client.Subscriptions.GetActive(ctx, &commet.GetActiveSubscriptionParams{	CustomerID: "user_123",})if err != nil {	log.Fatal(err)}
import co.commet.Commet;import co.commet.params.GetActiveSubscriptionParams;var commet = Commet.builder().apiKey("ck_xxx").build();var subscription = commet.subscriptions().getActive(    GetActiveSubscriptionParams.builder("user_123").build());
use Commet\Commet;$commet = new Commet('ck_xxx');$subscription = $commet->subscriptions->getActive(customerId: 'user_123');

getActive devuelve la relación de suscripción actual del customer o null.

import { Commet } from "@commet/node";const commet = new Commet({ apiKey: "ck_xxx" });const subscription = await commet.subscriptions.get({ id: "sub_xxx" });
from commet import Commetcommet = Commet("ck_xxx")subscription = commet.subscriptions.get("sub_xxx")
client, err := commet.New("ck_xxx")if err != nil {	log.Fatal(err)}ctx := context.Background()subscription, err := client.Subscriptions.Get(ctx, "sub_xxx")if err != nil {	log.Fatal(err)}
import co.commet.Commet;var commet = Commet.builder().apiKey("ck_xxx").build();var subscription = commet.subscriptions().get("sub_xxx");
use Commet\Commet;$commet = new Commet('ck_xxx');$subscription = $commet->subscriptions->get(id: 'sub_xxx');

Usá get con el ID público para obtener cualquier estado persistido, incluidos pending_payment, past_due y canceled.

Cancelar

import { Commet } from "@commet/node";const commet = new Commet({ apiKey: "ck_xxx" });const subscription = await commet.subscriptions.cancel({ id: "sub_xxx" });
from commet import Commetcommet = Commet("ck_xxx")subscription = commet.subscriptions.cancel("sub_xxx")
client, err := commet.New("ck_xxx")if err != nil {	log.Fatal(err)}ctx := context.Background()subscription, err := client.Subscriptions.Cancel(ctx, "sub_xxx", nil)if err != nil {	log.Fatal(err)}
import co.commet.Commet;import co.commet.params.CancelSubscriptionParams;var commet = Commet.builder().apiKey("ck_xxx").build();var subscription = commet.subscriptions().cancel(    "sub_xxx",    CancelSubscriptionParams.builder().build());
use Commet\Commet;$commet = new Commet('ck_xxx');$subscription = $commet->subscriptions->cancel(id: 'sub_xxx');

Una suscripción paga y activa programa la cancelación al final del período salvo que envíes immediate: true. Las relaciones gratuitas, pendientes y past-due se cancelan inmediatamente. La cancelación no borra el balance almacenado.

Revertir una cancelación programada

import { Commet } from "@commet/node";const commet = new Commet({ apiKey: "ck_xxx" });const subscription = await commet.subscriptions.uncancel({ id: "sub_xxx" });
from commet import Commetcommet = Commet("ck_xxx")subscription = commet.subscriptions.uncancel("sub_xxx")
client, err := commet.New("ck_xxx")if err != nil {	log.Fatal(err)}ctx := context.Background()subscription, err := client.Subscriptions.Uncancel(ctx, "sub_xxx", nil)if err != nil {	log.Fatal(err)}
import co.commet.Commet;import co.commet.params.UncancelSubscriptionParams;var commet = Commet.builder().apiKey("ck_xxx").build();var subscription = commet.subscriptions().uncancel(    "sub_xxx",    UncancelSubscriptionParams.builder().build());
use Commet\Commet;$commet = new Commet('ck_xxx');$subscription = $commet->subscriptions->uncancel(id: 'sub_xxx');

uncancel funciona solamente antes de que una cancelación al final del período se haga efectiva. Conserva la misma suscripción y período actual.

Recuperar una suscripción past-due

Reactivate reintenta el cobro de renovación pendiente y conserva la relación original:

import { Commet } from "@commet/node";const commet = new Commet({ apiKey: "ck_xxx" });const reactivatedSubscription = await commet.subscriptions.reactivate({ id: "sub_xxx" });
from commet import Commetcommet = Commet("ck_xxx")reactivated_subscription = commet.subscriptions.reactivate("sub_xxx")
client, err := commet.New("ck_xxx")if err != nil {	log.Fatal(err)}ctx := context.Background()reactivatedSubscription, err := client.Subscriptions.Reactivate(ctx, "sub_xxx", nil)if err != nil {	log.Fatal(err)}
import co.commet.Commet;import co.commet.params.ReactivateSubscriptionParams;var commet = Commet.builder().apiKey("ck_xxx").build();var reactivatedSubscription = commet.subscriptions().reactivate(    "sub_xxx",    ReactivateSubscriptionParams.builder().build());
use Commet\Commet;$commet = new Commet('ck_xxx');$reactivatedSubscription = $commet->subscriptions->reactivate(id: 'sub_xxx');

Si el customer debe actualizar su medio de pago, creá un link de recuperación:

import { Commet } from "@commet/node";const commet = new Commet({ apiKey: "ck_xxx" });const recoveryLink = await commet.subscriptions.createRecoveryLink({ id: "sub_xxx" });
from commet import Commetcommet = Commet("ck_xxx")recovery_link = commet.subscriptions.create_recovery_link("sub_xxx")
client, err := commet.New("ck_xxx")if err != nil {	log.Fatal(err)}ctx := context.Background()recoveryLink, err := client.Subscriptions.CreateRecoveryLink(ctx, "sub_xxx", nil)if err != nil {	log.Fatal(err)}
import co.commet.Commet;import co.commet.params.CreateSubscriptionRecoveryLinkParams;var commet = Commet.builder().apiKey("ck_xxx").build();var recoveryLink = commet.subscriptions().createRecoveryLink(    "sub_xxx",    CreateSubscriptionRecoveryLinkParams.builder().build());
use Commet\Commet;$commet = new Commet('ck_xxx');$recoveryLink = $commet->subscriptions->createRecoveryLink(id: 'sub_xxx');

Los reintentos automáticos de dunning se anclan al rechazo original en los días 1, 3, 5 y 7. Un cobro exitoso devuelve la suscripción a active.

Reactivar una suscripción cancelada

La misma operación reactivate cobra el medio de pago guardado, reutiliza el registro de suscripción y comienza un período nuevo anclado a la fecha de reactivación. Podés enviar un offerId; las fases aceptadas se persisten como una Offer Application inmutable.

El precio seleccionado no se guarda como snapshot. Las renovaciones futuras usan su valor actual de catálogo. Archivar ese precio impide nuevas selecciones, pero no rompe la suscripción existente.

Relacionado

  • Cambiar de plan
  • Manejar pagos fallidos
  • Precios regionales y por Market
  • Introductory Offers
  • Customer Portal

¿Cómo está esta guía?

Períodos de prueba

Usa fases de prueba gratuita en Offers para onboarding automático o campañas explícitas.

Upgrade y Downgrade de Planes

Cómo cambian de plan los clientes desde el Portal del Cliente y el dashboard.

On this page

Ciclo de vida
Crear
Consultar estado actual o histórico
Cancelar
Revertir una cancelación programada
Recuperar una suscripción past-due
Reactivar una suscripción cancelada
Relacionado