Laravel网站Stripe支付成功后触发Call to a member function first() on null错误
问题分析与解决
错误原因
错误Call to a member function first() on null出现在代码第38行$charge->charges->first()->id处,说明$charge->charges为null。常见触发场景:
- 部分支付方式(如预授权、延迟到账类)的PaymentIntent对象暂未生成charges记录
- Stripe API版本更新后,PaymentIntent的
charges字段返回逻辑发生变化 - 支付完成后,Stripe后台charges数据同步存在短暂延迟
解决方案
方案1:增加空值校验与备选逻辑
给获取charge_id的代码块添加有效性检查,避免直接调用first()导致报错:
$charge = PaymentIntent::retrieve($session->payment_intent); // 新增空值校验逻辑 $chargeId = null; if (isset($charge->charges) && $charge->charges->count() > 0) { $chargeId = $charge->charges->first()->id; } else { // 若charges为空,使用PaymentIntent的id作为备选(可根据业务需求调整) $chargeId = $session->payment_intent; // 可选:记录日志便于后续排查 Log::warning('Stripe PaymentIntent无charges记录', ['payment_intent_id' => $session->payment_intent]); }
方案2:直接从Checkout Session取数(更高效)
无需额外调用PaymentIntent接口,Checkout Session本身已包含核心支付信息。如果业务允许,可直接用Session的payment_intent作为支付凭证标识:
// 移除PaymentIntent::retrieve调用,直接使用session的payment_intent作为charge_id $chargeId = $session->payment_intent;
方案3:局部捕获异常优雅处理
在现有try-catch块中,针对该特定错误单独处理,避免整体流程中断:
try { // ... 原有代码 ... $charge = PaymentIntent::retrieve($session->payment_intent); // 尝试获取charge id,捕获可能的空值错误 try { $chargeId = $charge->charges->first()->id; } catch (\Throwable $e) { $chargeId = $session->payment_intent; Log::error('获取Stripe charge id失败', ['error' => $e->getMessage(), 'payment_intent_id' => $session->payment_intent]); } // ... 原有代码 ... } catch (Exception $exception) { // ... 原有异常处理代码 ... }
验证建议
- 测试多种支付方式(信用卡、电子钱包等),确认修改后全场景正常跳转
- 查看Stripe Dashboard的PaymentIntent记录,核对charges字段的实际返回结构
- 确保Stripe SDK版本与当前API版本兼容,避免版本差异导致的字段缺失
内容的提问来源于stack exchange,提问作者Ayman Shaikh
相关产品推荐
相关产品推荐

