已添加卡片仍触发Stripe报错:Cannot charge a customer that has no active card
问题原因分析与解决方案
我来帮你拆解这个问题——你遇到的Cannot charge a customer that has no active card报错,其实和你用的Stripe旧版Charges API的逻辑直接相关,结合你的代码和场景,主要有这几个可能的原因:
核心原因
- 客户卡片未设置为默认支付方式:Charges API在指定
customer参数时,会默认使用该客户的default_payment_method来扣款。如果你的客户虽然添加了卡片,但没把任何一张设为默认,API就会找不到可用的支付方式。 - 卡片状态非活跃:卡片可能过期、被标记为无效,或者添加时没完成必要的验证(比如3D安全验证),导致Stripe把它标记为非活跃状态。
- 卡片未正确关联到客户:你可能只是临时创建了支付方法,但没把它持久化关联到客户账户下(比如用了一次性token而不是绑定到customer的payment method)。
排查与解决步骤
1. 先确认客户的支付方式状态
用Stripe CLI或者Dashboard查看这个客户的详细信息,确认是否有活跃的关联卡片:
# 用Stripe CLI查询客户及关联的支付方式 stripe customers retrieve cus_I33Z2JrUSj1bBm --expand payment_methods.data
查看返回结果里的payment_methods.data,找状态为active的卡片,同时检查default_payment_method字段是否指向有效的支付方式ID。
2. 设置默认支付方式
如果卡片存在但未设默认,你可以:
- 在Stripe Dashboard里找到该客户,手动把目标卡片设为默认;
- 或者用代码更新客户的默认支付方式:
await stripe.customers.update('cus_I33Z2JrUSj1bBm', { default_payment_method: 'pm_xxxxxx' // 替换为客户名下的有效支付方式ID });
3. 切换到新版Payment Intents API(推荐)
旧版Charges API已经逐渐被Stripe弃用,新版Payment Intents API更灵活,支持更多支付场景(比如3D验证),而且会自动查找客户名下的活跃支付方式:
const paymentIntent = await stripe.paymentIntents.create({ amount: Number(amount), // 注意:金额要转成数字,Stripe要求用最小货币单位的整数 currency: currency, customer: customer, payment_method_types: ['card'], description: title, }, { idempotencyKey: onDemandId });
小提醒
你请求参数里的amount是字符串"40",虽然不是当前报错的原因,但Stripe要求金额必须是整数(比如USD的40代表40美分),建议改成数字类型避免后续问题。
内容的提问来源于stack exchange,提问作者Ahmed Abosrie
相关产品推荐
相关产品推荐

