Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

sAnsic's avatar

Laravel Cashier checkout() returns object instead of Stripe checkout page

I do as described in the instructions

Route::get('/subscription-checkout/{plan_id}', function (Request $request, string $plan_id) {
        return auth()->user()
            ->newSubscription('default', $plan_id)
            ->checkout([
                'success_url' => route('subscription.success'),
                'cancel_url' => route('subscription.error'),
            ]);
    })->name('subscription');

In documentation:

When a customer visits this route they will be redirected to Stripe's Checkout page

But this code returns an object to me:

{
    "id": "cs_test_a18z......",
    "object": "checkout.session",
    "after_expiration": null,
    "allow_promotion_codes": null,
    "amount_subtotal": 3900,
    "amount_total": 3900,
    "automatic_tax": {
        "enabled": false,
        "status": null
    },
    "billing_address_collection": null,
    "cancel_url": "http://example.com/subscription-error",
    "client_reference_id": null,
    "consent": null,
    "consent_collection": null,
    "currency": "usd",
    "customer": "cus_MNtVxbbMUf8RF0",
    "customer_creation": null,
    "customer_details": {
        "address": null,
        "email": "[email protected]",
        "name": null,
        "phone": null,
        "tax_exempt": null,
        "tax_ids": null
    },
    "customer_email": null,
    "expires_at": 1662579951,
    "livemode": false,
    "locale": null,
    "metadata": [],
    "mode": "subscription",
    "payment_intent": null,
    "payment_link": null,
    "payment_method_collection": "always",
    "payment_method_options": null,
    "payment_method_types": [
        "card"
    ],
    "payment_status": "unpaid",
    "phone_number_collection": {
        "enabled": false
    },
    "recovered_from": null,
    "setup_intent": null,
    "shipping": null,
    "shipping_address_collection": null,
    "shipping_options": [],
    "shipping_rate": null,
    "status": "open",
    "submit_type": null,
    "subscription": null,
    "success_url": "http://example.com/subscription-success",
    "total_details": {
        "amount_discount": 0,
        "amount_shipping": 0,
        "amount_tax": 0
    },
    "url": "https://checkout.stripe.com/pay/cs_test_a18znp............"
}
 "laravel/cashier": "13",
 "laravel/framework": "^8.75"

What is the problem?

0 likes
11 replies
sAnsic's avatar

I myself did not notice that I had version 13.0.0 installed, and there was no redirect in it yet. Updated to 13.16 and it worked

SaravananRajendiran's avatar

$checkout = $request->user()->stripe()->checkout->sessions->create([ 'customer_email' => $request->user()->email, 'line_items' => [[ 'price' => 'SUBSCRIPTION_ID', 'quantity' => 1, ]], 'mode' => 'subscription', 'success_url' => route('thankyou'), 'cancel_url' => route('home') ]);

//return $checkout; //checkout session response.

return redirect()->to( $checkout->url )->send();
dev_2108's avatar

@sansic @martinbean Good evening. Guys, tell me, please, I have a problem with Stripe subscriptions. I'm using a package - Laravel Cashier and I want to subscribe using Subscription Checkouts. Here is my piece of code


public function subscriptionCheckout(Request $request)
    {
        $user = auth()->user();
        return $user
            ->newSubscription('default', 'price_1N8z5gIXJCCFYtSmyBwtqii5')
            ->checkout([
                'success_url' => route('dashboard'),
                'cancel_url' => route('home'),
            ]);
    }

The subscription on the Stripe Dashboard is saved, but not in the database in the subscription table. Tell me, please, what else should be added?

Previously saved subscriptions like this


public function sunscribe($user, $paymentMethod, $plan)
     {
         $subscription = $user->newSubscription("$plan->name", $plan->plan_id);
         $subscription->create($paymentMethod);
     }

but didn't use, Subscription Checkouts, everything was saved normally, both on the Dashboard and in the Database

The documentation states

Using Stripe Checkout for subscriptions requires you to enable the customer.subscription.created webhook in your Stripe dashboard. This webhook will create the subscription record in your database and store all of the relevant subscription items.

I subscribed to all events

martinbean's avatar

@dev_2108 Check your webhook is actually processing events properly.

If you’ve already added your webhook URL to your Stripe Dashboard, then you should be able to inspect delivery attempts and their status (i.e. 200, 404, etc). If you haven’t added your webhook URL to your Stripe Dashboard, then that’s the first step.

dev_2108's avatar

@martinbean yes, I have a route that handles Stripe's webhooks

Route::post('/stripe/webhook', [StripeWebhookController::class, 'handleWebhook']);

here is my controller method that handles web hooks. I receive data from Stripe, it reaches me in the application, and I can process it.



public function handleWebhook(Request $request)
    {
        Stripe::setApiKey(config('services.stripe.secret'));
        $endPointSecret = config('services.stripe.webhook_secret');
        $payload = @file_get_contents('php://input');
        $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
        $event = null;

        try {
            $event = Webhook::constructEvent(
                $payload, $sig_header, $endPointSecret
            );
        } catch(\UnexpectedValueException $e) {
            // Invalid payload
            logger('Logger Invalid payload');
            http_response_code(400);
            exit();
        } catch(\Stripe\Exception\SignatureVerificationException $e) {
            // Invalid signature
            logger('Logger Invalid signature');
            http_response_code(400);
            exit();
        }

        switch ($event->type) {
            case 'invoice.payment_succeeded':
                /*
                
                */
            case 'customer.subscription.trial_will_end':
            /*
            
            */
            case 'invoice.payment_failed':
            /*
           
           */
            case 'customer.subscription.created':
            /*
            
            */

            default:
                break;
        }

        http_response_code(200);
    }

this code saves the subscription only on the stripe dashboard, but does not save it in the database.. help me please


public function subscriptionCheckout(Request $request)
    {
        $user = auth()->user();
        return $user
            ->newSubscription('default', 'price_1N8z5gIXJCCFYtSmyBwtqii5')
            ->checkout([
                'success_url' => route('dashboard'),
                'cancel_url' => route('home'),
            ]);
    }
martinbean's avatar

@dev_2108 Why are you doing that? Cashier already registers a webhook handler, that will create subscriptions off the back of checkout webhooks, and will automatically check webhook signatures.

Also, can you please create your own thread with your question, instead of piggy-backing someone else’s from 11 months ago?

1 like
sAnsic's avatar

@dev_2108 did you register webhooks?

php artisan cashier:webhook

and exclude stripe routes from middleware App\Http\Middleware\VerifyCsrfToken

protected $except = [
    'stripe/*',
];
dev_2108's avatar

@sAnsic no, but when I look at all the route php artisan route:list

stripe/webhook ......................................................................................................... cashier.webhook › Laravel\Cashier › WebhookController@handleWebhook

I have such a route, in the list

SaravananRajendiran's avatar

$checkout = $request->user()->stripe()->checkout->sessions->create([ 'customer_email' => $request->user()->email, 'line_items' => [[ 'price' => 'SUBSCRIPTION_ID', 'quantity' => 1, ]], 'mode' => 'subscription', 'success_url' => route('thankyou'), 'cancel_url' => route('home') ]);

//return $checkout; //checkout session response.

// Use $checkout->url to redirect return redirect()->to( $checkout->url )->send();

Please or to participate in this conversation.