Integrate PayPal Checkout into your React app

Greg Jopa
The PayPal Technology Blog
4 min readJun 7, 2021
Hand holding phone with doodles coming out of the screen
Photo by ESB Professional on Shutterstock

Shopping through a phone or tablet, also known as mobile commerce, has expanded at exponential rates over the past few years. Business Insider intelligence predicts that mobile commerce will account for 44% of e-commerce by 2024.

So what does this mean for developers? It means creating checkout functionality which is dynamic and fast. Single page applications can help accomplish both of these goals. ReactJS is a strong library for single page applications and we are excited to share our react-paypal-js library. This library provides an easy way to incorporate PayPal into React apps to support securely accepting payments.

These are a few of the features that react-paypal-js offers:

Global PayPalScriptProvider component

The global PayPalScriptProvder component abstracts away the complexity around loading the JS SDK.

Dispatching actions

Dispatching actions reload the JS SDK and re-render components when you require a change in global parameters. Like a currency change for instance.

Easy-to-use components

Easy-to-use components for all the different PayPal product offerings:

PayPal button stack (PayPal, Venmo, Pay Later, or Debit or Credit Card)
PayPal smart payment buttons. Venmo is available in the US only.

Get started

To start, you’ll need to get your PayPal API Credentials. This page will walk you through where to locate those in your developer portal.

Once you have your credentials, install react-paypal-js with npm.

npm install @paypal/react-paypal-js

Two main parts of this PayPal React library

This PayPal React library consists of two main parts:

1. Context Provider

The <PayPalScriptProvider /> component manages loading the JS SDK script. Add it to the root of your React app. It uses the Context API for managing state and communicating to child components. It also supports reloading the script when parameters change.

2. SDK Components

Components like <PayPalButtons /> are used to render the UI for PayPal products served by the JS SDK.

// App.js 
import { PayPalScriptProvider, PayPalButtons } from "@paypal/react-paypal-js";

export default function App() {
return (
<PayPalScriptProvider options={{ "client-id": "test" }}>
<PayPalButtons style={{ layout: "horizontal" }} />
</PayPalScriptProvider>
);
}
JavaScript on a computer screen with a bouquet in the background
Photo by Jexo on Unsplash

Options

Use the PayPalScriptProvider options prop to configure the JS SDK. It accepts an object for passing query parameters and data attributes to the JS SDK script.

const initialOptions = {
"client-id": "test",
currency: "USD",
intent: "capture",
"data-client-token": "abc123xyz==",
};

export default function App() {
return (
<PayPalScriptProvider options={initialOptions}>
<PayPalButtons />
</PayPalScriptProvider>
);
}

The JS SDK Configuration guide contains the full list of query parameters and data attributes that can be used with the JS SDK.

deferLoading

Use the optional PayPalScript Provider deferLoading prop to control when the JS SDK script loads.

  • This prop is set to false by default. Normally we know all the SDK script params up front and want to load the script right away so components like <PayPalButtons /> can render immediately.
  • This prop can be set to true. This prevents the JS SDK script from loading when the PayPalScriptProvider renders. Use deferLoading={true} initially and then dispatch an action later on in the app’s life cycle to load the SDK script.
<PayPalScriptProvider deferLoading={true} options={initialOptions}>
<PayPalButtons />
</PayPalScriptProvider>

To learn more, check out the defer loading example in storybook.

Track Loading State

The <PayPalScriptProvider /> component is designed to be used with the usePayPalScriptReducer hook to manage global state. For those familiar with React’s useReducer hook, the usePayPalScriptReducer hook has the same API.

This hook provides an easy way to access the loading state of the JS SDK script. The following derived attributes are provided for tracking the loading state:

  • isInitial: Not started (only used when passing deferLoading={true} )
  • isPending: Loading (default)
  • isResolved: Successfully loaded
  • isRejected: Failed to load

Some possible use cases are showing a loading spinner while the script loads or an error message if you encounter the isRejected result.

Here is an example of the loading spinner:

const [{ isPending }] = usePayPalScriptReducer();

return (
<>
{isPending ? <div className="spinner" /> : null}
<PayPalButtons />
</>
);

Reload When Parameters Change

The usePayPalScriptReducer hook can also be used to reload the JS SDK script when parameters change (e.g. currency). This can be done with the resetOptions action. Here is an example of using this action to change the currency.

// get the state for the sdk script and the dispatch method
const [{ options }, dispatch] = usePayPalScriptReducer();
const [currency, setCurrency] = useState(options.currency);

function onCurrencyChange({ target: { value } }) {
setCurrency(value);
dispatch({
type: "resetOptions",
value: {
...options,
currency: value,
},
});
}

return (
<>
<select value={currency} onChange={onCurrencyChange}>
<option value="USD">United States dollar</option>
<option value="EUR">Euro</option>
</select>
<PayPalButtons />
</>
);
GitHub Octocat toy with laptop in background
Photo by Roman Synkevych on Unsplash

Learn more and get involved

To learn more, check out the dynamic currency example in storybook.

If you want to get involved, you can always comment below or propose a pull request on the GitHub repo. We work to build products that capture the use cases developers need and your feedback helps ensure we’re on the right track.

--

--