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

# Recover Subscriptions

> Collect payment for failed subscription renewals and reactivate past-due or cancelled subscriptions.

When a subscription renewal fails, PayNext moves it to `past_due` status. Use this guide to let customers update their payment method and reactivate their subscription.

## Decision Flowchart

<div className="block dark:hidden">
  ```mermaid theme={"system"}
  flowchart LR
      A([Reactivate<br/>subscription]) --> B{Subscription<br/>status?}
      
      subgraph sdk ["SDK Checkout"]
          C([Collect payment])
          D([Collect payment])
      end
      
      subgraph api ["API Only"]
          E([Reactivate directly])
          F([Reactivate directly])
      end
      
      B -->|past_due| C
      B -->|cancelled| D
      B -->|cancelled| E
      B -->|scheduled_for_cancellation| F
      
      C --> G(["customer.id<br/>+ subscription.id"])
      D --> G
      E --> H(["PATCH /subscriptions"])
      F --> H

      style A fill:#f1f5f9,stroke:#64748b,color:#334155
      style B fill:#fef3c7,stroke:#d97706,color:#92400e
      style C fill:#dbeafe,stroke:#60a5fa,color:#1e40af
      style D fill:#dbeafe,stroke:#60a5fa,color:#1e40af
      style E fill:#f3e8ff,stroke:#c084fc,color:#7c3aed
      style F fill:#f3e8ff,stroke:#c084fc,color:#7c3aed
      style G fill:#f1f5f9,stroke:#94a3b8,color:#334155
      style H fill:#f1f5f9,stroke:#94a3b8,color:#334155
      style sdk fill:#eff6ff,stroke:#bfdbfe,color:#1f2937
      style api fill:#faf5ff,stroke:#e9d5ff,color:#1f2937
  ```
</div>

<div className="hidden dark:block">
  ```mermaid theme={"system"}
  flowchart LR
      A([Reactivate<br/>subscription]) --> B{Subscription<br/>status?}
      
      subgraph sdk ["SDK Checkout"]
          C([Collect payment])
          D([Collect payment])
      end
      
      subgraph api ["API Only"]
          E([Reactivate directly])
          F([Reactivate directly])
      end
      
      B -->|past_due| C
      B -->|cancelled| D
      B -->|cancelled| E
      B -->|scheduled_for_cancellation| F
      
      C --> G(["customer.id<br/>+ subscription.id"])
      D --> G
      E --> H(["PATCH /subscriptions"])
      F --> H

      style A fill:#1e293b,stroke:#475569,color:#cbd5e1
      style B fill:#78350f,stroke:#d97706,color:#fef3c7
      style C fill:#1e3a5f,stroke:#60a5fa,color:#bfdbfe
      style D fill:#1e3a5f,stroke:#60a5fa,color:#bfdbfe
      style E fill:#3b1d5c,stroke:#c084fc,color:#e9d5ff
      style F fill:#3b1d5c,stroke:#c084fc,color:#e9d5ff
      style G fill:#1e293b,stroke:#475569,color:#cbd5e1
      style H fill:#1e293b,stroke:#475569,color:#cbd5e1
      style sdk fill:#172554,stroke:#1e3a8a,color:#e5e7eb
      style api fill:#2e1065,stroke:#4c1d95,color:#e5e7eb
  ```
</div>

