Now all we have left to do is to connect our billing form to our billing API.

Change indicator Replace our return statement in src/containers/Settings.tsx with this.

const handleFormSubmit: BillingFormType["onSubmit"] = async (
  storage,
  info
) => {
  if (info.error) {
    onError(info.error);
    return;
  }

  setIsLoading(true);

  try {
    await billUser({
      storage,
      source: info.token?.id,
    });

    alert("Your card has been charged successfully!");
    nav("/");
  } catch (e) {
    onError(e);
    setIsLoading(false);
  }
};

return (
  <div className="Settings">
    <Elements
      stripe={stripePromise}
      options={{
        fonts: [
          {
            cssSrc:
              "https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800",
          },
        ],
      }}
    >
      <BillingForm isLoading={isLoading} onSubmit={handleFormSubmit} />
    </Elements>
  </div>
);

Change indicator Add the following imports to the header.

import { Elements } from "@stripe/react-stripe-js";
import { BillingForm, BillingFormType } from "../components/BillingForm";
import "./Settings.css";

We are adding the BillingForm component that we previously created here and passing in the isLoading and onSubmit prop that we referenced in the previous chapter. In the handleFormSubmit method, we are checking if the Stripe method returned an error. And if things looked okay then we call our billing API and redirect to the home page after letting the user know.

To initialize the Stripe Elements we pass in the Stripe.js object that we loaded a couple of chapters ago. This Elements component needs to wrap around any Stripe React components.

The Stripe elements are loaded inside an IFrame. So if we are using any custom fonts, we’ll need to include them explicitly. As covered in the Stripe docs.

Finally, let’s handle some styles for our settings page as a whole.

Change indicator Create a file named src/containers/Settings.css and add the following.

@media all and (min-width: 480px) {
  .Settings {
    padding: 60px 0;
  }

  .Settings form {
    margin: 0 auto;
    max-width: 480px;
  }
}

This ensures that our form displays properly for larger screens.

Settings screen with billing form screenshot

And that’s it. We are ready to test our Stripe form. Head over to your browser and try picking the number of notes you want to store and use the following for your card details:

  • A Stripe test card number is 4242 4242 4242 4242.
  • You can use any valid expiry date, security code, and zip code.
  • And set any name.

You can read more about the Stripe test cards in the Stripe API Docs here.

If everything is set correctly, you should see the success message and you’ll be redirected to the homepage.

Settings screen billing success screenshot

Now with our app nearly complete, we’ll look at securing some the pages of our app that require a login. Currently if you visit a note page while you are logged out, it throws an ugly error.

Note page logged out error screenshot

Instead, we would like it to redirect us to the login page and then redirect us back after we login. Let’s look at how to do that next.