如何使用 Laravel 6 创建 Subscription 和 Cashier 10 with Stripe?

How to create Subscription with Laravel 6 and Cashier 10 with Stripe?

Laravel 开发人员,

提交付款表格后,我收到 404 错误消息。当我检查数据库时,订阅文档中没有更新。有什么建议么?我已经这样做了一段时间了,我觉得我遗漏了一些应该显而易见的东西。

SubscriptionController.php

class SubscriptionController extends Controller
{
    public function create(Request $request, Plan $plan)
    {
        $plan = Plan::findOrFail($request->get('plan'));

        $request->user()
            ->newSubscription('main', $plan->stripe_plan)
            ->create($request->stripeToken);

        return redirect()->route('home')
            ->with('success', 'Your plan subscribed successfully');
    }
}

这是我的路线

 Route::get('/plans', 'PlanController@index')->name('plans.index');
 Route::get('/plan/{plan}', 'PlanController@show')->name('plans.show');

您正在您的路线和控制器上使用 Implicit Binding。即 Laravel 将自动注入 ID 与请求 URI 中的相应值匹配的模型实例。如果在数据库中没有找到匹配的模型实例,将自动生成 404 HTTP 响应。

但是您正在使用 findOrFail 重复此行为并调用 $request->get('plan')null 因为 plan 不在您的输入请求中但它在您的路线上。所以 Plan::findOrFail(null) 导致 404 错误。

您可以通过两种方式更正代码:

  1. 删除不必要的包含 findOrFail 的行,让 Laravel 通过 隐式绑定 为您处理(我推荐这种方式) :

    class SubscriptionController extends Controller
    {
        public function create(Request $request, Plan $plan)
        {
            //$plan = Plan::findOrFail($request->get('plan')); // <= unnecessary
    
            $request->user()
                ->newSubscription('main', $plan->stripe_plan)
                ->create($request->stripeToken);
    
            return redirect()->route('home')
                ->with('success', 'Your plan subscribed successfully');
        }
    }
    
  2. 更改路由和控制器的方法以使用 $id 而不是 隐式绑定 并手动使用 findOrFail(不推荐):

    Route::get('/plan/{id}', 'PlanController@show')->name('plans.show');
    
    class SubscriptionController extends Controller
    {
        public function create(Request $request, $id)
        {
            $plan = Plan::findOrFail($id);
    
            $request->user()
                ->newSubscription('main', $plan->stripe_plan)
                ->create($request->stripeToken);
    
            return redirect()->route('home')
                ->with('success', 'Your plan subscribed successfully');
        }
    }