# How to update a payment method via Stripe API

- Tool: Stripe
- Difficulty: Beginner
- Time required: 15 minutes
- Compatibility: Stripe API v2024-12+, Node.js 18+, any backend framework
- Last updated: March 2026

## TL;DR

Update a payment method in Stripe by calling stripe.paymentMethods.update() to change billing details, or attach a new payment method and set it as the customer's default with stripe.customers.update({ invoice_settings }). You cannot change the card number on an existing method — attach a new one and detach the old one instead.

## Managing Payment Methods via the Stripe API

Customers frequently need to update their card — whether it expired, was lost, or they simply want to use a different one. The Stripe API lets you update billing details (name, address) on an existing PaymentMethod, but you cannot change the card number itself. To replace a card, you attach a new PaymentMethod, set it as the default, and optionally detach the old one. This flow is essential for subscription businesses where failed charges due to expired cards cause involuntary churn.

## Before you start

- A Stripe account with at least one customer and attached payment method
- Node.js 18 or newer installed
- The stripe npm package installed (npm install stripe)
- Your Stripe secret key (sk_test_...) from Dashboard → Developers → API keys

## Step-by-step guide

### 1. Update billing details on a payment method

Use stripe.paymentMethods.update() to change the billing name, address, email, or phone on an existing payment method. This does not change the card number or expiration.

```
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const updated = await stripe.paymentMethods.update('pm_ABC123', {
  billing_details: {
    name: 'Jane Smith',
    email: 'jane.smith@example.com',
    address: {
      line1: '123 Main St',
      city: 'San Francisco',
      state: 'CA',
      postal_code: '94105',
      country: 'US',
    },
  },
});

console.log('Updated:', updated.id);
```

**Expected result:** The payment method's billing details are updated. The card number and expiration remain unchanged.

### 2. Attach a new payment method to a customer

When the customer provides a new card (collected via Stripe Elements on the frontend as a pm_ token), attach it to their customer record.

```
await stripe.paymentMethods.attach('pm_NEW456', {
  customer: 'cus_ABC123',
});
```

**Expected result:** The new payment method is attached to the customer and appears in their payment methods list.

### 3. Set the new method as default

Update the customer's invoice_settings to use the new payment method as the default. This ensures future invoices and subscription renewals charge the new card.

```
await stripe.customers.update('cus_ABC123', {
  invoice_settings: {
    default_payment_method: 'pm_NEW456',
  },
});
```

**Expected result:** The customer's default payment method is now the newly attached card.

### 4. Detach the old payment method

Optionally remove the old payment method to keep the customer's account clean. This prevents confusion about which card is active.

```
await stripe.paymentMethods.detach('pm_OLD789');
```

**Expected result:** The old payment method is detached from the customer and can no longer be used for charges.

## Complete code example

File: `update-payment-method.js`

```javascript
const express = require('express');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const app = express();
app.use(express.json());

// Replace the default payment method for a customer
app.post('/api/customers/:customerId/payment-method', async (req, res) => {
  try {
    const { customerId } = req.params;
    const { paymentMethodId } = req.body;

    if (!paymentMethodId) {
      return res.status(400).json({ error: 'paymentMethodId is required' });
    }

    // Get current default payment method
    const customer = await stripe.customers.retrieve(customerId);
    const oldDefault = customer.invoice_settings?.default_payment_method;

    // Attach new payment method
    await stripe.paymentMethods.attach(paymentMethodId, {
      customer: customerId,
    });

    // Set as default
    await stripe.customers.update(customerId, {
      invoice_settings: {
        default_payment_method: paymentMethodId,
      },
    });

    // Detach old payment method if it exists
    if (oldDefault && oldDefault !== paymentMethodId) {
      await stripe.paymentMethods.detach(oldDefault);
    }

    res.json({
      message: 'Payment method updated',
      newDefault: paymentMethodId,
      oldDetached: oldDefault || null,
    });
  } catch (err) {
    console.error('Payment method update error:', err.message);
    res.status(500).json({ error: err.message });
  }
});

// Update billing details on existing payment method
app.patch('/api/payment-methods/:pmId', async (req, res) => {
  try {
    const { billing_details } = req.body;
    const updated = await stripe.paymentMethods.update(req.params.pmId, {
      billing_details,
    });
    res.json({ id: updated.id, billing_details: updated.billing_details });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server on port ${PORT}`));
```

## Common mistakes

- **Trying to update the card number on an existing payment method** — undefined Fix: Card numbers cannot be changed. Attach a new payment method with the new card and detach the old one.
- **Attaching a payment method without setting it as default** — undefined Fix: After attaching, update the customer's invoice_settings.default_payment_method. Otherwise, subscriptions and invoices still charge the old card.
- **Detaching the only payment method on a customer with active subscriptions** — undefined Fix: Always attach and set the new default before detaching the old method. Detaching the only method causes subscription payments to fail.
- **Not handling the payment method already attached error** — undefined Fix: If a payment method is already attached to a customer, Stripe throws an error. Check if it is already attached before calling attach.

## Best practices

- Always set the new payment method as default before detaching the old one
- Collect new card details on the frontend using Stripe Elements to get a pm_ token securely
- Use test payment method tokens (pm_card_visa, pm_card_mastercard) during development
- Send a confirmation email when a customer updates their payment method
- Set up webhook listeners for payment_method.attached and payment_method.detached events
- Handle the case where the new payment method requires 3D Secure authentication
- Log payment method changes for audit and compliance purposes

## Frequently asked questions

### Can I update the expiration date on an existing payment method?

No. Like the card number, the expiration date cannot be modified on an existing PaymentMethod. Stripe automatically updates expiration dates through card network account updater services for many cards.

### What is Stripe's automatic card updater?

Stripe works with card networks (Visa, Mastercard) to automatically update card details when a bank issues a replacement card. This happens in the background and reduces failed payments from expired cards.

### How do I list all payment methods for a customer?

Use stripe.paymentMethods.list({ customer: 'cus_ABC', type: 'card' }) to get all card payment methods attached to a customer.

### What happens to pending charges if I detach a payment method?

Pending charges already authorized will still complete. Only future charges are affected. The detached method cannot be used for new payments.

### Can I reattach a detached payment method?

No. Once a PaymentMethod is detached, it cannot be reattached. The customer must provide their card details again to create a new PaymentMethod.

### What if I need help building a self-service billing portal?

For a complete billing portal where customers manage their own payment methods, invoices, and subscriptions, the RapidDev team can help you implement Stripe's Customer Portal or build a custom solution.

---

Source: https://www.rapidevelopers.com/stripe-guide/how-to-update-a-payment-method-via-stripe-api
© RapidDev — https://www.rapidevelopers.com/stripe-guide/how-to-update-a-payment-method-via-stripe-api
