> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.recurrente.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.recurrente.com/_mcp/server.

# Update Subscription Card

> Allow your subscribers to update their payment method via API

When a subscriber needs to change the card used for their subscription, the flow has two steps:

1. **Tokenize the new card** — Create a checkout in "setup" mode and send the link to the customer so they can enter their new card.
2. **Update the subscription** — When the customer completes the checkout, you receive the `payment_method_id` via webhook or by retrieving the checkout, and use it to update the subscription.

## Step 1: Create a tokenization checkout

Create a checkout with `mode: "setup"`. This checkout only tokenizes the card without charging anything.

```bash
curl -X POST https://app.recurrente.com/api/checkouts \
  -H "X-SECRET-KEY: your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "setup",
    "user_id": "us_SUBSCRIBER_ID",
    "success_url": "https://yoursite.com/card-updated",
    "cancel_url": "https://yoursite.com/cancelled"
  }'
```

**Response:**

```json
{
  "id": "ch_eegw9j5zgqoae3ms",
  "checkout_url": "https://app.recurrente.com/checkout-session/ch_eegw9j5zgqoae3ms"
}
```

Send the `checkout_url` to your customer (via email, WhatsApp, within your app, etc.) so they can enter their new card.

> **Note**
>
> Include the subscriber's `user_id` so the checkout pre-fills their information (name, email, etc.).

## Step 2: Receive the payment\_method\_id via webhook

When the customer completes the checkout, Recurrente sends a `setup_intent.succeeded` webhook to your configured endpoint. The saved method is inside `data.checkout.payment_method`:

```json
{
  "eventType": "setup_intent.succeeded",
  "data": {
    "event_type": "setup_intent.succeeded",
    "status": "succeeded",
    "checkout": {
      "id": "ch_eegw9j5zgqoae3ms",
      "status": "paid",
      "payment_method": {
        "id": "pay_m_new123",
        "type": "card",
        "card": {
          "last4": "5678",
          "network": "mastercard"
        }
      }
    }
  }
}
```

Save `data.checkout.payment_method.id` — you'll need it in the next step.

> **Note**
>
> If you don't have webhooks configured, you can also get the `payment_method_id` by doing a `GET /api/checkouts/{id}` on the checkout once it's been paid. The `payment_method.id` field will be in the response.

## Step 3: Update the subscription with the new card

Use the `payment_method_id` obtained to update the subscription:

```bash
curl -X PUT https://app.recurrente.com/api/subscriptions/su_SUBSCRIPTION_ID \
  -H "X-SECRET-KEY: your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{
    "payment_method_id": "pay_m_new123"
  }'
```

**Response:**

```json
{
  "id": "su_nehndm7j",
  "status": "active",
  "description": "Monthly Subscription",
  "default_payment_method": {
    "id": "pay_m_new123",
    "type": "card",
    "card": {
      "last4": "5678",
      "network": "mastercard"
    }
  }
}
```

From this point on, all future automatic charges for the subscription will use the new card.

> **Note**
>
> If the subscription has a pending payment (e.g., a failed charge), Recurrente will automatically attempt to charge it with the new card when you update it.

## Flow summary

```
Your backend                Recurrente                    Customer
    │                            │                           │
    │── POST /api/checkouts ────▶│                           │
    │◀── checkout_url ──────────│                           │
    │                            │                           │
    │── Send link to customer ──────────────────────────────▶│
    │                            │                           │
    │                            │◀── Enters new card ───────│
    │                            │                           │
    │◀── Webhook ───────────────│                           │
    │    setup_intent.succeeded  │                           │
    │    (payment_method_id)     │                           │
    │                            │                           │
    │── PUT /api/subscriptions ─▶│                           │
    │   (payment_method_id)      │                           │
    │◀── Subscription updated ──│                           │
```