> ## Documentation Index
> Fetch the complete documentation index at: https://commet.co/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagos únicos

> Vende acceso de por vida o compras únicas con un solo cargo y sin cobros recurrentes.

Un plan de pago único cobra al cliente una sola vez en el checkout y nunca vuelve a cobrar por el plan base. Úsalo para deals de por vida, compras únicas o cualquier plan donde los cobros recurrentes no aplican.

<Note>
  Esta página cubre cargos únicos cobrados como un **plan**. Para cobrar a un cliente una sola vez **sin suscripción ni plan** — un recibo independiente con impuestos y comprobante — usa [Aceptar pagos únicos](/docs/es/accept-one-time-payments) en su lugar.
</Note>

Los planes de pago único se comportan como cualquier otro plan — soportan [trials](/docs/es/trial-periods), [intro offers](/docs/es/introductory-offers), [add-ons](/docs/es/add-ons) y todos los [modelos de consumo](/docs/es/consumption-models). Las únicas diferencias son:

| Aspecto | Comportamiento |
| - | - |
| **Cobros** | El plan base se cobra una vez en el checkout. El overage se cobra en cada ciclo de cobro. |
| **Cancelación** | No permitida — la suscripción queda activa de forma permanente |
| **Cambios de intervalo** | No permitidos — no puedes pasar de pago único a un intervalo recurrente |

## Configurar en el dashboard

En el dashboard, ve a **Plans**, edita un plan y agrega un precio con intervalo **One-time (lifetime)**. Puedes combinar precios únicos con intervalos recurrentes en el mismo plan — cada precio tiene su propio intervalo.

## Crear una suscripción de pago único

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    const subscription = await commet.subscriptions.create({
      customerId: 'user_123',
      planCode: 'pro',
      billingInterval: 'one_time',
    })

    if (!subscription.checkoutUrl) {
      throw new Error('Commet did not return a checkout URL')
    }

    redirect(subscription.checkoutUrl)
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    subscription = commet.subscriptions.create(
        customer_id='user_123',
        plan_code='pro',
        billing_interval='one_time',
    )

    if not subscription.checkout_url:
        raise RuntimeError('Commet did not return a checkout URL')

    redirect(subscription.checkout_url)
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    planCode := "pro"
    billingInterval := "one_time"
    subscription, err := client.Subscriptions.Create(ctx, &commet.CreateSubscriptionParams{
        CustomerID:      "user_123",
        PlanCode:        &planCode,
        BillingInterval: &billingInterval,
    })
    if err != nil {
        log.Fatal(err)
    }
    if subscription.CheckoutURL == nil {
        log.Fatal("Commet did not return a checkout URL")
    }
    http.Redirect(w, r, *subscription.CheckoutURL, http.StatusSeeOther)
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    CreateSubscriptionParams params = CreateSubscriptionParams.builder()
        .customerId("user_123")
        .planCode("pro")
        .billingInterval("one_time")
        .build();
    var subscription = commet.subscriptions().create(params);
    if (subscription.checkoutUrl() == null) {
        throw new IllegalStateException("Commet did not return a checkout URL");
    }
    redirect(subscription.checkoutUrl());
    ```
  </Tab>

  <Tab title="PHP">
    ```php theme={null}
    $result = $commet->subscriptions->create(
        customerId: 'user_123',
        planCode: 'pro',
        billingInterval: 'one_time',
    );

    if ($result->checkoutUrl === null) {
        throw new RuntimeException('Commet did not return a checkout URL');
    }
    redirect($result->checkoutUrl);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST https://commet.co/api/v1/subscriptions \
      -H "x-api-key: $COMMET_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "customerId": "user_123",
        "planCode": "pro",
        "billingInterval": "one_time"
      }'
    ```
  </Tab>
</Tabs>

El `billingInterval` debe ser `one_time` y el plan tiene que tener un precio único configurado. Si el precio default del plan ya es único, puedes omitir el parámetro `billingInterval`.

## Recibos

El recibo inicial incluye el precio del plan base como un cargo único. Después, los ciclos de cobro siguientes solo generan recibos por overage — el plan base nunca se vuelve a cobrar.

| Recibo | Qué incluye |
| - | - |
| **Inicial** | `plan_base` (una vez) + descuento de intro offer si aplica |
| **Ciclos siguientes** | `feature_overage`, `feature_seats`, `addon_base` — solo si hay cargos |

Si no hay overage ni cargos adicionales en un ciclo de cobro, no se genera ningún recibo.

## Portal del cliente

En el [Portal del cliente](/docs/es/customer-portal), las suscripciones de pago único muestran el intervalo como **Lifetime**. El botón de cancelar queda oculto porque la cancelación no está permitida. Los clientes igual pueden cambiar de plan si el plan pertenece a un [Plan Group](/docs/es/plan-groups).

## Relacionado

* [Gestionar planes](/docs/es/create-plans) — Crear y configurar planes
* [Gestionar suscripciones](/docs/es/manage-subscriptions) — Ciclo de vida completo de la suscripción
* [Recibos y ciclos de cobro](/docs/es/invoices-and-billing-cycles) — Cómo funcionan los cobros
* [Modelos de consumo](/docs/es/consumption-models) — Metered, Credits y Balance explicados


## Related topics

- [Aceptar pagos únicos](/docs/es/accept-one-time-payments.md)
- [Quickstart](/docs/es/choose-a-billing-model.md)
- [Recibos y ciclos de cobro](/docs/es/invoices-and-billing-cycles.md)
- [CLI](/docs/es/cli.md)
- [Administrar suscripciones](/docs/es/manage-subscriptions.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.