@paypal/paypal-js

Client-side loader for the PayPal JS SDK

Usage no npm install needed!

<script type="module">
  import paypalPaypalJs from 'https://cdn.skypack.dev/@paypal/paypal-js';
</script>

README

paypal-js

A client-side loader for the PayPal JS SDK

build status code coverage npm version bundle size npm downloads apache license

Why use paypal-js?

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:

  • Async script loading to ensure page rendering isn't blocked.
  • A Promise API to know when script loading is complete.
  • A convenient way to reload the script when query parameters or data attributes change.

Installation

To get started, install paypal-js with npm.

npm install @paypal/paypal-js

Usage

Import the loadScript function for asynchronously loading the Paypal JS SDK.

loadScript(options)

  • accepts an object for passing query parameters and attributes to the JS SDK.
  • returns a Promise that resolves with window.paypal after the JS SDK is finished loading.

Async/Await

import { loadScript } from "@paypal/paypal-js";

let paypal;

try {
    paypal = await loadScript({ "client-id": "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);
    }
}

Promises

import { loadScript } from "@paypal/paypal-js";

loadScript({ "client-id": "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);
    });

Passing Arguments

The loadScript function accepts an object for configuring the JS SDK. It's used for setting query parameters and script attributes.

Query Parameters

The following example adds client-id and currency as query string parameters:

loadScript({ "client-id": "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&currency=EUR"></script>

View the full list of supported query parameters.

Data Attributes

All options prefixed with data- are considered attributes. The following example adds data-client-token as an attribute:

loadScript({
    "client-id": "YOUR_CLIENT_ID",
    "data-client-token": "abc123xyz==",
});

Which will load the following <script> asynchronously:

<script
    data-client-token="abc123xyz=="
    src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID"
></script>

View the full list of supported script parameters.

Merchant ID Array

The merchant-id 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 merchant-id values:

loadScript({
    "client-id": "YOUR_CLIENT_ID",
    "merchant-id": ["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({
    "client-id": "YOUR_CLIENT_ID",
    "merchant-id": ["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>

sdkBaseURL

For local development, the sdkBaseURL option can be used to set the base url of the JS SDK:

loadScript({
    "client-id": "YOUR_CLIENT_ID",
    sdkBaseURL: "http://localhost.paypal.com:8000/sdk/js",
});

Legacy Browser Support

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:

  1. Use a global polyfill strategy that monkey patches the window.Promise API implementation.
  2. Use a ponyfill strategy that passes a Promise library into 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@5.0.2/dist/iife/paypal-js.legacy.min.js"></script>

Using a CDN

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@5.0.2/dist/iife/paypal-js.min.js"></script>
    </head>
    <body>
        <div id="paypal-buttons"></div>
        <script>
            window.paypalLoadScript({ "client-id": "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.

  • accepts an object for defining the script url and attributes.
  • returns a promise to indicate if the script was successfully loaded.

Async/Await

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);
}

Promises

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);
    });

TypeScript Support

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.

Releasing

Run npm run release to publish a new release. The version number is determined by the git commits which follow conventional commits spec.