Laravel使用Stripe Payment Element展示已保存卡片报错排查
Stripe Payment Element 已保存支付方式拉取失败(版本头报错)解决方案
核心报错When authenticating with an ephemeral key, you must set the Stripe-Version header to an explicit API version的触发原因,和你在自有接口请求头加stripe_version字段无关——这个头是发给你自己Laravel后端的,Stripe.js SDK完全读不到,属于无效操作。
1. 修正后端临时密钥创建逻辑
你之前用的2019-11-05版本过低,根本不支持Payment Element读取已保存支付方式的能力,直接替换为稳定兼容版本即可,不要自行测试控制台里的过老版本:
$ephemeralKey = \Stripe\EphemeralKey::create( ['customer' => $user->stripe_customer_id], // 写死版本号,不要动态读取配置,2022-11-15是目前该功能稳定兼容的版本 ['stripe_version' => '2022-11-15'] );
注:给$user->stripe_customer_id额外包双引号转字符串是多余操作,直接传字段值即可,不会出现类型问题。
2. 补全返回给前端的customerOptions必填字段
90%的该类报错都是因为后端返回的customerOptions结构缺字段。Stripe.js初始化时不会读你自定义的请求头,只会从customerOptions对象里取版本号拼到发给Stripe接口的请求头里,正确返回结构如下:
return response()->json([ 'clientSecret' => $paymentIntent->client_secret, 'customerOptions' => [ 'customer' => $user->stripe_customer_id, 'ephemeralKeySecret' => $ephemeralKey->secret, // 传临时密钥的secret字段,不要传整个$ephemeralKey对象 // 必须补这个字段,和创建临时密钥时传的版本号完全一致 'stripeVersion' => '2022-11-15' ] ]);
3. 移除前端无效配置
你初始化Stripe实例时加的elements_customers_beta_1参数是早期测试版用的,现在该功能已经正式上线,保留这个beta参数反而会触发版本不匹配问题,直接删掉:
// 正确初始化,不需要传过时beta参数 const stripe = Stripe("{{env('STRIPE_KEY')}}");
其余前端Elements初始化逻辑不需要改动,只要保证接口返回的customerOptions字段完整即可。
兜底排查清单
如果上述操作完成后仍报错,依次检查:
- 本地stripe-php SDK版本必须≥v7.100.0,老版本SDK传
stripe_version参数不生效,直接执行composer require stripe/stripe-php:^10.0升级到稳定版 - Stripe控制台不要给账号设置全局beta版API版本,保持和代码里写死的
2022-11-15一致 - 检查返回的
ephemeralKeySecret格式是否完整,正确前缀为ek_test_(测试环境)或ek_live_(生产环境),不要截断字符串 - 去Stripe控制台对应客户详情页确认,该客户ID下确实存在已保存的支付方式,不要用无保存卡的测试账号验证
改完后清浏览器缓存硬刷新即可,Payment Element会自动在顶部加载客户已保存的银行卡列表。
内容的提问来源于stack exchange,提问作者Faran Khan
相关产品推荐
相关产品推荐

