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

# Subscriptions

> Learn how a subscription starts, how customers pay each invoice, and what happens when a payment fails.

A subscription connects a customer to a [plan](/platform/pricing/plans). While a subscription is active, Paygentic issues an invoice every billing period, collects payment, and keeps the customer's entitlements up to date.

To create a subscription, see [Customer Lifecycle](/platform/billing/customer-lifecycle#creating-subscriptions).

<Info>
  To collect payments, connect a payment provider (Stripe or Airwallex) in the dashboard under **Set Up Payments**. Without a payment provider, Paygentic still issues invoices, but customers can't pay them online and don't receive invoice emails.
</Info>

## Subscription lifecycle

1. You create a subscription for a customer.
2. If the plan charges anything in advance, Paygentic issues the first invoice, called Invoice 0. The subscription becomes active when the customer pays it.
3. Each billing period, Paygentic issues an invoice. The customer pays it on the invoice payment page, or Paygentic charges their saved payment method automatically.
4. If an automatic charge fails, Paygentic retries it and emails the customer. The subscription stays active.
5. When you end the subscription, Paygentic issues a final invoice and cancels the customer's entitlements.

## Subscription statuses

| Status | Description |
| - | - |
| `pending_payment` | The subscription is waiting for the customer to pay Invoice 0. |
| `active` | The subscription is in good standing and bills the customer each period. It stays `active` even if a renewal payment fails. |
| `terminated` | The subscription has ended and no longer bills the customer. This status is final. |

## The first invoice

If the plan has charges billed in advance, such as a setup fee or the first month's fee, Paygentic issues Invoice 0 when you create the subscription. The subscription stays `pending_payment` until Invoice 0 is paid.

To collect the payment, send the customer to `payment.checkoutUrl` from the subscription response. This link opens the invoice payment page. When the customer pays, the subscription becomes `active` and Paygentic sends the `subscription.activated.v0` webhook.

If the plan has nothing to charge in advance, Paygentic doesn't issue Invoice 0 and the subscription is `active` immediately.

The invoice payment page expires after `sessionExpiryMinutes`, which is 240 minutes by default. If the customer doesn't pay in time, Paygentic cancels Invoice 0 and ends the subscription. To try again, create a new subscription.

## How invoices are paid

The subscription's `autoCharge` setting controls how the customer pays each invoice.

| `autoCharge` | How the customer pays |
| - | - |
| `false` (default) | Paygentic emails the customer a link to the invoice payment page, and the customer pays there. |
| `true` | Paygentic charges the customer's saved payment method when the invoice is issued, then emails a payment confirmation. |

You can set `autoCharge` when you create a subscription, or update it later:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH "https://api.paygentic.io/v0/subscriptions/sub_z9a0b1c2d3e4f5g6" \
    -H "Authorization: Bearer sk_test_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "autoCharge": true }'
  ```

  ```javascript JavaScript theme={null}
  await fetch('https://api.paygentic.io/v0/subscriptions/sub_z9a0b1c2d3e4f5g6', {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer sk_test_YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ autoCharge: true }),
  });
  ```

  ```python Python theme={null}
  import requests

  requests.patch(
      "https://api.paygentic.io/v0/subscriptions/sub_z9a0b1c2d3e4f5g6",
      headers={"Authorization": "Bearer sk_test_YOUR_API_KEY"},
      json={"autoCharge": True},
  )
  ```
</CodeGroup>

For automatic charges, the customer needs a saved payment method. The customer can save one when they pay Invoice 0, or add one later in the [customer portal](/platform/billing/customer-lifecycle#customer-portal). If a renewal is coming up and no payment method is saved, the [renewal reminder](/platform/billing/customer-emails#renewal-reminders) asks the customer to add one.

<Info>
  **API Reference**: See the [Update Subscription endpoint](/api-reference/subscriptions/update) for all the fields you can change.
</Info>

## When an automatic charge fails

When an automatic charge fails, the subscription stays `active`. The customer keeps access to the plan, and Paygentic continues to issue invoices each period. Paygentic retries the charge and emails the customer, and you decide whether to change or end the subscription.

This section applies to renewal invoices. If Invoice 0 isn't paid, the subscription ends. See [The first invoice](#the-first-invoice).

### Retry schedule

Paygentic retries a failed card charge up to three times after the first failure:

| When | What happens |
| - | - |
| First failure | The customer receives an email saying the payment failed and when Paygentic will retry. |
| 1 hour later | Paygentic retries the charge. |
| 24 hours later | Paygentic retries the charge. |
| 72 hours later | Paygentic retries the charge for the last time. If it fails, the invoice status changes to `PAYMENT_FAILED` and the customer receives a final email. |

Paygentic doesn't send an email for each retry. If a retry succeeds, the invoice status changes to `PAID` and the customer receives a payment confirmation. Both emails include a link to the invoice payment page, so the customer can pay at any time without waiting for the next retry.

Paygentic doesn't retry a charge in these cases:

* **The card can't be charged again.** For example, the card was reported lost or stolen. The invoice status changes to `PAYMENT_FAILED` and the customer receives the final email right away.
* **The customer has no saved payment method.** The customer receives the final email. The invoice stays `ISSUED`, and the customer can still pay it on the invoice payment page.

Both emails follow the customer's `invoiceIssued` setting. See [Customer emails](/platform/billing/customer-emails).

### Find failed payments

Paygentic doesn't send a webhook when a subscription charge fails. To find invoices that need your attention, list invoices with the `PAYMENT_FAILED` status. Add `subscriptionId` to check one subscription, or leave it out to check all of them. You can run this check on any schedule that suits your business, for example once a day.

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.paygentic.io/v2/invoices?subscriptionId=sub_z9a0b1c2d3e4f5g6&status=PAYMENT_FAILED" \
    -H "Authorization: Bearer sk_test_YOUR_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.paygentic.io/v2/invoices?subscriptionId=sub_z9a0b1c2d3e4f5g6&status=PAYMENT_FAILED',
    { headers: { 'Authorization': 'Bearer sk_test_YOUR_API_KEY' } }
  );

  const { data: failedInvoices } = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.paygentic.io/v2/invoices",
      params={"subscriptionId": "sub_z9a0b1c2d3e4f5g6", "status": "PAYMENT_FAILED"},
      headers={"Authorization": "Bearer sk_test_YOUR_API_KEY"},
  )

  failed_invoices = response.json()["data"]
  ```
