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

# Suscripciones

> Cobros recurrentes que generan una serie de deudas automáticamente.

Una **suscripción** (`Subscription`) es un cobro recurrente que genera automáticamente una serie de [deudas](/es/recursos/deudas), una por ciclo. Tú defines **qué** cobrar (monto, frecuencia, deudor y duración) y TapiPay genera las cuotas y resuelve toda la complejidad interna por ti.

**Cuándo usarla:** cobros que se repiten en el tiempo (mensualidades, cuotas de crédito, planes periódicos). Para un cargo único usa una [deuda](/es/recursos/deudas); para cobrar sin deudor conocido, una [liga de pago](/es/recursos/ligas-de-pago).

## Generación de cuotas por adelantado

Al crear la suscripción, TapiPay calcula las fechas de todos los ciclos y **genera las deudas por adelantado** (no hay un proceso que cree una cuota por mes). La generación de esas deudas ocurre de forma **asíncrona**: la suscripción se devuelve en estado `ACTIVE` apenas el cálculo y el encolado terminan correctamente.

<Note>
  Si la generación de las deudas falla, la suscripción se revierte automáticamente para que puedas reintentar con el mismo `externalSubscriptionId` sin duplicar cobros.
</Note>

## Crear una suscripción

```bash theme={null}
curl --request POST \
  --url 'https://tapipay-facade.dev.tapila.cloud/subscriptions' \
  --header 'x-api-key: TU_API_KEY' \
  --header 'x-authorization-token: TU_TOKEN_TAPI' \
  --header 'Content-Type: application/json' \
  --data '{
    "externalSubscriptionId": "SUB-2026-007",
    "externalClientId": "CLI-00042",
    "amount": 999.00,
    "currency": "MXN",
    "intervalUnit": "month",
    "intervalCount": 1,
    "startDate": "2026-06-15",
    "totalCycles": 12
  }'
```

### Campos principales

<ResponseField name="externalSubscriptionId" type="string" required>
  Llave natural de la suscripción. Única por organización. Si la repites, la API responde `409 RESOURCE_CONFLICT`.
</ResponseField>

