8

Issue: So whenever I click the HTML button that activates the Javascript code, I get an error in the console stating: POST http://127.0.0.1:8000/payment 419 (unknown status)

What I have tried

I have tried different ways to get the variable to work, returning it with a view, JSON_ENCODE(), I keep trying to research how to use fetch with Laravel and I feel like I am missing something obvious.

Here is my HTML & Javascript code:

<form action="/payment" method="POST">
@csrf
<button class="btn btn-primary py-3 px-4" id="checkout-button">Proceed to Checkout</button>
<script type="text/javascript">
    // Create an instance of the Stripe object with your publishable API key
    var stripe = Stripe('pk_test_*******************');
    var checkoutButton = document.getElementById('checkout-button');

    checkoutButton.addEventListener('click', function() {
    // Create a new Checkout Session using the server-side endpoint you
    // created in step 3.
        fetch('/payment', {
            method: 'POST', 
            headers: {
               'Content-Type': 'application/json',
               'Accept': 'application/json',
               'url': '/payment',
            },
         })
         .then(function(response) {
             return response.json();
         })
         .then(function(session) {
             return stripe.redirectToCheckout({ sessionId: session.id });
         })
         .then(function(result) {
             // If `redirectToCheckout` fails due to a browser or network
             // error, you should display the localized error message to your
             // customer using `error.message`.
             if (result.error) {
                 alert(result.error.message);
             }
          })
          .catch(function(error) {
              //console.error('Error:', error);
          });
      });
</script>
</form>

This is my route:

Route::post('/payment', [StripePaymentController::class, 'payment']);

This is my controller method:

    /* Sends the stripe key, and payment info to the stripe api, as long as the payment session */
    public function payment() {
        // Sets up the businesses secret key to receive the payment
        \Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));

        // Sets up payment method, and product information
        $session = \Stripe\Checkout\Session::create ([
            'payment_method_types' => ['card'],
            'line_items' => [[
              'price_data' => [
                'currency' => 'usd',
                'product_data' => [
                  'name' => 'T-shirt',
                ],
                'unit_amount' => 2000,
              ],
              'quantity' => 1,
            ]],
            'mode' => 'payment',
            'success_url' => 'http://127.0.0.1:8000/',
            'cancel_url' => 'http://127.0.0.1:8000/cart',
        ]);

        return response()->json(['id' => $session->id]);
    }

2 Answers 2

11

It's an error regarding CSRF token mismatch

You will need to manually pass the token in fetch request

fetch('/payment', {
    method: 'POST', 
    headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'url': '/payment',
        "X-CSRF-Token": document.querySelector('input[name=_token]').value
    },
})
Sign up to request clarification or add additional context in comments.

10 Comments

Oh.... it works... I spent 2 days straight for that... How did you get this information? So I can reference it.
@RodrigoAlvarez Laravel docs: laravel.com/docs/8.x/csrf#csrf-introduction. Remember to accept/upvote the answer if it resolves your issue for the benefit of subsequent visitors
Yes indeed. If you look at the hidden input populated by @csrf in devtools you can see the name and value
Nothing wrong with the previous version. I changed it to vanilla javascript so that it becomes library/framework agnostic. No dependency on library like jquery
I would recommend beginnerjavascript.com course - it's a paid one but worth it. javascript30.com is another one from the same author and free but it's a bit on intermediate-advance level
|
0

In my case, I just define minimal fetch like :

    form.addEventListener('click', event => {
        event.preventDefault()
        event.stopPropagation()
        const btn = event.target // submit button of the form
        const form = btn.form // retrieve form
        const sample_id = document.querySelector('#sample-id').value
        const formData = new FormData(form)
        formData.append('sample-id', sample_id)
        fetch('/my-url/my-command', {
            method: 'POST',
            headers: {
                'X-CSRF-TOKEN': formData.get('_token')
            },
            body: formData

without content-type as suggested in https://stackoverflow.com/a/46640744/6614155

BE CAREFUL that your form in blade file was correctly make with the correct method (POST in this case … if use spatie : html->form->('POST'))… the form should be a POST with a hidden input with PUT for example, and it is tricky to find these error !

Then in my Laravel controller :

    public function storeFromJs(Request $formDatas)
    {
        dd($formDatas);
        // … $sample_id = $formDatas->input('sample-id');
        // …
        return response()->json(['place_id' => $place_id]);
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.