You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Stripe中Source、Card、Bank与Payment Method的区别及默认支付源问题

Stripe Default Payment Source Switching & API Confusion Fixes

Hey there, let's unpack the issues you're facing with Stripe's APIs and getting default payment sources to work properly. I've been through this exact confusion before, so let's break it down step by step.

Core Problem: Mixing New (Payment Methods) and Legacy (Sources) Systems

Stripe currently runs two parallel systems for handling payment methods:

  • Payment Methods API: The modern, recommended workflow for most payment types (like credit cards), which uses pm_xxx-formatted IDs.
  • Sources API: The legacy system for payment types that haven't been fully migrated to the new API yet (like bank accounts/ACH), which uses ba_xxx (bank account) or card_xxx (legacy card) IDs.

Your main issue with setting the default source comes from two key missteps:

  1. You're passing a token ID (btok_xxx) to default_source instead of a valid source ID (ba_xxx).
  2. You’re mixing the new Payment Methods workflow for cards with the legacy Sources workflow for bank accounts—these systems use separate parameters to set defaults.

Fix 1: Correctly Set Default Legacy Source (Bank Accounts)

When working with legacy payment sources like bank accounts, you need to use the actual source ID (not the token ID) to update the customer’s default. Here’s how to fix your code:

Step 1: Save the Bank Account Source ID After Creation

When you call stripe.customers.createSource, the returned bank_account object has an id field (e.g., ba_123456789). This is the ID you need to store for later use:

stripe.tokens.create({
  bank_account: {
    country: 'US',
    currency: 'usd',
    account_holder_name: decoded.account_holder_name,
    account_holder_type: 'individual',
    routing_number: '110000000',
    account_number: '000123456789'
  }
}).then(token => {
  stripe.customers.createSource(
    decoded.userId,
    { source: token.id }
  ).then(bank_account => {
    // Save bank_account.id (e.g., ba_xxx) to your database
    console.log("Bank account source ID:", bank_account.id);
    res.send(bank_account);
  }).catch(err => {
    res.send(err);
  })
}).catch(err => {
  res.send(err);
});

Step 2: Update Default Source with the Correct ID

Use the saved ba_xxx ID (not the btok_xxx token) when updating the customer:

const customer = req.body.customer;
// Ensure this is the source ID (ba_xxx), not the token ID!
const sourceId = req.body.sourceId; 

stripe.customers.update(
  customer,
  { default_source: sourceId }
).then(customer => {
  res.send(customer);
}).catch(err => {
  res.send(err);
});

Fix 2: Set Default Modern Payment Method (Credit Cards)

For credit cards created via the Payment Methods API, you can’t use default_source—you need to use the default_payment_method parameter instead:

Step 1: Attach Payment Method and Save Its ID

stripe.paymentMethods.create({
  type: "card",
  card: {
    number: decoded.number,
    exp_month: decoded.month,
    exp_year: decoded.year,
    cvc: decoded.cvc
  }
}).then(paymentMethod => {
  stripe.paymentMethods.attach(
    paymentMethod.id, // This is a pm_xxx ID
    { customer: decoded.customer }
  ).then(attachedMethod => {
    // Save attachedMethod.id (pm_xxx) to your database
    console.log("Payment Method ID:", attachedMethod.id);
    res.send(attachedMethod);
  }).catch(err => {
    res.send(err);
  });
}).catch(err => {
  res.send(err);
});

Step 2: Set Default Payment Method

const customer = req.body.customer;
const paymentMethodId = req.body.paymentMethodId; // pm_xxx ID

stripe.customers.update(
  customer,
  { default_payment_method: paymentMethodId }
).then(customer => {
  res.send(customer);
}).catch(err => {
  res.send(err);
});

API Clarifications

  • stripe.customers.create vs stripe.customers.createSource:
    • stripe.customers.create: Creates a brand new customer in Stripe’s system.
    • stripe.customers.createSource: Adds a legacy payment source (bank account, old-style card) to an existing customer.
  • Payment Methods vs Sources:
    • Payment Methods are the future-proof system—Stripe recommends using them for all supported payment types. Bank accounts/ACH are still on the Sources API for now, but Stripe is actively migrating these to the new system.

Why You Didn’t See Changes in the Stripe Console

Stripe’s dashboard separates modern Payment Methods and legacy Sources in the customer’s "Payment Methods" tab:

  • Legacy sources (bank accounts) appear under the "Legacy payment sources" section
  • Modern Payment Methods (cards) appear under the main "Payment methods" section

The default setting will be highlighted in the corresponding section once you use the correct parameter.

内容的提问来源于stack exchange,提问作者Funkberater

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:31:30