> ## 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.

# Charge Saved Payment Methods

> Client session payloads for one-time charges, plan changes, and recovery flows.

Quick reference for SDK client session parameters when charging returning customers. The SDK behavior is identical for all scenarios—only the client session payload differs.

<Note>
  For business context and when to use each approach, see [Charge Returning Customers](/guides/use-cases/charge-returning-customers).
</Note>

## Use Cases

| Flow                                  | Parameters                                    | Result                                  |
| ------------------------------------- | --------------------------------------------- | --------------------------------------- |
| [One-time payment](#one-time-payment) | `customer.id` + `plan.id`                     | Payment created, no subscription        |
| [Change plan](#change-plan)           | `customer.id` + `plan.id` + `subscription.id` | Subscription updated, payment collected |
| [Recover past due](#recover-past-due) | `customer.id` + `subscription.id`             | Subscription reactivated                |

## One-Time Payment

Charge an existing customer for a one-time purchase (add-on, credits, standalone item).

### Create Client Session

<CodeGroup>
  ```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" },
      "plan": { "id": "plan_7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d" },
      "payment": { "metadata": { "order_id": "order_12345" } },
      "options": { "payment_methods_mode": "saved_or_new" }
    }'
  ```

  ```typescript Node.js theme={"system"}
  const response = await fetch('https://api.paynext.com/client-session', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.PAYNEXT_API_KEY}`,
      'X-API-Version': '2.0.0',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      customer: { id: 'cus_11dfa45f-23b1-40f4-9e9b-c9d485915528' },
      plan: { id: 'plan_7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d' }, // Must be type: 'one_off'
      payment: { metadata: { order_id: 'order_12345' } },
      options: { payment_methods_mode: 'saved_or_new' },
    }),
  })

  const session = await response.json()
  // Use session.id as clientToken
  ```
</CodeGroup>

<Note>
  The plan must have `type: one_off`. Do not include `subscription` for one-time payments.
</Note>

## Change Plan

Upgrade or downgrade a subscription with immediate payment.

### Create Client Session

<CodeGroup>
  ```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" },
      "plan": { "id": "plan_8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e" },
      "subscription": {
        "id": "sub_11dfa45f-23b1-40f4-9e9b-c9d485915528",
        "proration_billing_mode": "prorated_immediately"
      },
      "options": { "payment_methods_mode": "saved_or_new" }
    }'
  ```

  ```typescript Node.js theme={"system"}
  const response = await fetch('https://api.paynext.com/client-session', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.PAYNEXT_API_KEY}`,
      'X-API-Version': '2.0.0',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      customer: { id: 'cus_11dfa45f-23b1-40f4-9e9b-c9d485915528' },
      plan: { id: 'plan_8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e' },
      subscription: {
        id: 'sub_11dfa45f-23b1-40f4-9e9b-c9d485915528',
        proration_billing_mode: 'prorated_immediately',
      },
      options: { payment_methods_mode: 'saved_or_new' },
    }),
  })

  const session = await response.json()
  ```
</CodeGroup>

### Proration Modes

| Mode                   | Behavior                                                       |
| ---------------------- | -------------------------------------------------------------- |
| `prorated_immediately` | Charge difference based on remaining time, reset billing cycle |
| `full_immediately`     | Charge full new plan price, reset billing cycle                |

→ [Change Subscription Plan](/guides/use-cases/change-subscription-plan) for proration calculations and examples

## Recover Past Due

Collect payment for failed renewals to reactivate a subscription.

### Create Client Session

<CodeGroup>
  ```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" }
    }'
  ```

  ```typescript Node.js theme={"system"}
  const response = await fetch('https://api.paynext.com/client-session', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.PAYNEXT_API_KEY}`,
      'X-API-Version': '2.0.0',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      customer: { id: 'cus_11dfa45f-23b1-40f4-9e9b-c9d485915528' },
      subscription: { id: 'sub_11dfa45f-23b1-40f4-9e9b-c9d485915528' },
      options: { payment_methods_mode: 'saved_or_new' },
    }),
  })

  const session = await response.json()
  ```
</CodeGroup>

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

→ [Recover Subscriptions](/guides/use-cases/recover-subscriptions) for status handling and workflows

## Mount the SDK

Once you have the session `id`, mount the checkout:

```tsx theme={"system"}
'use client'

import { useEffect } from 'react'
import { PayNextCheckout } from '@paynext/sdk'
import '@paynext/sdk/styles'

export const SavedMethodCheckout = ({ sessionId }: { sessionId: string }) => {
  useEffect(() => {
    const checkout = new PayNextCheckout()

    checkout.mount('paynext-checkout', {
      clientToken: sessionId,
      environment: 'sandbox',
      onCheckoutComplete: (result) => {
        console.log('Payment successful:', result.payment_id)
        // Handle success
      },
      onCheckoutFail: (error) => {
        console.error('Payment failed:', error.status_reason?.decline_code)
        // Customer can switch cards and retry in the SDK
      },
    })

    return () => checkout.unmount()
  }, [sessionId])

  return <div id="paynext-checkout" />
}
```

**Behavior:**

* SDK displays the customer's saved payment method
* Customer can switch to a new card if needed
* On failure, customer retries instantly—no new session required

→ [SDK Getting Started](/sdk-reference/introduction/getting-started) for full configuration options

## Payment Method Modes

| Mode                     | Behavior                                    |
| ------------------------ | ------------------------------------------- |
| `saved_or_new` (default) | Show saved card, allow switching to new     |
| `new_only`               | Collect new card only, ignore saved methods |

## Outcomes

| Result      | One-Time                       | Change Plan                               | Recovery                         |
| ----------- | ------------------------------ | ----------------------------------------- | -------------------------------- |
| **Success** | Payment created                | Subscription updated, billing cycle reset | Subscription returns to `active` |
| **Failure** | Customer retries with new card | Subscription stays on old plan            | Customer retries with new card   |
