Redirect to Stripe Checkout on Form Submission

I have been trying, without success, to get a form to both submit data to Netlify and redirect to Stripe Checkout for payment. Either one without the other works fine. It seems like the Stripe handler redirectToCheckout causes the issue. I need to make sure the data submits to Netlify first and overrides whatever redirectToCheckout is doing, and then go there once the data is processed. See my code below:

import React from "react";

import { navigate } from 'gatsby-link';

import { loadStripe } from "@stripe/stripe-js";

let stripePromise

const getStripe = () => {

  if (!stripePromise) {

    stripePromise = loadStripe("pk_test_RlvibjeKdvwY81acv2YLwvTM00I3UsWXIi")

  }

  return stripePromise

};

  const redirectToCheckout = async event => {

    event.preventDefault()

    const stripe = await getStripe()

    const { error } = await stripe.redirectToCheckout({

      mode: "subscription",

      lineItems: [{ price: "price_1Gva5YAeKYVunD5viRkFzoR7", quantity: 1 }],

      successUrl: `http://localhost:8000/thanks/`,

      cancelUrl: `http://localhost:8000/404`,

    });

    if (error) {

      console.warn("Error:", error)

    }

  };

function encode(data) {

  return Object.keys(data)

    .map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))

    .join('&')

}

export default function Checkout() {

  const [state, setState] = React.useState({})

  const handleChange = (e) => {

    setState({ ...state, [e.target.name]: e.target.value })

  }

  const handleSubmit = (e) => {

    e.preventDefault()

    const form = e.target

    fetch('/', {

      method: 'POST',

      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },

      body: encode({

        'form-name': form.getAttribute('name'),

        ...state,

      }),

    })

    .then(() => console.log(`OK`)) // navigate to desired page

      .catch((error) => alert(error))

  };

  return (

      <form

        name="transfer"

        method="post"

        data-netlify="true"

        data-netlify-honeypot="bot-field"

        onSubmit={event => this.handleSubmit(event)}

        onSuccess={redirectToCheckout}

      >

        {/* The `form-name` hidden field is required to support form submissions without JavaScript */}

        <input type="hidden" name="form-name" value="transfer" />

        <p hidden>

          <label>

            Don’t fill this out: <input name="bot-field" onChange={handleChange} />

          </label>

        </p>

        <p>

          <label>

            Your name:

            <br />

            <input type="text" name="name" onChange={handleChange} />

          </label>

        </p>

        <p>

          <label>

            Your email:

            <br />

            <input type="email" name="email" onChange={handleChange} />

          </label>

        </p>

        <p>

        <button type = "submit"  >Pay</button>

        </p>

      </form>

  )

}

I have tried all types of form handling attributes: onClick, onSubmit, onSuccess. So far nothing allows for both the redirectToCheckout as well as submit data to Netlify. Feel like I’ve exhausted my options there.

I retain some help for placing the Stripe redirect inside the handleSubmit function .then(() => console.log(OK)) // navigate to desired page

Does this seem viable? If so, how would you go about calling redirectToCheckout?

  • Matt

Hey Matt,
The best plan of action would be to first make sure your forms are submitting. This code snippet is very similar to yours but has some key differences: gatsby-starter-default-form/form.js at form-custom-success · kaganjd/gatsby-starter-default-form · GitHub Want to see if you can drop that into your project and get a form submission to it?

After that, you should be able to add some logic in the navigate portion here:

to call the function you want to redirect to Stripe. Let us know how it goes!

1 Like

Hey Jen,

Thanks for jumping in!

Yes, I am able to submit.

However, when I add

      .then(() => navigate({redirectToCheckout}))       

I get a browser error in localhost stating

TypeError: path.startsWith is not a function

Any idea what’s going on? Not sure if Gatsby’s navigate can handle the function call :thinking:

Hey @mcb-11561,
Great! If form submissions are working, let’s move on to Stripe stuff. I think you’re correct that you can’t call redirectToCheckout the way you are there. Want to try this instead:

// instead of navigate(), call your Stripe function
.then(() => redirectToCheckout())

I don’t think you’ll need the event bit of that function since, as far as I can tell, you’re not using it in the redirect. I’d try something like this:

const redirectToCheckout = async () => {
    const stripe = await getStripe()
    const { error } = await stripe.redirectToCheckout({
// ... the rest of the function ... 

Let us know how it goes!

1 Like

Hey Jen - Yes: This worked. My logic is a little different but the meat is the same.
Here’s my result in staging: https://thirsty-lovelace-bf2b31.netlify.app/lei-extension/

1 Like