Laravel Cashier报错:Call to a member function stripe() on null求助
问题场景
已创建Stripe产品,通过以下subscriptionProcess方法尝试为用户创建订阅:
public function subscriptionProcess(Request $request) { //dd($request->user()->newSubscription('Author', 'price_1MPP8WSCmMZAfVWiwJlCbVym')); $subscription = $request->user()->newSubscription('Author', 'price_1MPP8WSCmMZAfVWiwJlCbVym')->create($request->token); return view("pages.subscription_success"); }
使用Stripe测试卡号发起请求后,始终收到报错:
Laravel Cashier Call to a member function stripe() on null
执行dd($request->user()->newSubscription('Author', 'price_1MPP8WSCmMZAfVWiwJlCbVym'));能正常获取SubscriptionBuilder对象,但调用create方法时触发错误,错误日志栈如下:
[2023-01-12 21:56:53] local.ERROR: Call to a member function stripe() on null {"userId":51,"exception":"[object] (Error(code: 0): Call to a member function stripe() on null at /var/www/html/vendor/laravel/cashier/src/Subscription.php:1371) [stacktrace] #0 /var/www/html/vendor/laravel/cashier/src/Subscription.php(1271): Laravel\Cashier\Subscription->asStripeSubscription(Array) #1 /var/www/html/vendor/laravel/cashier/src/Concerns/HandlesPaymentFailures.php(28): Laravel\Cashier\Subscription->latestPayment() #2 /var/www/html/vendor/laravel/cashier/src/SubscriptionBuilder.php(263): Laravel\Cashier\SubscriptionBuilder->handlePaymentFailure(Object(Laravel\Cashier\Subscription), 'pm_1MPT92SCmMZA...') #3 /var/www/html/app/Http/Controllers/AuthorController.php(72): Laravel\Cashier\SubscriptionBuilder->create('pm_1MPT92SCmMZA...') #4 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): App\Http\Controllers\AuthorController->subscriptionProcess(Object(Illuminate\Http\Request)) #5 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\Routing\Controller->callAction('subscriptionPro...', Array) #6 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(260): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(App\Http\Controllers\AuthorController), 'subscriptionPro...') #7 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php(205): Illuminate\Routing\Route->runController() #8 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(727): Illuminate\Routing\Route->run() #9 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request)) #10 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #11 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure)) #12 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #13 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure)) #14 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/AuthenticateSession.php(59): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #15 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Session\Middleware\AuthenticateSession->handle(Object(Illuminate\Http\Request), Object(Closure)) #16 /var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(44): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #17 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Auth\Middleware\Authenticate->handle(Object(Illuminate\Http\Request), Object(Closure)) #18 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #19 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure)) #20 /var/www/html/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #21 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure)) #22 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #23 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest(Object(Illuminate\Http\Request), Object(Illuminate\Session\Store), Object(Closure)) #24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure)) #25 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #26 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure)) #27 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #28 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure)) #29 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #30 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(728): Illuminate\Pipeline\Pipeline->then(Object(Closure)) #31 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(705): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request)) #32 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(669): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route)) #33 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(658): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request)) #34 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(190): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request)) #35 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(141): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request)) #36 /var/www/html/vendor/barryvdh/laravel-debugbar/src/Middleware/InjectDebugbar.php(66): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #37 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Barryvdh\Debugbar\Middleware\InjectDebugbar->handle(Object(Illuminate\Http\Request), Object(Closure)) #38 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #39 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure)) #40 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle(Object(Illuminate\Http\Request), Object(Closure)) #41 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #42 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure)) #43 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\TrimStrings->handle(Object(Illuminate\Http\Request), Object(Closure)) #44 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #45 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle(Object(Illuminate\Http\Request), Object(Closure)) #46 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #47 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Http\Middleware\HandleCors->handle(Object(Illuminate\Http\Request), Object(Closure)) #48 /var/www/html/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(39): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #49 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(180): Illuminate\Http\Middleware\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure)) #50 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(116): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) #51 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(165): Illuminate\Pipeline\Pipeline->then(Object(Closure)) #52 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(134): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request)) #53 /var/www/html/public/index.php(52): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request)) #54 {main} "}
错误原因分析
从栈信息追踪,错误发生在Subscription.php的asStripeSubscription方法,说明尝试调用stripe()方法的对象为null。结合流程拆解:
- 订阅创建时支付失败,Cashier进入
handlePaymentFailure处理逻辑 - 调用
subscription->latestPayment()获取最新支付记录 - 尝试将本地订阅转换为Stripe订阅对象时,发现关联的Stripe订阅实例不存在
核心诱因可能包括:
- 用户模型未正确引入Cashier的
Billabletrait,或数据库表缺少stripe_id等必需字段(用于存储用户在Stripe平台的关联ID) - 订阅创建流程中,Stripe端未生成订阅记录,但本地已创建订阅条目,导致后续操作找不到对应Stripe对象
- 使用的测试卡号触发支付失败(如卡被拒绝、金额不足),而Cashier在处理失败场景时依赖已存在的Stripe订阅对象
解决方案
1. 检查用户模型与数据库配置
确保用户模型引入Laravel\Cashier\Billable trait,且数据库表包含stripe_id、pm_type、pm_last_four等Cashier必备字段:
use Laravel\Cashier\Billable; class User extends Authenticatable { use Billable; // ... 其他代码 }
若数据库缺少字段,执行Cashier迁移命令补全:
php artisan migrate
2. 捕获支付失败异常
在调用create方法时,主动捕获PaymentFailureException,避免触发内部错误:
use Laravel\Cashier\Exceptions\PaymentFailureException; public function subscriptionProcess(Request $request) { try { $subscription = $request->user()->newSubscription('Author', 'price_1MPP8WSCmMZAfVWiwJlCbVym') ->create($request->token); return view("pages.subscription_success"); } catch (PaymentFailureException $e) { // 自定义支付失败提示,返回上一页 return back()->withErrors(['payment' => '支付失败,请检查您的支付信息']); } }
3. 提前关联Stripe客户
若用户尚未生成Stripe客户ID,可提前手动创建(Cashier也会自动创建,但提前处理可避免异常):
// 确保用户已关联Stripe客户 if (!$request->user()->stripe_id) { $request->user()->createAsStripeCustomer(); }
4. 验证Stripe价格ID有效性
确认使用的price_1MPP8WSCmMZAfVWiwJlCbVym是Stripe测试环境中存在的有效订阅型价格ID,且与产品配置匹配。
5. 使用有效测试卡号
避免使用会触发支付失败的测试卡号,推荐使用4242 4242 4242 4242(任意未来过期日期、CVC均可通过),确保订阅流程正常执行。
内容的提问来源于stack exchange,提问作者Niloy Rony

