
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
@paypal/paypal-js
Advanced tools
@paypal/paypal-js is an npm package that provides a client-side JavaScript SDK for integrating PayPal's payment services into web applications. It allows developers to easily add PayPal buttons, handle transactions, and manage payment flows with minimal setup.
Load PayPal Script
This feature allows you to load the PayPal JavaScript SDK dynamically. You need to provide your PayPal client ID, and the script will be loaded asynchronously.
import { loadScript } from '@paypal/paypal-js';
loadScript({ 'client-id': 'your-client-id' }).then((paypal) => {
console.log('PayPal script loaded successfully');
}).catch((error) => {
console.error('Failed to load PayPal script', error);
});
Render PayPal Buttons
This feature allows you to render PayPal buttons on your web page. You can customize the button's behavior, such as creating an order and handling the approval process.
import { loadScript } from '@paypal/paypal-js';
loadScript({ 'client-id': 'your-client-id' }).then((paypal) => {
paypal.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [{
amount: {
value: '0.01'
}
}]
});
},
onApprove: (data, actions) => {
return actions.order.capture().then((details) => {
alert('Transaction completed by ' + details.payer.name.given_name);
});
}
}).render('#paypal-button-container');
});
Handle Payment Transactions
This feature allows you to handle payment transactions, including creating orders, capturing payments, and handling errors during the transaction process.
import { loadScript } from '@paypal/paypal-js';
loadScript({ 'client-id': 'your-client-id' }).then((paypal) => {
paypal.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [{
amount: {
value: '0.01'
}
}]
});
},
onApprove: (data, actions) => {
return actions.order.capture().then((details) => {
console.log('Transaction completed by ' + details.payer.name.given_name);
});
},
onError: (err) => {
console.error('An error occurred during the transaction', err);
}
}).render('#paypal-button-container');
});
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.
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,
});
FAQs
Loading wrapper and TypeScript types for the PayPal JS SDK
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 26 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.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.