Stripe订阅报错:客户无关联支付源或默认支付方法排查求助
问题排查与修复方案
报错的核心原因是你虽然将支付方法关联到了客户,但未将其设置为客户的默认支付方式,同时代码中存在冗余且错误的支付操作。
问题1:未设置客户默认支付方式
调用stripe.paymentMethods.attach仅完成支付方法与客户的关联,Stripe不会自动将其设为默认支付方式。当创建订阅时,若既未指定payment_method参数,客户也没有默认支付方式,就会触发This customer has no attached payment source or default payment method错误。
两种修复方式:
方式一:关联后设置默认支付方式
在支付方法关联完成后,添加代码将其设为客户的默认账单支付方式:// 关联支付方法后新增此段 await stripe.customers.update(customer.id, { invoice_settings: { default_payment_method: paymentMethod.id, }, });方式二:创建订阅时直接指定支付方法
在subscriptions.create参数中明确传入已关联的支付方法ID:const subscription = await stripe.subscriptions.create({ customer: customer.id, items: [{price: price.id}], payment_behavior: 'default_incomplete', payment_settings: { save_default_payment_method: 'on_subscription' }, expand: ['latest_invoice.payment_intent'], payment_method: paymentMethod.id, // 新增此行 });
问题2:冗余且错误的PaymentIntent操作
你在订阅创建后额外创建并确认了一个独立的PaymentIntent,这完全没必要——订阅创建时已自动生成对应的Invoice和PaymentIntent(通过expand参数可直接获取)。此外,你硬编码使用pm_card_visa这个测试支付方法ID,而非之前创建并关联的支付方法,会导致支付与订阅完全无关,属于无效操作,建议直接删除这部分代码。
完整修复后的代码
exports.attachPaymentMethodWithCustomer = functions.https.onCall(async (data) => { try { // 创建Customer const customer = await stripe.customers.create({ description: 'My First Test Customer (created for API docs at https://www.stripe.com/docs/api)', }); // 创建Payment Method const paymentMethod = await stripe.paymentMethods.create({ type: 'card', card: { number: '4242424242424242', exp_month: 10, exp_year: new Date().getFullYear() + 1, // 改用动态年份避免测试卡过期 cvc: '314', }, }); // 关联Payment Method到Customer await stripe.paymentMethods.attach( paymentMethod.id, { customer: customer.id } ); // 设置默认支付方式 await stripe.customers.update(customer.id, { invoice_settings: { default_payment_method: paymentMethod.id, }, }); // 创建Product const product = await stripe.products.create({ name: 'Gold Special', }); // 创建Price const price = await stripe.prices.create({ unit_amount: 1000, currency: 'usd', recurring: { interval: 'month' }, product: product.id, }); // 创建Subscription const subscription = await stripe.subscriptions.create({ customer: customer.id, items: [{ price: price.id }], payment_behavior: 'default_incomplete', payment_settings: { save_default_payment_method: 'on_subscription' }, expand: ['latest_invoice.payment_intent'], }); console.log(`${subscription.id} Subscription created`); return subscription.id; } catch (error) { console.log(`error: ${error}`); throw new functions.https.HttpsError('internal', error.message); // 抛出标准错误给前端处理 } });
内容的提问来源于stack exchange,提问作者Ali Coder
相关产品推荐
相关产品推荐

