
Security News
MCP Community Begins Work on Official MCP Metaregistry
The MCP community is launching an official registry to standardize AI tool discovery and let agents dynamically find and install MCP servers.
@paypal/react-paypal-js
Advanced tools
@paypal/react-paypal-js is a React library that provides a set of components and hooks to easily integrate PayPal's payment services into a React application. It simplifies the process of adding PayPal buttons, handling transactions, and managing the PayPal SDK.
PayPal Buttons
This feature allows you to add PayPal buttons to your React application. The PayPalButtons component renders the PayPal buttons and handles the payment process.
import { PayPalScriptProvider, PayPalButtons } from '@paypal/react-paypal-js';
function App() {
return (
<PayPalScriptProvider options={{ "client-id": "your-client-id" }}>
<PayPalButtons style={{ layout: 'vertical' }} />
</PayPalScriptProvider>
);
}
Custom Button Styles
This feature allows you to customize the appearance of the PayPal buttons. You can change the layout, color, shape, and label of the buttons.
import { PayPalScriptProvider, PayPalButtons } from '@paypal/react-paypal-js';
function App() {
return (
<PayPalScriptProvider options={{ "client-id": "your-client-id" }}>
<PayPalButtons style={{ layout: 'horizontal', color: 'blue', shape: 'pill', label: 'pay' }} />
</PayPalScriptProvider>
);
}
Handling Payment Events
This feature allows you to handle payment events such as order creation and approval. You can define custom functions to create orders and handle successful transactions.
import { PayPalScriptProvider, PayPalButtons } from '@paypal/react-paypal-js';
function App() {
const createOrder = (data, actions) => {
return actions.order.create({
purchase_units: [{
amount: {
value: '0.01',
},
}],
});
};
const onApprove = (data, actions) => {
return actions.order.capture().then((details) => {
alert('Transaction completed by ' + details.payer.name.given_name);
});
};
return (
<PayPalScriptProvider options={{ "client-id": "your-client-id" }}>
<PayPalButtons createOrder={createOrder} onApprove={onApprove} />
</PayPalScriptProvider>
);
}
react-stripe-js is a React library for integrating Stripe's payment services into a React application. It provides components and hooks for handling payment forms, managing the Stripe SDK, and processing transactions. Compared to @paypal/react-paypal-js, react-stripe-js focuses on Stripe's payment services and offers similar functionalities for handling payments and customizing payment forms.
react-paypal-express-checkout is another React library for integrating PayPal's payment services. It provides a simpler interface for adding PayPal buttons and handling transactions. Compared to @paypal/react-paypal-js, react-paypal-express-checkout offers a more straightforward approach but may lack some of the advanced customization options available in @paypal/react-paypal-js.
react-payment-request-api is a React library that leverages the Payment Request API to handle payments. It supports multiple payment methods, including credit cards and digital wallets like Google Pay. Compared to @paypal/react-paypal-js, react-payment-request-api offers a more generic approach to handling payments and can be used with various payment providers.
React components for the PayPal JS SDK
Developers integrating with PayPal are expected to add the JS SDK <script>
to a website and then render components like the PayPal Buttons after the script loads. This architecture works great for simple websites but can be challenging when building single page apps.
React developers think in terms of components and not about loading external scripts from an index.html file. It's easy to end up with a React PayPal integration that's sub-optimal and hurts the buyer's user experience. For example, abstracting away all the implementation details of the PayPal Buttons into a single React component is an anti-pattern because it tightly couples script loading with rendering. It's also problematic when you need to render multiple different PayPal components that share the same global script parameters.
react-paypal-js
provides a solution to developers to abstract away complexities around loading the JS SDK. It enforces best practices by default so buyers get the best possible user experience.
Features
currency
change.To get started, install react-paypal-js with npm.
npm install @paypal/react-paypal-js
This PayPal React library consists of two main parts:
<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.<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={{ clientId: "test" }}>
<PayPalButtons style={{ layout: "horizontal" }} />
</PayPalScriptProvider>
);
}
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. Use camelCase for the object keys (clientId, dataClientToken, dataNamespace, etc...).
const initialOptions = {
clientId: "test",
currency: "USD",
intent: "capture",
};
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.
Use the optional PayPalScriptProvider deferLoading
prop to control when the JS SDK script loads.
<PayPalButtons />
render immediately.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.
The <PayPalScriptProvider />
component is designed to be used with the usePayPalScriptReducer
hook for managing global state. This usePayPalScriptReducer
hook has the same API as React's useReducer hook.
The usePayPalScriptReducer
hook provides an easy way to tap into the loading state of the JS SDK script. This state can be used to show a loading spinner while the script loads or an error message if it fails to load. The following derived attributes are provided for tracking this loading state:
deferLoading={true}
)For example, here's how you can use it to show a loading spinner.
const [{ isPending }] = usePayPalScriptReducer();
return (
<>
{isPending ? <div className="spinner" /> : null}
<PayPalButtons />
</>
);
To learn more, check out the loading spinner example in storybook.
The usePayPalScriptReducer
hook can be used to reload the JS SDK script when parameters like currency change. It provides the action resetOptions
for reloading with new parameters. For example, here's how you can use it to change 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 />
</>
);
To learn more, check out the dynamic currency example in storybook.
The <PayPalButtons />
component is documented in Storybook.
Here's an example:
// App.js
import { PayPalScriptProvider, PayPalButtons } from "@paypal/react-paypal-js";
export default function App() {
function createOrder() {
return fetch("/my-server/create-paypal-order", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
// use the "body" param to optionally pass additional order information
// like product ids and quantities
body: JSON.stringify({
cart: [
{
id: "YOUR_PRODUCT_ID",
quantity: "YOUR_PRODUCT_QUANTITY",
},
],
}),
})
.then((response) => response.json())
.then((order) => order.id);
}
function onApprove(data) {
return fetch("/my-server/capture-paypal-order", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
orderID: data.orderID
})
})
.then((response) => response.json())
.then((orderData) => {
const name = orderData.payer.name.given_name;
alert(`Transaction completed by ${name}`);
});
}
}
return (
<PayPalScriptProvider options={{ clientId: "test" }}>
<PayPalButtons
createOrder={createOrder}
onApprove={onApprove}
/>
</PayPalScriptProvider>
);
}
To learn more about other available props, see the PayPalButtons docs.
The Braintree SDK can be used with the PayPal JS SDK to render the PayPal Buttons. Read more about this integration in the Braintree PayPal client-side integration docs. The <BraintreePayPalButtons />
component is designed for Braintree merchants who want to render the PayPal button.
// App.js
import {
PayPalScriptProvider,
BraintreePayPalButtons,
} from "@paypal/react-paypal-js";
export default function App() {
return (
<PayPalScriptProvider
options={{
clientId: "test",
dataClientToken:
"<the data-client-token value generated by your server-side code>",
}}
>
<BraintreePayPalButtons
createOrder={(data, actions) => {
return actions.braintree.createPayment({
flow: "checkout",
amount: "10.0",
currency: "USD",
intent: "capture",
});
}}
onApprove={(data, actions) => {
return actions.braintree
.tokenizePayment(data)
.then((payload) => {
// call server-side endpoint to finish the sale
});
}}
/>
</PayPalScriptProvider>
);
}
Check out the docs page for the BraintreePayPalButtons to learn more about the available props.
The JS SDK hosted-fields component provides payment form functionality that you can customize. Read more about this integration in the PayPal Advanced Card Payments documentation.
There are 3 parts to the hosted-fields integration:
<PayPalHostedFieldsProvider />
provider component wraps the form field elements and accepts props like createOrder()
.<PayPalHostedField>
component is used for the credit card number, expiration, and cvv elements. These are customizable using props and must be children of the <PayPalHostedFieldsProvider />
component.usePayPalHostedFields
hook exposes the submit()
function for submitting the payment with your own custom button.import {
PayPalScriptProvider,
PayPalHostedFieldsProvider,
PayPalHostedField,
usePayPalHostedFields,
} from "@paypal/react-paypal-js";
const SubmitPayment = () => {
// Here declare the variable containing the hostedField instance
const hostedFields = usePayPalHostedFields();
const submitHandler = () => {
if (typeof hostedFields.submit !== "function") return; // validate that `submit()` exists before using it
hostedFields
.submit({
// The full name as shown in the card and billing address
cardholderName: "John Wick",
})
.then((order) => {
fetch(
"/your-server-side-integration-endpoint/capture-payment-info",
)
.then((response) => response.json())
.then((data) => {
// Inside the data you can find all the information related to the payment
})
.catch((err) => {
// Handle any error
});
});
};
return <button onClick={submitHandler}>Pay</button>;
};
export default function App() {
return (
<PayPalScriptProvider
options={{
clientId: "your-client-id",
dataClientToken: "your-data-client-token",
}}
>
<PayPalHostedFieldsProvider
createOrder={() => {
// Here define the call to create and order
return fetch(
"/your-server-side-integration-endpoint/orders",
)
.then((response) => response.json())
.then((order) => order.id)
.catch((err) => {
// Handle any error
});
}}
>
<PayPalHostedField
id="card-number"
hostedFieldType="number"
options={{ selector: "#card-number" }}
/>
<PayPalHostedField
id="cvv"
hostedFieldType="cvv"
options={{ selector: "#cvv" }}
/>
<PayPalHostedField
id="expiration-date"
hostedFieldType="expirationDate"
options={{
selector: "#expiration-date",
placeholder: "MM/YY",
}}
/>
<SubmitPayment />
</PayPalHostedFieldsProvider>
</PayPalScriptProvider>
);
}
The JS SDK card-fields component provides payment form functionality that you can customize. Read more about this integration in the PayPal Advanced Card Payments documentation.
There are 3 parts to the this card-fields integration:
<PayPalCardFieldsProvider />
provider component wraps the form field elements and accepts props like createOrder()
.<PayPalCardFieldsForm />
component renders a form with all 4 fields included out of the box. This is an alternative for merchants who don't want to render each field individually in their react app.usePayPalCardFields
hook exposes the cardFieldsForm
instance that includes methods suchs as the cardFieldsForm.submit()
function for submitting the payment with your own custom button. It also exposes the references to each of the individual components for more granular control, eg: fields.CVVField.focus()
to programatically manipulate the element in the DOM.import {
PayPalScriptProvider,
PayPalCardFieldsProvider,
PayPalCardFieldsForm
usePayPalCardFields,
} from "@paypal/react-paypal-js";
const SubmitPayment = () => {
const { cardFields, fields } = usePayPalCardFields();
function submitHandler() {
if (typeof cardFields.submit !== "function") return; // validate that `submit()` exists before using it
cardFields
.submit()
.then(() => {
// submit successful
})
.catch(() => {
// submission error
});
}
return <button onClick={submitHandler}>Pay</button>;
};
export default function App() {
function createOrder() {
// merchant code
}
function onApprove() {
// merchant code
}
function onError() {
// merchant code
}
return (
<PayPalScriptProvider
options={{
clientId: "your-client-id",
components: "card-fields",
}}
>
<PayPalCardFieldsProvider
createOrder={createOrder}
onApprove={onApprove}
onError={onError}
>
<PayPalCardFieldsForm />
<SubmitPayment />
</PayPalCardFieldsProvider>
</PayPalScriptProvider>
);
}
There are 3 parts to the this card-fields integration:
<PayPalCardFieldsProvider />
provider component wraps the form field elements and accepts props like createOrder()
.<PayPalNumberField>
component used for the credit card number element. It is customizable using props and must be a child of the <PayPalCardFieldsProvider />
component.<PayPalCVVField>
component used for the credit card cvv element. It is customizable using props and must be a child of the <PayPalCardFieldsProvider />
component.<PayPalExpiryField>
component used for the credit card expiry element. It is customizable using props and must be a child of the <PayPalCardFieldsProvider />
component.<PayPalNameField>
component used for the credit cardholder's name element. It is customizable using props and must be a child of the <PayPalCardFieldsProvider />
component.usePayPalCardFields
hook exposes the cardFieldsForm
instance that includes methods suchs as the cardFieldsForm.submit()
function for submitting the payment with your own custom button. It also exposes the references to each of the individual components for more granular control, eg: fields.CVVField.focus()
to programatically manipulate the element in the DOM.import {
PayPalScriptProvider,
PayPalCardFieldsProvider,
PayPalNameField,
PayPalNumberField,
PayPalExpiryField,
PayPalCVVField,
usePayPalCardFields,
} from "@paypal/react-paypal-js";
const SubmitPayment = () => {
const { cardFields, fields } = usePayPalCardFields();
function submitHandler() {
if (typeof cardFields.submit !== "function") return; // validate that `submit()` exists before using it
cardFields
.submit()
.then(() => {
// submit successful
})
.catch(() => {
// submission error
});
}
return <button onClick={submitHandler}>Pay</button>;
};
// Example using individual card fields
export default function App() {
function createOrder() {
// merchant code
}
function onApprove() {
// merchant code
}
function onError() {
// merchant code
}
return (
<PayPalScriptProvider
options={{
clientId: "your-client-id",
components: "card-fields",
}}
>
<PayPalCardFieldsProvider
createOrder={createOrder}
onApprove={onApprove}
onError={onError}
>
<PayPalNameField />
<PayPalNumberField />
<PayPalExpiryField />
<PayPalCVVField />
<SubmitPayment />
</PayPalCardFieldsProvider>
</PayPalScriptProvider>
);
}
This library supports all popular browsers, including IE 11. It provides the same browser support as the JS SDK. Here's the full list of supported browsers.
FAQs
React components for the PayPal JS SDK
The npm package @paypal/react-paypal-js receives a total of 134,468 weekly downloads. As such, @paypal/react-paypal-js popularity was classified as popular.
We found that @paypal/react-paypal-js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 23 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The MCP community is launching an official registry to standardize AI tool discovery and let agents dynamically find and install MCP servers.
Research
Security News
Socket uncovers an npm Trojan stealing crypto wallets and BullX credentials via obfuscated code and Telegram exfiltration.
Research
Security News
Malicious npm packages posing as developer tools target macOS Cursor IDE users, stealing credentials and modifying files to gain persistent backdoor access.