You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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) {
    // ... 原有异常处理代码 ...
}

验证建议

  1. 测试多种支付方式(信用卡、电子钱包等),确认修改后全场景正常跳转
  2. 查看Stripe Dashboard的PaymentIntent记录,核对charges字段的实际返回结构
  3. 确保Stripe SDK版本与当前API版本兼容,避免版本差异导致的字段缺失

内容的提问来源于stack exchange,提问作者Ayman Shaikh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 17:15:16