Ahsan
Ahsan

Reputation: 1359

Laravel Stripe checkout: 419 (unknown status)

I am trying to use Stripe checkout using the payment page hosted on Stripe. Stripe documentation works with pure PHP. But with Laravel, its not redirecting to Stripe payment page. In the console, it shows POST http://127.0.0.1:8000/stripe 419 (unknown status) and Error: SyntaxError: Unexpected token < in JSON at position 0. According to some posts, I added https://checkout.stripe.com/ in the VerifyCsrfToken middleware.

The checkout page:

<head>
    ...
    <script src="https://polyfill.io/v3/polyfill.min.js?version=3.52.1&features=fetch"></script>
    <script src="https://js.stripe.com/v3/"></script>
</head>
<body>
<button type="button" id="checkout-button">Checkout</button>
<script type="text/javascript">
    var stripe = Stripe("{{ env('STRIPE_KEY') }}");;
    var checkoutButton = document.getElementById("checkout-button");
    checkoutButton.addEventListener("click", function () {
        fetch("{{ route('stripe-store') }}", {
            method: "POST",
        })
            .then(function (response) {
                return response.json();
            })
            .then(function (session) {
                return stripe.redirectToCheckout({ sessionId: session.id });
            })
            .then(function (result) {
                if (result.error) {
                    alert(result.error.message);
                }
            })
            .catch(function (error) {
                console.error("Error:", error);
            });
    });
</script>

In controller:

public function store(Request $request)
{
    Stripe::setApiKey(env('STRIPE_SECRET'));
    header('Content-Type: application/json');
    $checkout_session = Session::create([
        'payment_method_types' => ['card'],
        'line_items' => [[
            'price_data' => [
                'currency' => 'usd',
                'unit_amount' => 2000,
                'product_data' => [
                    'name' => 'Stubborn Attachments',
                ],
            ],
            'quantity' => 1,
        ]],
        'mode' => 'payment',
        'success_url' => route('welcome'),
        'cancel_url' => route('welcome'),
    ]);
    echo json_encode(['id' => $checkout_session->id], JSON_THROW_ON_ERROR);
}

The route for the controller method is Route::post('stripe', [StripeController::class, 'store'])->name('stripe-store');

Please help.

Upvotes: 5

Views: 2599

Answers (1)

John Lobo
John Lobo

Reputation: 15319

add your route url in VerifyCsrfToken .This will exclude validating csrf token .You can find this middleware in App\Http\Middleware path folder

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'stripe',
       
    ];
}

As official documentation says

Sometimes you may wish to exclude a set of URIs from CSRF protection. For example, if you are using Stripe to process payments and are utilizing their webhook system, you will need to exclude your Stripe webhook handler route from CSRF protection since Stripe will not know what CSRF token to send to your routes. Typically, you should place these kinds of routes outside of the web middleware group that the App\Providers\RouteServiceProvider applies to all routes in the routes/web.php file. However, you may also exclude the routes by adding their URIs to the $except property of the VerifyCsrfToken middleware:

Ref for laravel 8:https://laravel.com/docs/8.x/csrf#preventing-csrf-requests

Ref for laravel 10 : https://laravel.com/docs/10.x/csrf#csrf-excluding-uris

Upvotes: 9

Related Questions