Disclaimer You can find the updated version of this tutorial
This tutorial is part of the « Cooking a Deliveroo clone with Next.js (React), GraphQL, Strapi and Stripe » tutorial series.
Table of contents
Note: the source code is available on [GitHub(https://github.com/strapi/strapi-examples/tree/master/nextjs-react-strapi-deliveroo-clone-tutorial).
You must start being starving... I am sure you want to be able to order!
We need to store the orders in our database, so we are going to create a new Content Type in our API.
Same process as usual:
Add Content Type
.order
as name.Add New Field
and create the followings fields:address
with type String
.city
with type String
.dishes
with type JSON
.amount
with type Integer
(decimal).To create new orders from the client, we are going to hit the create
endpoint of the order
API. To allow access, navigate to the Roles & Permissions section (http://localhost:1337/admin/plugins/users-permissions), select the authenticated
role, tick the order/create
checkbox, and save.
In this section you will need Stripe API keys. To get them, create a Stripe account and navigate to https://dashboard.stripe.com/account/apikeys.
If you already used Stripe, you probably know the credit card information does not go through your backend server. Instead, the credit card information is sent to the Stripe API (ideally using their SDK). Then, your frontend receives a token that can be used to charge credit cards. The id
must be sent to your backend which will create the Stripe charge.
Not passing the credit card information through your server relieves you the responsibility to meet complicated data handling compliance, and is just far easier than worrying about securely storing sensitive data.
In order to integrate the Stripe logic, we need to update the create
charge endpoint in our Strapi API. To do so, edit backend/api/order/controllers/order.js
and replace its content with:
Path: /backend/api/order/controllers/order.js
Note: in a real-world example, the amount should be checked on the backend side and the list of dishes related to the command should be stored in a more specific Content Type called orderDetail
.
Install the stripe
package inside the backend directory:
1cd ..
2cd ..
3cd ..
4cd backend
5npm i stripe --save
Do not forget to restart the Strapi server.
Note: if an error occurs, run npm i strapi-hook-mongoose
.
To interact with the Stripe API, we will use the react-stripe-elements which will give us a StripeProvider and Elements components to style our credit card form and submit the information properly to Stripe.
Create a new page: pages/checkout.js/
,
1cd ..
2cd frontend
3yarn add react-stripe-elements
4cd pages
5touch checkout.js
Path: /frontend/pages/checkout.js
Now we are going to create the checkout form and card section component to capture the credit card info and pass it to Stripe using the react-stripe-elements package:
Create the checkout form files:
1cd ..
2cd components
3mkdir Checkout
4cd Checkout
5touch CheckoutForm.js
Path: /frontend/components/Checkout/CheckoutForm.js
Now create a CardSection.js
file to use the React Elements in, this will house the input boxes that will capture the CC information.
1touch CardSection.js
Path: /frontend/components/Checkout/CardSection.js
Now if you select a dish and click the order you should see:
Now if you submit your order, you should see the order under the Strapi dashboard as follows:
Explanations 🕵️
Note: explanations of code samples only, do not change your code to match this as you should already have this code this is simply a snippet
For server-side rendering with react-stripe elements, some modifications need to be made as Stripe will only be available on the client not the server.
To account for this, the stripe pk_key is set in the ComponentDidMount lifecycle hook that only fires on the browser:
Stripe will use a <StripeProvider>
component that will take in your stripe pk_key as a prop. This allows the children of the component access to the stripe key.
To use the integrated stripe components we will wrap our CheckoutForm component in the <Elements>
component.
The downstream import { injectStripe } from "react-stripe-elements"
inside the CheckoutForm component is required for the Elements children components to pass the CC information to Stripe.
Stripe will automatically detect which components are generating the CC information and what information to send to receive the token.
This submitOrder function will first make the call to Stripe with the CC information and receive back the Token if the CC check passed. If the token is received we next call the Strapi SDK to create the order passing in the appropriate information and token id.
This is what creates the order in Stripe and creates the DB entry in Strapi. If successful you should see your Stripe test balances increase by the amount of the test order.
You are now able to let users submit their order.
Bon appétit! 🇫🇷
🚀 In the next (and last) section, you will learn how to deploy your Strapi app on Heroku and your frontend app on NOW: https://blog.strapi.io/strapi-next-deploy.
Ryan is an active member of the Strapi community and he's been contributing at a very early stage by writing awesome tutorial series to help fellow Strapier grow and learn.