
Security News
How Enterprise Security Is Adapting to AI-Accelerated Threats
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.
@paypal/paypal-js
Advanced tools
Loading wrapper and TypeScript types for the PayPal JS SDK
The default JS SDK code snippet blocks page rendering:
<script src="https://www.paypal.com/sdk/js?client-id=test"></script>
<script>
paypal.Buttons().render("body");
</script>
The above snippet can be difficult to implement in a non-blocking way, especially in single page web apps. This is where the paypal-js library comes in. It provides the following benefits over the above snippet:
To get started, install paypal-js with npm.
npm install @paypal/paypal-js
Import the loadScript function for asynchronously loading the Paypal JS SDK.
loadScript(options)window.paypal after the JS SDK is finished loading.import { loadScript } from "@paypal/paypal-js";
let paypal;
try {
paypal = await loadScript({ clientId: "test" });
} catch (error) {
console.error("failed to load the PayPal JS SDK script", error);
}
if (paypal) {
try {
await paypal.Buttons().render("#your-container-element");
} catch (error) {
console.error("failed to render the PayPal Buttons", error);
}
}
import { loadScript } from "@paypal/paypal-js";
loadScript({ clientId: "test" })
.then((paypal) => {
paypal
.Buttons()
.render("#your-container-element")
.catch((error) => {
console.error("failed to render the PayPal Buttons", error);
});
})
.catch((error) => {
console.error("failed to load the PayPal JS SDK script", error);
});
The loadScript function accepts an object for configuring the JS SDK. It's used for setting query parameters and script attributes. It accepts parameters in camelCase or kebab-case.
The following example adds client-id and currency as query string parameters:
loadScript({ clientId: "YOUR_CLIENT_ID", currency: "EUR" });
Which will load the following <script> asynchronously:
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID¤cy=EUR"></script>
By default, the JS SDK only loads the buttons component. The components query string parameter can be used to load multiple components:
loadScript({
clientId: "YOUR_CLIENT_ID",
components: ["buttons", "marks", "messages"],
});
Which will load the following <script> asynchronously:
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&components=buttons,marks,messages"></script>
View the full list of supported query parameters.
All options prefixed with data are considered attributes. The following example adds data-page-type as an attribute:
loadScript({
clientId: "YOUR_CLIENT_ID",
dataPageType: "checkout",
});
Which will load the following <script> asynchronously:
<script
data-page-type="checkout"
src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID"
></script>
View the full list of supported script parameters.
The merchantId option accepts an array to simplify the implementation for Multi-Seller Payments. With this approach the caller doesn't have to worry about managing the two different merchant id values (data-merchant-id and merchant-id).
Here's an example with multiple merchantId values:
loadScript({
clientId: "YOUR_CLIENT_ID",
merchantId: ["123", "456", "789"],
});
Which will load the following <script> and use merchant-id=* to properly configure the edge cache:
<script
data-merchant-id="123,456,789"
src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&merchant-id=*"
></script>
Here's an example with one merchant-id value:
loadScript({
clientId: "YOUR_CLIENT_ID",
merchantId: ["123"],
});
When there's only one, the merchant-id is passed in using the query string.
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&merchant-id=123"></script>
For local development, the sdkBaseUrl option can be used to set the base url of the JS SDK:
loadScript({
clientId: "YOUR_CLIENT_ID",
sdkBaseUrl: "http://localhost.paypal.com:8000/sdk/js",
});
This library relies on JavaScript Promises. To support legacy browsers like IE 11, you must provide your own Promise polyfill. With a Promise polyfill this library will support the same browsers as the JS SDK.
The loadScript() function takes in a second parameter for providing a Promise ponyfill. It defaults to the global Promise object if it exists. There are two options for polyfilling the Promise object:
window.Promise API implementation.loadScript() without affecting other code:import { loadScript } from "@paypal/paypal-js";
import PromisePonyfill from "promise-polyfill";
loadScript(options, PromisePonyfill).then((paypalObject) => {});
We also provide a legacy build that includes the promise-polyfill library. You can reference it from the CDN here:
<script src="https://unpkg.com/@paypal/paypal-js@8.0.0/dist/iife/paypal-js.legacy.min.js"></script>
The paypal-js script is also available on the unpkg CDN. The iife/paypal-js.js build assigns the loadScript function to the window object as window.paypalLoadScript. Here's an example:
<!doctype html>
<html lang="en">
<head>
<script src="https://unpkg.com/@paypal/paypal-js@8.0.0/dist/iife/paypal-js.min.js"></script>
</head>
<body>
<div id="paypal-buttons"></div>
<script>
window.paypalLoadScript({ clientId: "test" }).then((paypal) => {
paypal.Buttons().render("#paypal-buttons");
});
</script>
</body>
</html>
loadCustomScript(options)The loadCustomScript function is a generic script loader function that works with any url.
import { loadCustomScript } from "@paypal/paypal-js";
try {
await loadCustomScript({
url: "https://www.example.com/index.js",
attributes: {
id: "custom-id-value",
"data-foo": "custom-data-attribute",
},
});
console.log("successfully loaded the custom script");
} catch (error) {
console.error("failed to load the custom script", error);
}
import { loadCustomScript } from "@paypal/paypal-js";
loadCustomScript({
url: "https://www.example.com/index.js",
attributes: { id: "custom-id-value", "data-foo": "custom-data-attribute" },
})
.then(() => {
console.log("successfully loaded the custom script");
})
.catch((err) => {
console.error("failed to load the custom script", err);
});
This package includes TypeScript type definitions for the PayPal JS SDK. This includes types for the window.paypal namespace. We support projects using TypeScript versions >= 3.8.
In addition to the type definitions above, this package also includes Typescript type definitions for the PayPal JS SDK V6.
A basic example showing data-typing for PayPal One Time Payment.
import type {
PayPalV6Namespace,
OnApproveDataOneTimePayments,
OnShippingAddressChangeData,
} from "@paypal/paypal-js/sdk-v6";
declare global {
interface Window {
paypal: PayPalV6Namespace;
}
}
const sdkInstance = await window.paypal.createInstance({
clientToken: "INSERT_YOUR_CLIENT_TOKEN_HERE",
components: ["paypal-payments", "venmo-payments"],
});
function onApproveCallback(data: OnApproveDataOneTimePayments) {}
function onShippingAddressChangeCallback(data: OnShippingAddressChangeData) {}
const paypalCheckout = sdkInstance.createPayPalOneTimePaymentSession({
onApprove: onApproveCallback,
onShippingAddressChange: onShippingAddressChangeCallback,
});
react-paypal-button-v2 is a React component wrapper for the PayPal JavaScript SDK. It simplifies the integration of PayPal buttons in React applications. Compared to @paypal/paypal-js, it is more tailored for React developers and provides a more seamless integration with React's component-based architecture.
paypal-rest-sdk is a server-side SDK for integrating PayPal's REST APIs. It allows you to handle payments, subscriptions, and other PayPal services on the server side. Unlike @paypal/paypal-js, which is client-side, paypal-rest-sdk is used for backend integrations.
braintree-web is a client-side JavaScript SDK for integrating Braintree's payment services, which is a PayPal company. It supports various payment methods, including PayPal. Compared to @paypal/paypal-js, braintree-web offers a broader range of payment options and is suitable for developers looking to integrate multiple payment methods.
FAQs
Loading wrapper and TypeScript types for the PayPal JS SDK
The npm package @paypal/paypal-js receives a total of 183,688 weekly downloads. As such, @paypal/paypal-js popularity was classified as popular.
We found that @paypal/paypal-js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 27 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
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.