Skip to main content
RapidDev - Software Development Agency
stripe-guide

How to update a payment method via Stripe API

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.

What you'll learn

  • How to update billing details on an existing payment method
  • How to attach a new payment method to a customer
  • How to set a new default payment method for invoices and subscriptions
  • How to detach an old payment method after replacement
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner5 min read15 minutesStripe API v2024-12+, Node.js 18+, any backend frameworkMarch 2026RapidDev Engineering Team
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.

Prerequisites

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

typescript
1const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
2
3const updated = await stripe.paymentMethods.update('pm_ABC123', {
4 billing_details: {
5 name: 'Jane Smith',
6 email: 'jane.smith@example.com',
7 address: {
8 line1: '123 Main St',
9 city: 'San Francisco',
10 state: 'CA',
11 postal_code: '94105',
12 country: 'US',
13 },
14 },
15});
16
17console.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.

typescript
1await stripe.paymentMethods.attach('pm_NEW456', {
2 customer: 'cus_ABC123',
3});

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.

typescript
1await stripe.customers.update('cus_ABC123', {
2 invoice_settings: {
3 default_payment_method: 'pm_NEW456',
4 },
5});

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.

typescript
1await 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 working example

update-payment-method.js
1const express = require('express');
2const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
3
4const app = express();
5app.use(express.json());
6
7// Replace the default payment method for a customer
8app.post('/api/customers/:customerId/payment-method', async (req, res) => {
9 try {
10 const { customerId } = req.params;
11 const { paymentMethodId } = req.body;
12
13 if (!paymentMethodId) {
14 return res.status(400).json({ error: 'paymentMethodId is required' });
15 }
16
17 // Get current default payment method
18 const customer = await stripe.customers.retrieve(customerId);
19 const oldDefault = customer.invoice_settings?.default_payment_method;
20
21 // Attach new payment method
22 await stripe.paymentMethods.attach(paymentMethodId, {
23 customer: customerId,
24 });
25
26 // Set as default
27 await stripe.customers.update(customerId, {
28 invoice_settings: {
29 default_payment_method: paymentMethodId,
30 },
31 });
32
33 // Detach old payment method if it exists
34 if (oldDefault && oldDefault !== paymentMethodId) {
35 await stripe.paymentMethods.detach(oldDefault);
36 }
37
38 res.json({
39 message: 'Payment method updated',
40 newDefault: paymentMethodId,
41 oldDetached: oldDefault || null,
42 });
43 } catch (err) {
44 console.error('Payment method update error:', err.message);
45 res.status(500).json({ error: err.message });
46 }
47});
48
49// Update billing details on existing payment method
50app.patch('/api/payment-methods/:pmId', async (req, res) => {
51 try {
52 const { billing_details } = req.body;
53 const updated = await stripe.paymentMethods.update(req.params.pmId, {
54 billing_details,
55 });
56 res.json({ id: updated.id, billing_details: updated.billing_details });
57 } catch (err) {
58 res.status(500).json({ error: err.message });
59 }
60});
61
62const PORT = process.env.PORT || 3000;
63app.listen(PORT, () => console.log(`Server on port ${PORT}`));

Common mistakes when updating a payment method via Stripe API

Why it's a problem: Trying to update the card number on an existing payment method

How to avoid: Card numbers cannot be changed. Attach a new payment method with the new card and detach the old one.

Why it's a problem: Attaching a payment method without setting it as default

How to avoid: After attaching, update the customer's invoice_settings.default_payment_method. Otherwise, subscriptions and invoices still charge the old card.

Why it's a problem: Detaching the only payment method on a customer with active subscriptions

How to avoid: Always attach and set the new default before detaching the old method. Detaching the only method causes subscription payments to fail.

Why it's a problem: Not handling the payment method already attached error

How to avoid: 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

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

Write a Node.js Express endpoint that replaces a Stripe customer's default payment method. Accept the customer ID and new payment method ID. Attach the new method, set it as default, and detach the old one. Use the stripe npm package.

Stripe Prompt

Add a payment method update flow to my app. Create an endpoint that accepts a new payment method token from the frontend, attaches it to the customer, sets it as the default for invoices, and removes the previous default payment method.

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.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.