| Status                       | What Happened             | Recovery Options                                                               |
| ---------------------------- | ------------------------- | ------------------------------------------------------------------------------ |
| `past_due`                   | Renewal payment failed    | [SDK checkout](#recover-past-due) (must collect payment)                       |
| `cancelled`                  | Subscription ended        | [SDK checkout](#recover-past-due) or [API](#reactivate-cancelled-subscription) |
| `scheduled_for_cancellation` | Customer requested cancel | [API only](/guides/platform/subscriptions#reactivate) (no payment needed)      |

## Recover Past-Due

For `past_due` subscriptions, you must collect payment via SDK checkout—there's no API-only option.

<Steps>
  <Step title="Create a client session">
    Include customer and subscription—do **not** include `plan.id`:

    ```bash cURL theme={"system"}
    curl -X POST https://api.paynext.com/client-session \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "X-API-Version: 2.0.0" \
      -H "Content-Type: application/json" \
      -d '{
        "customer": { "id": "cus_11dfa45f-23b1-40f4-9e9b-c9d485915528" },
        "subscription": { "id": "sub_11dfa45f-23b1-40f4-9e9b-c9d485915528" },
        "options": { "payment_methods_mode": "saved_or_new" }
      }'
    ```

    <Warning>
      Do **not** include `plan.id` for recovery—PayNext uses the existing plan from the subscription.
    </Warning>
  </Step>

  <Step title="Mount the SDK">
    Display checkout with the customer's saved payment method:

    ```javascript theme={"system"}
    const checkout = new PayNextCheckout()

    checkout.mount('checkout-container', {
      clientToken: session.id,
      environment: 'sandbox',
      onCheckoutComplete: (result) => {
        // Subscription is now active again
        console.log('Subscription recovered:', result.payment_id)
      },
      onCheckoutFail: (error) => {
        // Customer can try a different card
      }
    })
    ```
  </Step>
</Steps>

**Outcomes:**

* **Success**: Subscription returns to `active`, billing cycle resets
* **Failure**: Customer can switch to a different card and retry instantly

## Reactivate Cancelled Subscription

For `cancelled` subscriptions, you can either collect payment via SDK checkout (above) or reactivate directly via API:

```bash cURL theme={"system"}
curl -X PATCH https://api.paynext.com/subscriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "X-API-Version: 2.0.0" \
  -H "Content-Type: application/json" \
  -d '{
    "subscription": {
      "id": "sub_887934f2-de1a-4b28-a288-ba8f70c71bd3",
      "status": "active"
    }
  }'
```

The outcome depends on whether the paid period (`current_period_end`) is still active:

* **Paid period still active** (`current_period_end` in the future) — the subscription returns to `active` with **no charge**, restoring access for the remaining paid period.
* **Paid period has ended** (`current_period_end` in the past or unset) — PayNext attempts an immediate charge on the customer's saved payment method:
  * **Charge succeeds** → `active` with a new billing period.
  * **Charge fails** → `past_due`; the subscription enters the standard retry flow and access is **not** restored.

PayNext emits a single `subscription_v2` event reflecting the resulting status (`subscription_v2.activated` on reactivation, or `subscription_v2.past_due` if the reactivation charge fails).

<Note>
  API reactivation works for `scheduled_for_cancellation` and `cancelled` subscriptions. A `past_due` subscription cannot be reactivated this way—collect payment via SDK checkout instead.
</Note>

## Automatic Recovery From Card Updates

Some past-due subscriptions recover without any action from you or the customer. When a saved card is reissued or its network token becomes usable again, PayNext charges the subscription right away instead of waiting for the next scheduled retry. A success moves the subscription back to `active` and emits `subscription_v2.renewed`.

Two rules keep this from producing a burst of attempts, and they explain why you won't always see an immediate charge:

* After a failed update-triggered attempt, PayNext waits 24 hours before trying again from another update.
* If a scheduled retry is already due shortly, PayNext lets that one run instead.

The regular retry ladder continues underneath, so nothing is lost if an update-triggered attempt is skipped.

A payment declined for insufficient funds recovers the same way, on a different trigger: the card network signals when the funds are likely there, and the attempt runs then instead of on schedule. See [Funds-Available Retries](/guides/advanced/funds-available-retries).

## Dead Payment Methods

A payment method can reach a state where no charge can succeed: the card is expired, closed, or invalid **and** it has no usable network token, or the customer revoked the mandate in Cash App, Pix, PayPal, or Venmo.

When that happens, PayNext stops attempting charges rather than sending a run of guaranteed declines. Any attempt that is aborted this way is recorded as `INCOMPLETE` with `decline_code` [`payment_method_disabled`](/guides/payments/decline-codes) and `advice_code` `do_not_try_again`.

The subscription stays `past_due` and waits for a recovery—it is **not** cancelled at that moment. If nothing recovers it within the grace period, PayNext cancels it with `cancellation_details.reason` set to `dead_instrument`.

| Payment method                      | Grace period |
| :---------------------------------- | :----------- |
| Cards                               | 30 days      |
| Cash App, Pix, PayPal Wallet, Venmo | 14 days      |

<Tip>
  This is the window to reach the customer. A `subscription_v2.past_due` event with a `payment_method_disabled` decline means retries will not help—prompt the customer for a new payment method rather than waiting for the ladder.
</Tip>

## Best Practices

1. **Notify customers promptly** when renewals fail—the sooner they update their card, the higher the recovery rate
2. **Use email or in-app messaging** to direct customers to your recovery page
3. **Show the amount due** clearly in your UI before they reach checkout