</CodeGroup>

**Response (abbreviated):**

```json theme={null}
{
  "object": "list",
  "data": [
    {
      "id": "inv_a1b2c3d4e5f6g7h8",
      "status": "PAYMENT_FAILED",
      "subscriptionId": "sub_z9a0b1c2d3e4f5g6",
      "invoiceNumber": "INV-2026-000042",
      "periodStart": "2026-08-01T00:00:00Z",
      "periodEnd": "2026-08-31T23:59:59Z",
      "grandTotal": "49.99",
      "unpaidAmount": "49.99",
      "paymentUrl": "https://platform.paygentic.io/portal/pay/ps_k7m2n9p4q1r8s3t6"
    }
  ],
  "pagination": { "limit": 10, "offset": 0, "total": 1 }
}
```

Each invoice includes `paymentUrl`, a link to the invoice payment page. You can show this link in your app or send it to the customer. If the customer pays later, Paygentic sends the `invoice.paid.v0` webhook.

<Note>
  The `payment.failed.v0` webhook applies only to [Payment Links](/platform/payments/overview). Paygentic doesn't send it for subscription invoices.
</Note>

### Decide what happens to the subscription

Because the subscription stays `active`, you decide what happens after a failed payment. For example, you can limit access, move the customer to a smaller plan, or [end the subscription](#end-a-subscription).

We recommend acting when the invoice status changes to `PAYMENT_FAILED`. This is when Paygentic stops retrying and sends the final email, so your action matches what the customer has been told.

To help the customer pay, send them a [customer portal link](/platform/billing/customer-lifecycle#customer-portal) or the invoice's `paymentUrl`. From there, they can add a new payment method and pay the invoice.

## End a subscription

To end a subscription, call the termination endpoint with a reason. The subscription ends immediately, and you can't schedule it for a later date.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.paygentic.io/v0/subscriptions/sub_z9a0b1c2d3e4f5g6/termination" \
    -H "Authorization: Bearer sk_test_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "reason": "Payment failure" }'
  ```

  ```javascript JavaScript theme={null}
  await fetch('https://api.paygentic.io/v0/subscriptions/sub_z9a0b1c2d3e4f5g6/termination', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sk_test_YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ reason: 'Payment failure' }),
  });
  ```

  ```python Python theme={null}
  import requests

  requests.post(
      "https://api.paygentic.io/v0/subscriptions/sub_z9a0b1c2d3e4f5g6/termination",
      headers={"Authorization": "Bearer sk_test_YOUR_API_KEY"},
      json={"reason": "Payment failure"},
  )
  ```
</CodeGroup>

When a subscription ends, Paygentic:

1. Changes the status to `terminated`.
2. Issues a final invoice for the current billing period. If Invoice 0 is still unpaid, Paygentic cancels it instead.
3. Cancels the customer's entitlements and voids their grants, including purchased credits.
4. Cancels any upcoming renewal reminder.
5. Sends the `subscription.cancelled.v0` webhook.

If the subscription has already ended, the request has no effect.

<Info>
  **API Reference**: See the [Terminate Subscription endpoint](/api-reference/subscriptions/terminate).
</Info>

## Webhooks

| Event | When Paygentic sends it |
| - | - |
| `subscription.created.v0` | You create a subscription. Its status can still be `pending_payment`. |
| `subscription.activated.v0` | The subscription becomes `active`. |
| `subscription.cancelled.v0` | The subscription ends. |

For invoice events, see [Invoices](/platform/billing/invoices#track-invoices). For payloads, see [Webhooks](/platform/developers/webhooks).

## Next steps

* [Invoices](/platform/billing/invoices)
* [Customer emails](/platform/billing/customer-emails)
* [Customer Lifecycle](/platform/billing/customer-lifecycle)
* [Webhooks](/platform/developers/webhooks)
