使用Stripe Ruby API存储已存信用卡时遇PaymentIntent报错
问题分析与解决方案
核心问题拆解
- 自动支付方法启用时缺少
return_url:启用automatic_payment_methods[enabled]=true后,Stripe可能需要引导用户完成额外验证(如3DS),必须提供return_url让用户验证后返回你的服务。 - 错误手动创建
Charge:Stripe当前推荐用PaymentIntent处理全流程支付,手动创建Charge属于过时用法;且你试图将PaymentIntent作为source传入的逻辑完全错误,这直接导致了“No such token”错误。 PaymentIntent未正确确认:创建PaymentIntent后必须执行确认操作才能触发支付流程,跳过确认会导致其处于未完成状态,无法生成有效支付记录。
修正后的完整代码
# 创建PaymentIntent,提前指定return_url(后续确认时也可传入) pay_intent = Stripe::PaymentIntent.create({ amount: (invoice._amount_due * 100).to_i, customer: account.stripe_id, currency: 'usd', payment_method: method.stripe_id, automatic_payment_methods: { enabled: true }, return_url: 'https://your-domain.com/payment-return' # 替换为你的实际回调地址 }) begin # 确认PaymentIntent,传入必要参数 pay_intent = Stripe::PaymentIntent.confirm( pay_intent.id, { return_url: 'https://your-domain.com/payment-return' } # 若创建时未传,此处必须提供 ) rescue Stripe::InvalidRequestError => e Rails.logger.debug "Stripe支付确认失败: #{e.message}" # 可添加错误处理逻辑,如返回提示给用户 return end # 处理支付结果 if pay_intent.status == 'succeeded' # PaymentIntent成功后会自动生成关联Charge,无需手动创建 charge = pay_intent.charges.data.first # 修复拼写错误:acocunt → account payment = Payment.find_or_create_by( account: invoice.account, stripe_id: charge.id ) payment.update({ amount: charge['amount'].to_f / 100, stripe_amount_captured: charge['amount_captured'].to_f / 100, stripe_created: Time.at(charge['created']), # 使用Charge的实际创建时间 stripe_currency: charge['currency'] }) AccountInvoicePaymentApplicator.new(invoice: invoice) else # 处理支付未完成场景,如requires_action需引导用户完成验证 Rails.logger.debug "支付未完成,状态: #{pay_intent.status}" # 若状态为requires_action,需前端跳转到pay_intent.next_action.redirect_to_url.url完成验证 end
关键修正点说明
- 补充
return_url:无论在create还是confirm阶段,必须提供有效的回调地址,用于用户完成3DS等验证后返回你的服务。 - 移除手动创建
Charge:PaymentIntent成功后,Stripe会自动生成关联的Charge,通过pay_intent.charges.data.first即可获取,无需手动创建。 - 正确处理状态分支:若
pay_intent.status为requires_action,需引导用户跳转到指定链接完成验证,而非直接判定为失败。 - 修复代码错误:修正拼写错误
acocunt,调整时间字段赋值逻辑,确保数据准确性。 - 复用已保存支付方式:你传入的
payment_method: method.stripe_id已关联到目标客户,支付成功后该方式会保留在客户名下,后续可直接复用。
内容的提问来源于stack exchange,提问作者Jason FB
相关产品推荐
相关产品推荐