<ResponseField name="externalClientId / contactData" type="string | object" required>
  El deudor. Envía uno de los dos (no ambos), igual que en una [deuda](/es/recursos/deudas#identificar-al-deudor). En v1 cada suscripción tiene exactamente un deudor.
</ResponseField>

<ResponseField name="amount" type="number" required>
  Monto por ciclo en **pesos**, con hasta 2 decimales (mínimo `0.01`).
</ResponseField>

<ResponseField name="intervalUnit" type="string" required>
  Unidad del intervalo: `day`, `week`, `month` o `year`.
</ResponseField>

<ResponseField name="intervalCount" type="integer" required>
  Cantidad de unidades por ciclo. Por ejemplo, `intervalUnit: "month"` + `intervalCount: 3` es trimestral.
</ResponseField>

<ResponseField name="startDate" type="string" required>
  Fecha de inicio en formato `YYYY-MM-DD`.
</ResponseField>

<ResponseField name="totalCycles" type="integer">
  Cantidad de ciclos a generar (máximo 520). **Excluyente** con `endDate`.
</ResponseField>

<ResponseField name="endDate" type="string">
  Fecha de fin (`YYYY-MM-DD`), posterior a `startDate`. **Excluyente** con `totalCycles`.
</ResponseField>

<ResponseField name="billingDay" type="object">
  Override del día de cobro: `{ day, month? }`. Solo aplica a intervalos `month` o `year`. Ver más abajo.
</ResponseField>

<ResponseField name="enforcePaymentOrder" type="boolean" default="false">
  Si es `true`, el deudor debe pagar las cuotas en orden cronológico.
</ResponseField>

También acepta `description`, `productName`, `allowOverduePayment`, `allowPartialPayments`, `autopay` y `paymentMethods` con el mismo comportamiento que una [deuda](/es/recursos/deudas). Ver [Medios de pago](/es/conceptos/medios-de-pago).

### Frecuencias con `intervalUnit` + `intervalCount`

| Frecuencia   | `intervalUnit` | `intervalCount` |
| ------------ | -------------- | --------------- |
| Semanal      | `week`         | `1`             |
| Quincenal    | `week`         | `2`             |
| Mensual      | `month`        | `1`             |
| Trimestral   | `month`        | `3`             |
| Cada 45 días | `day`          | `45`            |
| Anual        | `year`         | `1`             |

### Día de cobro (`billingDay`)

Por defecto, el día de cobro se infiere del `startDate` (modelo *aniversario*): si la suscripción inicia el día 15, todos los cobros caen el 15. El override `billingDay` desacopla el día de cobro del `startDate`.

<Warning>
  `billingDay` solo es válido para intervalos `month` o `year`. El subcampo `month` solo aplica a intervalos `year`.
</Warning>

**Fin de mes:** si el día configurado supera el último día del mes (por ejemplo, `31` en febrero), el cobro se realiza el **último día del mes**; el mes siguiente vuelve al día original.

```text billingDay = { day: 31 }, mensual, startDate 2026-01-31 theme={null}
Ciclo 1: 2026-01-31   (enero tiene 31)
Ciclo 2: 2026-02-28   (febrero tiene 28 en 2026)
Ciclo 3: 2026-03-31   (vuelve al día original)
Ciclo 4: 2026-04-30   (abril tiene 30)
```

### Duración indefinida

Si no envías `totalCycles` ni `endDate`, la suscripción queda `ACTIVE` y se genera **solo la deuda del primer ciclo** (para no generar cobros sin límite). Define `totalCycles` o `endDate` cuando quieras generar todas las cuotas por adelantado.

## La respuesta

Los datos de programación viajan **anidados** en el objeto `scheduling`.

```json theme={null}
{
  "data": {
    "subscriptionId": "sub_4pQ2nW8s",
    "externalSubscriptionId": "SUB-2026-007",
    "status": "ACTIVE",
    "scheduling": {
      "intervalUnit": "month",
      "intervalCount": 1,
      "startDate": "2026-06-15",
      "totalCycles": 12,
      "endDate": null,
      "billingDay": { "day": 15 }
    },
    "externalClientId": "CLI-00042",
    "amount": 999.00,
    "currency": "MXN",
    "paymentUrl": "https://app.tapipay.la/s/acme-corp/portal/CLI-00042/",
    "enforcePaymentOrder": false,
    "autopay": false,
    "allowOverduePayment": true,
    "createdAt": "2026-06-03T18:15:00Z",
    "updatedAt": "2026-06-03T18:15:00Z"
  },
  "requestId": "req_a1b2c3d4"
}
```

## Ciclo de vida

```mermaid theme={null}
stateDiagram-v2
    [*] --> PROCESSING
    PROCESSING --> ACTIVE: deudas generadas
    PROCESSING --> CANCELLED
    ACTIVE --> PAUSED: pausar
    PAUSED --> ACTIVE: reanudar
    ACTIVE --> CANCELLED: cancelar
    PAUSED --> CANCELLED: cancelar
    CANCELLED --> [*]
```

| Estado       | Significado                                                                |
| ------------ | -------------------------------------------------------------------------- |
| `PROCESSING` | Estado transitorio mientras se generan las deudas al crear la suscripción. |
| `ACTIVE`     | Activa. Las deudas de los ciclos ya fueron generadas.                      |
| `PAUSED`     | Pausada manualmente. Puede reanudarse.                                     |
| `CANCELLED`  | Cancelada manualmente. Estado final.                                       |

<Note>
  Cada deuda generada por la suscripción tiene su **propio** ciclo de vida (`PENDING`, `PAID`, etc.). Cancelar la suscripción no cancela automáticamente las deudas ya generadas. Ver [Deudas](/es/recursos/deudas#ciclo-de-vida).
</Note>

### Pago en orden (`enforcePaymentOrder`)

Con `enforcePaymentOrder: true`, el deudor no puede pagar una cuota si hay cuotas anteriores impagas. Intentarlo devuelve `422 BUSINESS_RULE_VIOLATION`. Debe saldarlas en orden cronológico.

## Endpoints

| Método  | Ruta                         | Descripción                                                                                                                                         |
| ------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST`  | `/subscriptions`             | Crear una suscripción.                                                                                                                              |
| `GET`   | `/subscriptions/{id}`        | Consultar una suscripción.                                                                                                                          |
| `GET`   | `/subscriptions`             | Listar suscripciones.                                                                                                                               |
| `PATCH` | `/subscriptions/{id}`        | Actualizar campos editables (`amount`, `description`, `enforcePaymentOrder`, `allowOverduePayment`, `autopay`, `paymentMethods`, `additionalData`). |
| `POST`  | `/subscriptions/{id}/pause`  | Pausar.                                                                                                                                             |
| `POST`  | `/subscriptions/{id}/resume` | Reanudar.                                                                                                                                           |
| `POST`  | `/subscriptions/{id}/cancel` | Cancelar.                                                                                                                                           |
| `GET`   | `/subscriptions/{id}/debts`  | Listar las deudas generadas.                                                                                                                        |

<Card title="Pruébalo en el API Reference" icon="play" href="/api-reference">
  Explora cada endpoint con su playground interactivo.
</Card>
