How to add PayPal checkout payments to your React app
Pato
Posted on November 2, 2022
Have you always wondered how to monetize your web applications 🤑? Time to start making those benjamins 💸💸. In this how-to guide, you will learn how to integrate PayPal as your checkout payment solution for your ReactJS app using the react-paypal-js npm package.
What is PayPal? Paypal is a payment processing product that helps you process payments for your mobile and web applications. We provide a fast and easy way to handle online payments, whether it's for a digital media property or an online merchant of any kind in over 100 countries.
Guide Overview
-
Part 1: PayPal Developer sandbox App
- Creating an app using the PayPal sandbox
-
Part 2: Adding PayPal to your React App
- Add the PayPal NPM package
- Working with the
PayPalScriptProvider
- Loading state with the
usePayPalScriptReducer
- Adding the PayPal buttons
-
Part 3: Testing the PayPal Checkout
- Testing the PayPal Checkout
This tutorial requires the following:
- A PayPal Developer Account
- A ReactJS application (I'm using create react app for this example).
You can find the source code to this guide in our PayPal React Sample App in our Github Org.
Part 1: PayPal Developer sandbox app
First, we need to create a PayPal app. To do this, navigate to the PayPal Developer Dashboard and login into your PayPal developer account. Once you are inside the PayPal Developer dashboard, make sure you are in the My Apps & Credentials page. Inside this page, click on the blue button Create App.
Enter the name of the PayPal app you are creating. In my case, I named my app React-checkout. Now, select the App Type to be a Merchant, and click on the blue button Create App.
After creating your PayPal app, you will see a screen similar to mine. In this screen, you will see your Client ID. Copy this ID and save it somewhere (We will use it later on in this tutorial).
You can always get this Client ID by navigating to the app you just created inside of the PayPal Developer Dashboard.
Note: Client ID is Class 4 data. Client ID is non-sensitive data, but still be prudent about sharing or posting it. We recommend putting the Client ID in an environment variable in an .env
file.
Part 2: Adding PayPal to your React App
Add the PayPal NPM package
To install the react-paypal-js npm package run the following command inside of your project's terminal.
npm install @paypal/react-paypal-js
The PayPal npm package consists of 2 main parts:
The Context Provider, this
<PayPalScriptProvider/>
is responsible for the PayPal JS SDK script. This provider uses the native React Context API for managing the state and communicating with child components. It also supports reloading the script when parameters change.The PayPal SDK Components, components like
<PayPalButtons/>
are used to render the UI for PayPal products served by the JS SDK.
If you have any issues with this npm package, please report them in its GitHub repo.
After you have installed the react-paypal-js npm package, open your root file, in my case my root file is the App.js
file.
In this app, the App.js
component is responsible for loading the PayPal script and rendering the <Checkout/>
component. The <Checkout/>
component will be created later in this tutorial.
In this file, you will import the PayPalScriptProvider
from the PayPal npm package.
At the top of the file, add the following line of code:
import { PayPalScriptProvider } from "@paypal/react-paypal-js";
In this file we are adding the initialOptions
object, these options can be changed with other configuration parameters. To learn more about the other configuration options look at the PayPal SDK docs.
const initialOptions = {
"client-id": "YOUR-CLIENT-ID-HERE",
currency: "USD",
intent: "capture",
};
Now, make sure you replace the text from the client-id property with the Client ID from your PayPal app.
Working with the PayPalScriptProvider
Finally, inside the App.js
, we add the <PayPalScriptProvider/>
. Notice we have inside the provider the <Checkout/>
component where we have the PayPal components. We now add the options prop to the PayPalScriptProvider
to configure the JS SDK. It accepts an object for passing query parameters and data attributes to the JS SDK script.
<PayPalScriptProvider options={initialOptions}>
<Checkout/>
</PayPalScriptProvider>
Your App.js
component should look like this:
import Checkout from './Checkout';
import { PayPalScriptProvider } from "@paypal/react-paypal-js";
const initialOptions = {
"client-id": "YOUR-CLIENT-ID-HERE",
currency: "USD",
intent: "capture",
};
function App() {
return (
<PayPalScriptProvider options={initialOptions}>
<Checkout/>
</PayPalScriptProvider>
);
}
export default App;
In our React app, we are giving the user the option to select between 2 currencies (USD and Euro) to make a payment. When the user changes the currency, the value will be passed to the PayPal script thanks to the usePayPalScriptReducer()
.
Time to create a new Checkout.js
component inside of your React application. This file is responsible for loading the PayPal components such as the PayPal buttons.
At the top of the Checkout.js
file, add the following line to include the PayPalButtons
and the usePayPalScriptReducer
.
import { PayPalButtons, usePayPalScriptReducer } from "@paypal/react-paypal-js";
Loading state with the usePayPalScriptReducer
The usePayPalScriptReducer
will show a spinner when the PayPal script is loading and can be used to change the values of the options of the PayPal script and at the same time reload the script with the updated parameters.
The PayPal script has several loading states and with the usePayPalScriptReducer
we can track it in an easier way. This state can be used to show a loading spinner while the script loads or an error message if it fails to load.
Loading states:
- isInitial - not started (only used when passing deferLoading={true})
- isPending - loading (default)
- isResolved - successfully loaded
- isRejected - failed to load
In this sample app, we used the isPending
state to render the rest of the UI including the PayPalButtons
.
Inside your Checkout
component add the code below. This code will extract the options
, the loading state (isPending), and the dispatch
to dispatch an action to our usePayPalScriptReducer()
;
const [{ options, isPending }, dispatch] = usePayPalScriptReducer();
Adding The Currency Selectors
In the Checkout
component, you will add the code to update the state with the new currency the user selects and this will dispatch an action to the usePayPalScriptReducer
to update the PayPal script.
const [currency, setCurrency] = useState(options.currency);
const onCurrencyChange = ({ target: { value } }) => {
setCurrency(value);
dispatch({
type: "resetOptions",
value: {
...options,
currency: value,
},
});
}
Now, your UI will look like this:
{
isPending ? <p>LOADING...</p> : (
<>
<select value={currency} onChange={onCurrencyChange}>
<option value="USD">💵 USD</option>
<option value="EUR">💶 Euro</option>
</select>
</>
)
}
Adding the PayPal buttons
To start using the PayPal buttons, all you have to do is add the <PayPalButtons/>
component to your JSX
. The magic comes when you extend the functionality of the PayPal buttons by passing the following props available:
- style: This attribute allows you to style the PayPal button E.g color, shape, layout, and more.
- createOrder: This attribute allows you to create the request of your order with the following properties: item_total, purchase_units, and more.
- onApprove: This attribute allows doing something with the order details after the order has been created.
Inside of your <Checkout/>
component, after the onCurrencyChange
function add the following functions to be called with the onCreateOrder
and onApprove
props of the PayPal button.
const onCreateOrder = (data,actions) => {
return actions.order.create({
purchase_units: [
{
amount: {
value: "8.99",
},
},
],
});
}
const onApproveOrder = (data,actions) => {
return actions.order.capture().then((details) => {
const name = details.payer.name.given_name;
alert(`Transaction completed by ${name}`);
});
}
Now we will add the <PayPalButtons/>
component to your <Checkout/>
component. Your JSX
code should look like this:
<div className="checkout">
{isPending ? <p>LOADING...</p> :
(
<>
<select value={currency} onChange={onCurrencyChange}>
option value="USD">💵 USD</option>
<option value="EUR">💶 Euro</option>
</select>
<PayPalButtons
style={{ layout: "vertical" }}
createOrder={(data, actions) => onCreateOrder(data, actions)}
onApprove={(data, actions) => onApproveOrder(data, actions)}
/>
</>
)}
</div>
The Final code of the Checkout.js
file will look like this:
import React, { useState } from 'react';
import './Checkout.css';
import { PayPalButtons, usePayPalScriptReducer } from "@paypal/react-paypal-js";
const Checkout = () => {
const [{ options, isPending }, dispatch] = usePayPalScriptReducer();
const [currency, setCurrency] = useState(options.currency);
const onCurrencyChange = ({ target: { value } }) => {
setCurrency(value);
dispatch({
type: "resetOptions",
value: {
...options,
currency: value,
},
});
}
const onCreateOrder = (data,actions) => {
return actions.order.create({
purchase_units: [
{
amount: {
value: "8.99",
},
},
],
});
}
const onApproveOrder = (data,actions) => {
return actions.order.capture().then((details) => {
const name = details.payer.name.given_name;
alert(`Transaction completed by ${name}`);
});
}
return (
<div className="checkout">
{isPending ? <p>LOADING...</p> : (
<>
<select value={currency} onChange={onCurrencyChange}>
<option value="USD">💵 USD</option>
<option value="EUR">💶 Euro</option>
</select>
<PayPalButtons
style={{ layout: "vertical" }}
createOrder={(data, actions) => onCreateOrder(data, actions)}
onApprove={(data, actions) => onApproveOrder(data, actions)}
/>
</>
)}
</div>
);
}
export default Checkout;
Part 3: Testing the PayPal Checkout
Testing the PayPal Checkout
Inside your project run in the terminal the npm start
command to run your ReactJS application.
Open http://localhost:3000 to view the app in your browser.
You should see the following:
Finally, click on the Debit or Credit Card button to make a payment! You can use the sample card below to test the guest checkout experience with the credit cards.
Sample Card
You can create sample credit card numbers using the PayPal Credit Card Generator inside of your PayPal Developer Dashboard.
Card Type: Visa
Card Number: 4032039534213337
Expiration Date: 03/2026
CVV: 952
Online payments have grown exponentially in the past years, especially during the COVID-19 pandemic. The number of online payment transactions will continue to grow as the years go by. We know that online payments are not going anywhere, but now it’s up to you to get on this trend so your business continues to make money and PayPal is here to help you with this.
You can find the source code to guide in our PayPal React Sample App in our Github Org.
S/O to Greg Jopa for his content that help me write this how-to guide :)
PayPal Developer Community
The PayPal Developer community helps you build your career, while also improving PayPal products and the developer experience. You’ll be able to contribute code and documentation, meet new people and learn from the open source community.
- Website: developer.paypal.com
- Twitter: @paypaldev
- Github: @paypal developer
Posted on November 2, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 13, 2024