# Reference (/sdk/js/reference)

JavaScript SDK v6 Reference



Use the PayPal v6 JavaScript SDK to integrate PayPal, Venmo, Pay Later, and other payment methods into web applications. This reference covers payment eligibility checking, session management, callback handling, and web components.

> **Success:** * For the React JavaScript SDK v6 reference, see [React SDK v6
>   Reference](/sdk/react/reference). - For setup and initialization, see [Set up JavaScript
>   SDK v6](/sdk/js/set-up).

## Check payment eligibility [#check-payment-eligibility]

Before displaying payment buttons to your buyers, check which payment methods are available for the current transaction. Eligibility depends on various factors including the buyer's location, currency, merchant configuration, and transaction amount.

### `sdkInstance.findEligibleMethods(options?)` [#sdkinstancefindeligiblemethodsoptions]

Use `findEligibleMethods` to determine which payment methods are available for the current context. `findEligibleMethods` queries PayPal's eligibility service and returns an object with methods to check specific payment options.

#### Parameters [#parameters]

Parameter

Required

Description

currencyCode

no

string. The three-letter ISO 4217 currency code for
the transaction, for example, `"USD"`, `"EUR"`, or `"GBP"`. This
affects payment method availability, especially for Pay Later options
which have currency restrictions. Default: "USD"

countryCode

no

string. The two-letter ISO 3166-1 alpha-2 country
code representing the buyer's country. This determines regional
payment method availability. For example, Venmo is only available in
the US. If not specified, the SDK attempts to detect the buyer's
country.

amount

no

string. The transaction amount as a string, for
example, `"99.99"`. The amount affects Pay Later eligibility, as
different financing options have minimum and maximum amount
thresholds.

#### Returns [#returns]

`findEligibleMethods` returns a promise that resolves to an `EligiblePaymentMethods` object with methods to check and retrieve payment method information.

The returned object provides these methods:

* `isEligible(method)` - Check if a specific payment method is available
* `getDetails(method)` - Get additional information about a payment method

#### Example [#example]

Check payment method eligibility with default settings or specific transaction parameters, then use the results to conditionally display payment buttons.

```javascript
// Check with default settings
const paymentMethods = await sdkInstance.findEligibleMethods();

// Check with specific currency and amount
const paymentMethods = await sdkInstance.findEligibleMethods({
  currencyCode: "USD",
  countryCode: "US",
  amount: "125.00",
});

// Use the eligibility results
if (paymentMethods.isEligible("paypal")) {
  // Show PayPal button
}

if (paymentMethods.isEligible("paylater")) {
  const details = paymentMethods.getDetails("paylater");
  // Show Pay Later button with product-specific messaging
}
```

### `paymentMethods.isEligible(method)` [#paymentmethodsiseligiblemethod]

Check whether a specific payment method is available for the current transaction.

#### Parameters [#parameters-1]

Parameter

Required

Description

method

yes

string. The payment method identifier to check.

Supported values:

paypal — PayPal Checkout

venmo — Venmo (US only)

paylater — Pay Later / Pay in 4

credit — PayPal Credit

#### Returns [#returns-1]

`isEligible` returns `true` if the payment method is available, or `false` otherwise.

#### Example [#example-1]

Check individual payment methods and conditionally show their buttons based on availability.

```javascript
// Check individual payment methods
const canUsePayPal = paymentMethods.isEligible("paypal");
const canUseVenmo = paymentMethods.isEligible("venmo");

// Conditionally show buttons
if (paymentMethods.isEligible("venmo")) {
  document.getElementById("venmo-button").style.display = "block";
}
```

### `paymentMethods.getDetails(method)` [#paymentmethodsgetdetailsmethod]

Retrieve additional configuration details for a specific payment method. This is particularly useful for Pay Later and PayPal Credit, which require additional attributes for proper button rendering.

#### Parameters [#parameters-2]

Parameter

Required

Description

method

yes

string. The payment method to get details for.

Currently returns details for:

paylater — Returns product code and country

credit — Returns country configuration

#### Returns [#returns-2]

`getDetails` returns an object with payment method-specific details. The structure varies by payment method.

For Pay Later:

```javascript
{
  productCode: string; // Example: "PAY_IN_4"
  countryCode: string; // Example: "US"
}
```

For PayPal Credit:

```javascript
{
  countryCode: string; // Example: "US"
}
```

#### Example [#example-2]

Retrieve Pay Later product details and use them to configure the button component.

```javascript
// Get Pay Later configuration
const payLaterDetails = paymentMethods.getDetails("paylater");
const button = document.querySelector("paylater-button");
button.productCode = payLaterDetails.productCode;
button.countryCode = payLaterDetails.countryCode;

// Get PayPal Credit configuration
const creditDetails = paymentMethods.getDetails("credit");
```

## Creating payment sessions [#creating-payment-sessions]

Payment sessions manage the complete payment flow from initiation through completion. Each payment method has its own session creation method that returns a session object with methods to start and control the payment process.

### `sdkInstance.createPayPalOneTimePaymentSession(options)` [#sdkinstancecreatepaypalonetimepaymentsessionoptions]

Create a payment session for one-time PayPal payments. This session handles the complete PayPal Checkout flow, including payment approval, shipping address changes, and order updates.

#### Parameters [#parameters-3]

The options object configures callbacks that handle different stages of the payment flow. These callbacks allow you to respond to buyer actions and update your order accordingly.

Parameter

Required

Description

onApprove

yes

function(data). Called when the buyer approves the
payment in the PayPal flow. This is where you should
[capture](/api/orders/v2/orders-capture) or
[authorize](/api/orders/v2/orders-authorize) the payment on your
server.

The function receives a data object containing:

orderId — The PayPal order ID to capture

payerId — The buyer's PayPal payer ID

This function can return a promise if you need to perform async
operations like capturing the payment.

onCancel

no

function(data). Called when the buyer cancels the
payment flow by closing the PayPal window or selecting cancel.

The data object contains:

orderId — The order ID (if one was created)

Use this callback to:

Track abandoned checkouts

Re-enable your checkout button

Show a message to the buyer

onError

no

function(error). Called when an error occurs during
the payment flow. This includes network errors, validation errors, or
payment failures.

The error object contains:

code — Error code for identifying the issue

message — Human-readable error description

Use this to display user-friendly error messages and log errors for
debugging.

onShippingAddressChange

no

function(data). Called when the buyer changes their
shipping address within the PayPal flow. This allows you to update
shipping costs or restrict certain addresses.

The data object contains:

errors — Errors to show to the user

orderId — The current order ID

shippingAddress — The new address object

Return a promise to update the order with new shipping costs. If you
reject the promise, the address change will be rejected.

onShippingOptionsChange

no

function(data). Called when the buyer selects a
different shipping option, for example, standard or express shipping.

The data object contains:

errors — Errors to show to the user

orderId — The current order ID

selectedShippingOption — The selected option details

Return a promise to update the order total with the new shipping cost.

orderId

no

string. An existing PayPal order ID to use for this
session. This allows you to [create the
order](/api/orders/v2/orders-create) on your server before starting
the payment flow (eager order creation).

If not provided, you'll pass an order creation function to the{" "}
start() method.

commit

no

boolean. Controls the final button text in the PayPal
flow:

true — Shows "Pay Now" (payment happens immediately)

false — Shows "Continue" (additional confirmation step)

Default: true

savePayment

no

boolean. Saves the customer's payment method during
purchase. Set to true if your [Orders
API](/api/orders/v2/orders-create) request saves the payment method
using [payment tokens](/api/payment-tokens/v3/payment-tokens-create).

#### Returns [#returns-3]

`createPayPalOneTimePaymentSession` returns a `PaymentSession` object with methods to control the payment flow.

```javascript
interface PaymentSession {
  start(options?: StartOptions, orderPromise: Promise): Promise<void>;
  hasReturned(): boolean;
  resume(): Promise<void>;
}
```

#### Example [#example-3]

Create a PayPal payment session with handlers for approval, shipping changes, cancellation, and errors.

```javascript
const paypalSession = sdkInstance.createPayPalOneTimePaymentSession({
  onApprove: async (data) => {
    // Capture the payment on your server
    const response = await fetch(`/api/orders/${data.orderId}/capture`, {
      method: "POST",
    });

    if (response.ok) {
      // Payment successful
      window.location.href = "/order/complete";
    } else {
      throw new Error("Capture failed");
    }
  },

  onShippingAddressChange: async (data) => {
    // Calculate new shipping cost based on address
    const shippingCost = await calculateShipping(data.shippingAddress);

    // Update the order with new shipping
    return fetch(`/api/orders/${data.orderId}/update-shipping`, {
      method: "PATCH",
      body: JSON.stringify({ shippingCost }),
    });
  },

  onCancel: (data) => {
    console.log("Payment cancelled", data);
    // Re-enable checkout button
    document.getElementById("checkout-btn").disabled = false;
  },

  onError: (error) => {
    console.error("Payment error:", error);
    // Show error message to buyer
    showErrorMessage("Payment failed. Please try again.");
  },
});
```

### `sdkInstance.createPayPalSavePaymentSession(options)` [#sdkinstancecreatepaypalsavepaymentsessionoptions]

Create a session for saving PayPal as a payment method for future use ([vaulting](/api/payment-tokens/v3/payment-tokens-create)). This allows buyers to save their PayPal account for faster checkout in future purchases.

The parameters and usage are identical to `createPayPalOneTimePaymentSession`, except the `onApprove` callback receives a `billingToken` instead of requiring immediate payment capture.

#### Example [#example-4]

Save the buyer's PayPal account as a payment method for future purchases.

```javascript
const saveSession = sdkInstance.createPayPalSavePaymentSession({
  onApprove: async (data) => {
    // Save the billing token to your customer's profile
    await savePaymentMethod({
      customerId: currentUser.id,
      billingToken: data.billingToken,
      type: "paypal",
    });

    showSuccess("PayPal saved for future purchases");
  },
});
```

### `sdkInstance.createVenmoOneTimePaymentSession(options)` [#sdkinstancecreatevenmoonetimepaymentsessionoptions]

Create a payment session for Venmo payments (US only). Venmo provides a mobile-optimized payment experience for US buyers using their Venmo balance or linked payment methods.

The parameters are identical to `createPayPalOneTimePaymentSession`. Venmo sessions support the same callbacks and flow options.

#### Example [#example-5]

Create a Venmo payment session and capture the payment on approval.

```javascript
const venmoSession = sdkInstance.createVenmoOneTimePaymentSession({
  onApprove: async (data) => {
    // Capture the Venmo payment
    await captureOrder(data.orderId);
  },
});
```

### `sdkInstance.createPayLaterOneTimePaymentSession(options)` [#sdkinstancecreatepaylateronetimepaymentsessionoptions]

Create a session for Pay Later financing options. Pay Later allows buyers to pay in installments (like Pay in 4) or over time with longer-term financing.

The parameters are identical to `createPayPalOneTimePaymentSession`. Pay Later availability depends on transaction amount and buyer eligibility.

#### Example [#example-6]

Create a Pay Later session and configure the button with product-specific details from eligibility results.

```javascript
const payLaterSession = sdkInstance.createPayLaterOneTimePaymentSession({
  onApprove: async (data) => {
    await captureOrder(data.orderId);
    // Buyer has been approved for Pay Later financing
  },
});

// Configure the Pay Later button with product details
const details = paymentMethods.getDetails("paylater");
const button = document.querySelector("paylater-button");
button.productCode = details.productCode;
button.countryCode = details.countryCode;
```

### `sdkInstance.createPayPalCreditOneTimePaymentSession(options)` [#sdkinstancecreatepaypalcreditonetimepaymentsessionoptions]

Create a session for PayPal Credit payments (US only). PayPal Credit offers buyers a reusable line of credit for purchases.

### `sdkInstance.createPayPalSubscriptionSession(options)` [#sdkinstancecreatepaypalsubscriptionsessionoptions]

Create a payment session for PayPal subscription payments. Use subscriptions when buyers need recurring billing — for example, membership fees, software licenses, or regular service plans.

> **Info:** Before creating a subscription session, [create a subscription
> plan](/api/subscriptions/v1/plans-create) using the Subscriptions API. You'll
> [create a subscription](/api/subscriptions/v1/subscriptions-create) for the
> buyer using this Plan ID when the buyer initiates checkout.

#### Parameters [#parameters-4]

Parameter

Required

Description

onApprove

yes

function(data) — Called when the buyer approves the
subscription. The data object includes:

subscriptionId — The approved PayPal subscription ID.
Use this to activate or retrieve subscription details on your
server.

payerId — The buyer's PayPal payer ID.

onCancel

no

function(data) — Called when the buyer cancels the
subscription flow. The data object contains{" "}
subscriptionId if a subscription was created.

onError

no

function(error) — Called when an error occurs during
the subscription flow. The error object contains code and{" "}
message.

#### Returns [#returns-4]

`createPayPalSubscriptionSession` returns a subscription session object with a `start(options?, subscriptionPromise)` method. The `subscriptionPromise` must resolve to `{ subscriptionId: string }` containing your PayPal subscription ID.

#### Example [#example-7]

Create a subscription session, handle approval with server-side activation, and start the flow when the buyer clicks the subscribe button.

```javascript
const subscriptionSession = sdkInstance.createPayPalSubscriptionSession({
  onApprove: async (data) => {
    console.log("Subscription approved:", data.subscriptionId);

    // Record the subscription on your server
    await fetch("/api/subscriptions/activate", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ subscriptionId: data.subscriptionId }),
    });

    window.location.href = "/subscription/success";
  },

  onCancel: (data) => {
    console.log("Subscription cancelled");
    document.getElementById("subscribe-button").disabled = false;
  },

  onError: (error) => {
    console.error("Subscription error:", error.code, error.message);
  },
});

document.getElementById("subscribe-button").addEventListener("click", () => {
  subscriptionSession.start(
    { presentationMode: "auto" },
    Promise.resolve({ subscriptionId: "YOUR_SUBSCRIPTION_ID" }),
  );
});
```

### `sdkInstance.createGooglePayOneTimePaymentSession()` [#sdkinstancecreategooglepayonetimepaymentsession]

Create a session for Google Pay payments. The Google Pay session integrates with the [Google Pay API](https://developers.google.com/pay/api/web/guides/tutorial) and handles PayPal order confirmation.

> **Info:** Google Pay requires the `googlepay-payments` component and the [Google Pay
> JavaScript SDK](https://pay.google.com/gp/p/js/pay.js). Load both before
> calling `createGooglePayOneTimePaymentSession`. Enable Google Pay in your
> PayPal sandbox and production account settings before going live.

#### Returns [#returns-5]

`createGooglePayOneTimePaymentSession` synchronously returns a `GooglePaySession` object with these methods:

#### `googlePaySession.formatConfigForPaymentRequest(config)` [#googlepaysessionformatconfigforpaymentrequestconfig]

Format the Google Pay configuration for the Google Pay API. Before calling `formatConfigForPaymentRequest`, use `sdkInstance.findEligibleMethods()` to check eligibility and retrieve the raw configuration, then pass the `.config` property from `paymentMethods.getDetails("googlepay")`:

```javascript
const paymentMethods = await sdkInstance.findEligibleMethods({
  currencyCode: "USD",
});
const googlePayPaymentMethodDetails = paymentMethods.getDetails("googlepay");
const googlePayConfig = googlePaySession.formatConfigForPaymentRequest(
  googlePayPaymentMethodDetails.config,
);
```

##### Parameters [#parameters-5]

| Parameter | Required | Description                                                                      |
| :-------- | :------- | :------------------------------------------------------------------------------- |
| `config`  | yes      | **object.** The `config` property from `paymentMethods.getDetails("googlepay")`. |

##### Returns [#returns-6]

`formatConfigForPaymentRequest` returns a formatted configuration object:

| Property                | Type   | Description                                         |
| :---------------------- | :----- | :-------------------------------------------------- |
| `allowedPaymentMethods` | array  | Payment method configuration for the Google Pay API |
| `merchantInfo`          | object | PayPal merchant information for Google Pay          |
| `apiVersion`            | number | Google Pay API version                              |
| `apiVersionMinor`       | number | Google Pay API minor version                        |
| `countryCode`           | string | Two-letter ISO 3166-1 country code                  |

#### `googlePaySession.confirmOrder(options)` [#googlepaysessionconfirmorderoptions]

Use the payment data from Google Pay to confirm the PayPal order. Call this inside the `onPaymentAuthorized` callback.

##### Parameters [#parameters-6]

| Parameter           | Required | Description                                                                                                       |
| :------------------ | :------- | :---------------------------------------------------------------------------------------------------------------- |
| `orderId`           | yes      | **string.** The PayPal order ID created on your server.                                                           |
| `paymentMethodData` | yes      | **object.** The payment method data from the Google Pay authorization response (`paymentData.paymentMethodData`). |

##### Returns [#returns-7]

`confirmOrder` returns a promise that resolves to `{ status }`:

| Status                  | Description                                       |
| :---------------------- | :------------------------------------------------ |
| `APPROVED`              | Order confirmed and ready to capture.             |
| `PAYER_ACTION_REQUIRED` | 3D Secure authentication required before capture. |

#### Example [#example-8]

Set up a complete Google Pay integration, from eligibility checking and configuration through payment authorization and order confirmation.

```javascript
const sdkInstance = await window.paypal.createInstance({
  clientId: "YOUR_CLIENT_ID",
  components: ["googlepay-payments"],
  pageType: "checkout",
});

// Check eligibility before setting up Google Pay
const paymentMethods = await sdkInstance.findEligibleMethods({
  currencyCode: "USD",
});

if (paymentMethods.isEligible("googlepay")) {
  const googlePayPaymentMethodDetails = paymentMethods.getDetails("googlepay");

  // Create Google Pay session and format config
  const googlePaySession = sdkInstance.createGooglePayOneTimePaymentSession();
  const googlePayConfig = googlePaySession.formatConfigForPaymentRequest(
    googlePayPaymentMethodDetails.config,
  );

  // Initialize Google Pay client
  const paymentsClient = new google.payments.api.PaymentsClient({
    environment: "TEST", // Use "PRODUCTION" for live transactions
    paymentDataCallbacks: {
      onPaymentAuthorized: async (paymentData) => {
        try {
          const orderId = await createOrder();

          const { status } = await googlePaySession.confirmOrder({
            orderId,
            paymentMethodData: paymentData.paymentMethodData,
          });

          if (status !== "PAYER_ACTION_REQUIRED") {
            await captureOrder(orderId);
          }

          return { transactionState: "SUCCESS" };
        } catch (err) {
          return {
            transactionState: "ERROR",
            error: { message: err.message },
          };
        }
      },
    },
  });

  // Check readiness and render button
  const { result } = await paymentsClient.isReadyToPay({
    allowedPaymentMethods: googlePayConfig.allowedPaymentMethods,
    apiVersion: googlePayConfig.apiVersion,
    apiVersionMinor: googlePayConfig.apiVersionMinor,
  });

  if (result) {
    const button = paymentsClient.createButton({
      onClick: () => {
        paymentsClient.loadPaymentData({
          ...googlePayConfig,
          transactionInfo: {
            countryCode: googlePayConfig.countryCode,
            currencyCode: "USD",
            totalPriceStatus: "FINAL",
            totalPrice: "10.00",
          },
          callbackIntents: ["PAYMENT_AUTHORIZATION"],
        });
      },
    });
    document.getElementById("google-pay-container").appendChild(button);
  }
}
```

### `sdkInstance.createApplePayOneTimePaymentSession()` [#sdkinstancecreateapplepayonetimepaymentsession]

Create a session for Apple Pay payments. The Apple Pay session integrates with the browser's native `ApplePaySession` API and handles merchant validation and order confirmation.

> **Info:** Apple Pay requires: - The `applepay-payments` component - The [Apple Pay
> JavaScript SDK](https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js) - An
> HTTPS connection - A merchant domain registration with PayPal Apple Pay is
> available in Safari on Apple devices only.

#### Returns [#returns-8]

`createApplePayOneTimePaymentSession` returns a promise that resolves to an Apple Pay session object with these methods:

#### `applePaySession.config()` [#applepaysessionconfig]

Fetch the Apple Pay merchant configuration from PayPal.

##### Returns [#returns-9]

`config` returns a promise that resolves to:

| Property               | Type      | Description                                                                             |
| :--------------------- | :-------- | :-------------------------------------------------------------------------------------- |
| `merchantCapabilities` | string\[] | Merchant capabilities for the Apple Pay payment request, for example, `["supports3DS"]` |
| `supportedNetworks`    | string\[] | Card networks the merchant accepts, for example, `["visa", "masterCard", "amex"]`       |

#### `applePaySession.validateMerchant(options)` [#applepaysessionvalidatemerchantoptions]

Complete Apple Pay merchant validation. Call this inside the `onvalidatemerchant` event handler of the browser's `ApplePaySession`.

##### Parameters [#parameters-7]

| Parameter       | Required | Description                                                                                 |
| :-------------- | :------- | :------------------------------------------------------------------------------------------ |
| `validationUrl` | yes      | **string.** The validation URL from the `onvalidatemerchant` event (`event.validationURL`). |

##### Returns [#returns-10]

`validateMerchant` returns a promise that resolves to `{ merchantSession }`. Pass `merchantSession` to `applePaySession.completeMerchantValidation()`.

#### `applePaySession.confirmOrder(options)` [#applepaysessionconfirmorderoptions]

Confirm the PayPal order using the payment token from Apple Pay. Call this inside the `onpaymentauthorized` event handler.

##### Parameters [#parameters-8]

| Parameter         | Required | Description                                                                    |
| :---------------- | :------- | :----------------------------------------------------------------------------- |
| `orderId`         | yes      | **string.** The PayPal order ID created on your server.                        |
| `token`           | yes      | **object.** The Apple Pay payment token from `event.payment.token`.            |
| `billingContact`  | no       | **object.** The buyer's billing contact from `event.payment.billingContact`.   |
| `shippingContact` | no       | **object.** The buyer's shipping contact from `event.payment.shippingContact`. |

#### Payment request structure [#payment-request-structure]

Build an `ApplePayPaymentRequest` to pass to the browser's `new ApplePaySession()`:

| Property                        | Description                                                                            |
| :------------------------------ | :------------------------------------------------------------------------------------- |
| `countryCode`                   | Merchant country code, for example, `"US"`                                             |
| `currencyCode`                  | Transaction currency code, for example, `"USD"`                                        |
| `merchantCapabilities`          | From `applePaySession.config()`                                                        |
| `supportedNetworks`             | From `applePaySession.config()`                                                        |
| `requiredBillingContactFields`  | Array of required billing fields: `"name"`, `"phone"`, `"email"`, `"postalAddress"`    |
| `requiredShippingContactFields` | Array of required shipping fields, or empty array if no shipping needed                |
| `total`                         | Object with `label` (string), `amount` (string), and `type` (`"final"` or `"pending"`) |

#### Example [#example-9]

Set up a complete Apple Pay integration, including eligibility checking, merchant validation, payment authorization, and order confirmation.

```javascript
const sdkInstance = await window.paypal.createInstance({
  clientId: "YOUR_CLIENT_ID",
  components: ["applepay-payments"],
  pageType: "checkout",
});

// Create Apple Pay session
const paypalApplePaySession = sdkInstance.createApplePayOneTimePaymentSession();

// Get merchant configuration
    const paymentMethods = await sdkInstance.findEligibleMethods({
      currencyCode: "USD",
    });

    if (paymentMethods.isEligible("applepay")) {
      const applePayPaymentMethodDetails =
        paymentMethods.getDetails("applepay");
      setupApplePayButton(sdkInstance, applePayPaymentMethodDetails);

// Display Apple Pay button
document.getElementById("apple-pay-container").innerHTML =
  '<apple-pay-button buttonstyle="black" type="buy" locale="en"></apple-pay-button>';

document.querySelector("apple-pay-button").addEventListener("click", async () => {
  const paymentRequest = {
    countryCode: "US",
    currencyCode: "USD",
    merchantCapabilities,
    supportedNetworks,
    requiredBillingContactFields: ["name", "postalAddress"],
    requiredShippingContactFields: [],
    total: {
      label: "Your Store",
      amount: "25.00",
      type: "final",
    },
  };

  const applePaySession = new ApplePaySession(4, paymentRequest);

  applePaySession.onvalidatemerchant = async (event) => {
    try {
      const { merchantSession } = await paypalApplePaySession.validateMerchant({
        validationUrl: event.validationURL,
      });
      applePaySession.completeMerchantValidation(merchantSession);
    } catch (err) {
      console.error("Merchant validation failed:", err);
      applePaySession.abort();
    }
  };

  applePaySession.onpaymentauthorized = async (event) => {
    try {
      const orderId = await createOrder();

      await paypalApplePaySession.confirmOrder({
        orderId,
        token: event.payment.token,
        billingContact: event.payment.billingContact,
        shippingContact: event.payment.shippingContact,
      });

      await captureOrder(orderId);

      applePaySession.completePayment({
        status: ApplePaySession.STATUS_SUCCESS,
      });
    } catch (err) {
      console.error("Payment failed:", err);
      applePaySession.completePayment({
        status: ApplePaySession.STATUS_FAILURE,
      });
    }
  };

  applePaySession.oncancel = () => {
    console.log("Apple Pay cancelled");
  };

  applePaySession.begin();
});
```

### `sdkInstance.createFastlane()` [#sdkinstancecreatefastlane]

Create a Fastlane instance for accelerated guest checkout. Fastlane enables one-click checkout for recognized guests.

#### Returns [#returns-11]

`createFastlane` returns a promise that resolves to a Fastlane instance.

#### Example [#example-10]

Initialize a Fastlane instance for accelerated guest checkout.

```javascript
const fastlane = await sdkInstance.createFastlane();
// Use fastlane instance for guest checkout acceleration
```

### `sdkInstance.createPayPalMessages(options?)` [#sdkinstancecreatepaypalmessagesoptions]

Display PayPal Messages to show financing options and promotional messaging to buyers. These messages dynamically update based on the transaction amount and buyer eligibility.

#### Parameters [#parameters-9]

Parameter

Required

Description

amount

no

number. The product or cart amount to display
messaging for. Messages update dynamically based on this amount.

placement

no

string. The page placement context for the messages.
This affects message format and content.

Values: product, cart, checkout

style

no

object. Visual styling options for the messages,
including layout and logo configuration.

#### Returns [#returns-12]

`createPayPalMessages` returns a `PayPalMessagesInstance` object with `fetchContent(options?)` and `createLearnMore(options?)` methods.

#### `messagesInstance.fetchContent(options?)` [#messagesinstancefetchcontentoptions]

Fetch message content from PayPal and render it in all `<paypal-messages>` components on the page.

| Option            | Required | Description                                                                                                                                                                     |
| :---------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `amount`          | no       | **string.** Transaction amount with up to 2 decimal places, for example, `"125.00"`. Affects which financing offers are displayed.                                              |
| `currencyCode`    | no       | **string.** Three-letter ISO 4217 currency code, for example, `"USD"`.                                                                                                          |
| `logoPosition`    | no       | **string.** Where to place the PayPal logo. Values: `LEFT` (default), `RIGHT`, `TOP`, `INLINE`. Note: `MONOGRAM` logo type requires `LEFT`; `TEXT` logo type requires `INLINE`. |
| `logoType`        | no       | **string.** PayPal branding style. Values: `WORDMARK` (default), `MONOGRAM`, `TEXT`.                                                                                            |
| `textColor`       | no       | **string.** Message text color. Values: `BLACK` (default), `WHITE`, `MONOCHROME`.                                                                                               |
| `onContentReady`  | no       | **function.** Called when content arrives from the server. Takes precedence over `onReady`.                                                                                     |
| `onTemplateReady` | no       | **function.** Called when content is served from local cache. Takes precedence over `onReady`.                                                                                  |
| `onReady`         | no       | **function.** Called when content is ready from either cache or server. Used when neither `onContentReady` nor `onTemplateReady` is specified.                                  |

#### `messagesInstance.createLearnMore(options?)` [#messagesinstancecreatelearnmoreoptions]

Initialize a Learn more presentation that provides additional financing details when buyers select the Learn more link in a message.

| Option             | Required | Description                                                                                              |
| :----------------- | :------- | :------------------------------------------------------------------------------------------------------- |
| `amount`           | no       | **string.** The transaction amount to display in the Learn more presentation.                            |
| `presentationMode` | no       | **string.** How the Learn more content is shown. Values: `AUTO` (default), `MODAL`, `POPUP`, `REDIRECT`. |
| `onApply`          | no       | **function.** Called when the buyer selects Apply in the Learn more presentation.                        |
| `onCalculate`      | no       | **function.** Called when the buyer enters a value in the amount input field.                            |
| `onShow`           | no       | **function.** Called when the Learn more presentation opens.                                             |
| `onClose`          | no       | **function.** Called when the Learn more presentation closes.                                            |

#### CSS custom properties [#css-custom-properties]

Customize message appearance using these CSS properties on the `<paypal-messages>` element:

| Property                      | Description                                        | Default |
| :---------------------------- | :------------------------------------------------- | :------ |
| `--paypal-message-font-size`  | Font size in `px`, clamped to `10px`–`16px`.       | `14px`  |
| `--paypal-message-text-align` | Text alignment. Values: `left`, `right`, `center`. | `left`  |

#### Example [#example-11]

Initialize the SDK with the messages component, render financing messages with styling options, and set up a Learn More modal.

```javascript
const sdkInstance = await window.paypal.createInstance({
  clientId: "YOUR_CLIENT_ID",
  components: ["paypal-messages"],
});

const messagesInstance = sdkInstance.createPayPalMessages();

// Render message with style options
messagesInstance.fetchContent({
  amount: "199.99",
  currencyCode: "USD",
  logoPosition: "LEFT",
  logoType: "WORDMARK",
  textColor: "BLACK",
  onContentReady: () => {
    document.getElementById("paypal-message-container").style.display = "block";
  },
});

// Optional: create a Learn More presentation
const learnMore = messagesInstance.createLearnMore({
  amount: "199.99",
  presentationMode: "MODAL",
  onShow: () => console.log("Learn more opened"),
  onClose: () => console.log("Learn more closed"),
});
```

Add the `<paypal-messages>` web component to your HTML and customize its appearance with CSS custom properties.

```html
<!-- PayPal Messages web component with CSS custom properties -->
<paypal-messages
  style="--paypal-message-font-size: 14px; --paypal-message-text-align: left;"
></paypal-messages>
```

### `paymentSession.start(options?, orderPromise)` [#paymentsessionstartoptions-orderpromise]

Start the payment user experience. `start` opens the payment interface using the specified presentation mode and begins the checkout flow.

#### Parameters [#parameters-10]

Parameter

Required

Description

options

no

object. Configuration for how the payment UI is
presented.

options.presentationMode

no

string. Controls how the payment interface is
displayed to the buyer.

Available modes:

auto — Recommended. SDK automatically selects the best
experience. Tries popup first and falls back to modal if popups are
blocked.

popup — Opens PayPal in a popup window. May be blocked
by popup blockers.

modal — Creates an iframe overlay on the current page.
Recommended only for WebView scenarios. Do not use in desktop web
scenarios as this integration has limitations on cookies, which can
affect user authentication.

redirect — Full page redirect to PayPal. Recommended
for mobile devices. Requires a return/cancel URL.

payment-handler — Experimental. Uses the browser's
Payment Handler API. Provides a native payment experience. Modern
browsers only.{" "}

Default: auto

The SDK will automatically fall back to alternative modes if the
requested mode is unavailable.

options.autoRedirect

no

object. Configuration for redirect mode behavior.

enabled (boolean) — Whether to automatically redirect
or return the URL

Only applies when using presentationMode: "redirect".

options.fullPageOverlay

no

object. Controls the background overlay when using
popup mode.

enabled (boolean) — Show/hide the page overlay

Default: enabled: true

options.loadingScreen

no

object. Customize the loading screen text.

label (string) — Currently only supports "connecting"

orderPromise

yes

promise. A promise that creates or retrieves the
PayPal order. This promise should resolve to an object containing the{" "}
orderId.

The order creation can happen asynchronously while the payment UI is
loading, improving perceived performance.

#### Returns [#returns-13]

For most presentation modes, `start` returns a promise that resolves when the payment flow completes or is cancelled.

For redirect mode with `autoRedirect.enabled: false`, `start` returns the redirect URL:

```javascript
Promise<{ redirectURL: string }>
```

#### Example [#example-12]

Start the payment flow using different presentation modes, including auto mode, redirect with manual URL handling, and a fallback pattern for incompatible browsers.

```javascript
// Basic usage with auto mode
await paymentSession.start(
  { presentationMode: "auto" },
  createOrder(), // Returns Promise<{orderId: string}>
);

// Redirect mode with manual handling
const { redirectURL } = await paymentSession.start(
  {
    presentationMode: "redirect",
    autoRedirect: { enabled: false },
  },
  createOrder(),
);

if (redirectURL) {
  // Manually redirect the buyer to a new tab
  // Only recommended for use cases where the v6 SDK is being wrapped in an iframe
  // Or usage with redirect flow for webview use cases
  window.location.href = redirectURL;
}

// Fallback pattern for incompatible browsers
const modes = [
  { mode: "popup", errorCode: "ERR_DEV_UNABLE_TO_OPEN_POPUP" },
  { mode: "modal", errorCode: null },
];

for (const { mode, errorCode } of modes) {
  try {
    await paymentSession.start({ presentationMode: mode }, createOrder());
    break; // Success
  } catch (error) {
    if (errorCode && error.code === errorCode) {
      continue; // Try next mode
    }
    throw error; // Unexpected error
  }
}
```

### `paymentSession.hasReturned()` [#paymentsessionhasreturned]

Check if the current page load is a return from a redirect payment flow. Use `hasReturned` on page load to detect and resume interrupted payment sessions.

#### Returns [#returns-14]

`hasReturned` returns `true` if the buyer is returning from a PayPal redirect, or `false` otherwise.

#### Example [#example-13]

Detect whether the buyer is returning from a redirect flow, and resume the payment session to trigger the original callbacks.

```javascript
// Runs on page load when SDK has finished downloading
async function onPayPalWebSdkLoaded() {
  try {
    const sdkInstance = await window.paypal.createInstance({
      clientId: "YOUR_CLIENT_ID",
      components: ["paypal-payments"],
      pageType: "checkout",
    });
    const paypalPaymentSession = sdkInstance.createPayPalOneTimePaymentSession(
      paymentSessionOptions,
    );
    // Check to see if Buyer is returning from PayPal
    if (paypalPaymentSession.hasReturned()) {
      // Original callbacks will be triggered
      await paypalPaymentSession.resume();
    } else {
      configurePayPalButton(paypalPaymentSession);
    }
  } catch (error) {
    console.error(error);
  }
}
```

### `paymentSession.resume()` [#paymentsessionresume]

Resume a payment session after returning from a redirect flow. `resume` continues the payment process and triggers the appropriate callbacks based on the payment outcome.

#### Returns [#returns-15]

`resume` returns a promise that resolves when the session is successfully resumed.

## Handling callbacks [#handling-callbacks]

Callbacks allow you to respond to events during the payment flow. Each callback receives specific data about the event and can optionally return a promise to perform asynchronous operations.

### `onApprove(data)` [#onapprovedata]

The SDK calls this function when the buyer successfully approves the payment. This is where you should [capture](/api/orders/v2/orders-capture) or [authorize](/api/orders/v2/orders-authorize) the payment on your server.

#### Parameters [#parameters-11]

The callback receives a data object with the following properties:

| Property       | Type                | Description                                                                                                             |
| :------------- | :------------------ | :---------------------------------------------------------------------------------------------------------------------- |
| `orderId`      | string              | The PayPal order ID that was approved. Use this to [capture](/api/orders/v2/orders-capture) the payment on your server. |
| `payerId`      | string              | The buyer's PayPal payer ID. This identifies the PayPal account used for payment.                                       |
| `paymentId`    | string \| undefined | Legacy payment ID for backwards compatibility. Only present in certain flows.                                           |
| `billingToken` | string \| undefined | Token for saving payment method. Only present when using save payment sessions.                                         |

#### Return value [#return-value]

The callback can optionally return a promise. If a promise is returned, the SDK waits for it to resolve before completing the flow.

#### Example [#example-14]

Capture the approved payment on your server and redirect the buyer to a success page.

```javascript
onApprove: async (data) => {
  console.log("Payment approved for order:", data.orderId);

  // Capture the payment on your server
  const response = await fetch(`/api/orders/${data.orderId}/capture`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
  });

  const captureData = await response.json();

  if (captureData.status === "COMPLETED") {
    // Redirect to success page
    window.location.href = `/order/success?id=${data.orderId}`;
  } else {
    throw new Error("Payment capture failed");
  }
};
```

### `onCancel(data)` [#oncanceldata]

The SDK calls this function when the buyer cancels the payment without completing it. This typically happens when the buyer closes the PayPal window or selects a cancel button.

#### Parameters [#parameters-12]

| Property  | Type                | Description                                                                                               |
| :-------- | :------------------ | :-------------------------------------------------------------------------------------------------------- |
| `orderId` | string \| undefined | The order ID if one was created before cancellation. May be undefined if cancelled before order creation. |

#### Example [#example-15]

Track the abandoned checkout, notify the buyer, and re-enable the checkout button.

```javascript
onCancel: (data) => {
  console.log("Payment cancelled", data);

  // Use your own analytics to track cancellation
  // Always ensure this is a non-blocking call
  analytics.track("checkout_abandoned", {
    orderId: data.orderId,
    timestamp: Date.now(),
  });

  // Show a message to the buyer
  showMessage("Your payment was cancelled. Your cart items are still saved.");

  // Re-enable the checkout button
  document.getElementById("checkout-button").disabled = false;
};
```

### `onError(error)` [#onerrorerror]

The SDK calls this function when an error occurs during the payment flow. This includes network errors, validation failures, and payment processing errors.

#### Parameters [#parameters-13]

The callback receives an error object with these properties:

| Property  | Type   | Description                                                                                     |
| --------- | ------ | ----------------------------------------------------------------------------------------------- |
| `code`    | string | A specific error code identifying the type of error. Use this for programmatic error handling.  |
| `message` | string | A human-readable error description. This may contain technical details not suitable for buyers. |

#### Common error codes [#common-error-codes]

| Code                                            | Description                        | Recommended action                    |
| :---------------------------------------------- | :--------------------------------- | :------------------------------------ |
| `ERR_INVALID_CLIENT_TOKEN`                      | Client token is invalid or expired | Generate a new token and reinitialize |
| `ERR_DOMAIN_MISMATCH`                           | Current domain doesn't match token | Verify domain configuration           |
| `ERR_DEV_UNABLE_TO_OPEN_POPUP`                  | Popup was blocked by browser       | Fall back to modal or redirect mode   |
| `ERR_FLOW_PAYMENT_HANDLER_BROWSER_INCOMPATIBLE` | Payment handler not supported      | Use traditional checkout flow         |
| `INSTRUMENT_DECLINED`                           | Payment method was declined        | Suggest alternative payment method    |
| `NETWORK_ERROR`                                 | Network request failed             | Retry or check connection             |

#### Example [#example-16]

Handle different error types with user-friendly messages and appropriate recovery actions.

```javascript
onError: (error) => {
  console.error("Payment error:", error);

  // Log to error tracking service
  errorReporter.log(error);

  // Show user-friendly message based on error code
  let message;
  switch (error.code) {
    case "ERR_INVALID_CLIENT_TOKEN":
      message = "Your session has expired. Please refresh and try again.";
      setTimeout(() => location.reload(), 3000);
      break;
    case "INSTRUMENT_DECLINED":
      message =
        "Your payment was declined. Please try a different payment method.";
      break;
    case "NETWORK_ERROR":
      message = "Connection lost. Please check your internet and try again.";
      break;
    default:
      message = "Something went wrong. Please try again.";
  }

  showErrorMessage(message);
};
```

### `onShippingAddressChange(data)` [#onshippingaddresschangedata]

The SDK calls this function when the buyer selects or changes their shipping address within the PayPal flow. Use this callback to [update](/api/orders/v2/orders-patch) shipping costs, validate addresses, or apply location-based restrictions.

#### Data properties [#data-properties]

| Property                      | Type   | Description                                                   |
| :---------------------------- | :----- | :------------------------------------------------------------ |
| `errors`                      | object | Error messages you can display to the user in the Checkout UI |
| `errors.ADDRESS_ERROR`        | string | "Your order can't be shipped to this address."                |
| `errors.COUNTRY_ERROR`        | string | "Your order can't be shipped to this country."                |
| `errors.STATE_ERROR`          | string | "Your order can't be shipped to this state."                  |
| `errors.ZIP_ERROR`            | string | "Your order can't be shipped to this zip."                    |
| `orderId`                     | string | The current order ID                                          |
| `shippingAddress`             | object | The newly selected shipping address                           |
| `shippingAddress.city`        | string | City name                                                     |
| `shippingAddress.state`       | string | State or province code                                        |
| `shippingAddress.countryCode` | string | ISO 3166-1 alpha-2 country code                               |
| `shippingAddress.postalCode`  | string | Postal or ZIP code                                            |

#### Return value [#return-value-1]

Return a promise to update the order asynchronously. If the promise rejects, the address change will be rejected and the buyer must select a different address.

#### Example [#example-17]

Validate the new shipping address, calculate updated shipping costs, and update the order on your server.

```javascript
onShippingAddressChange: async (data) => {
  const { errors, shippingAddress } = data;

  // Check if we ship to this address
  if (!isShippableLocation(shippingAddress)) {
    // Reject the address change
    throw new Error(errors.ADDRESS_ERROR);
  }

  // Calculate new shipping cost
  const shippingCost = calculateShipping({
    address: shippingAddress,
    items: cartItems,
  });

  // Update the order with new shipping
  const response = await fetch(`/api/orders/${data.orderId}/shipping`, {
    method: "PATCH",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      shippingAddress,
      shippingCost,
    }),
  });

  if (!response.ok) {
    throw new Error("Failed to update shipping");
  }
};
```

### `onShippingOptionsChange(data)` [#onshippingoptionschangedata]

The SDK calls this function when the buyer selects a different shipping option, for example, standard or express delivery. Use this callback to [update the order](/api/orders/v2/orders-patch) total with the selected shipping cost.

#### Data properties [#data-properties-1]

| Property                    | Type   | Description                                                                                        |
| :-------------------------- | :----- | :------------------------------------------------------------------------------------------------- |
| `errors`                    | object | Error messages you can display to the user in the Checkout UI                                      |
| `errors.METHOD_UNAVAILABLE` | string | "The shipping method you chose is unavailable. To continue, choose another way to get your order." |
| `errors.STORE_UNAVAILABLE`  | string | "Part of your order isn't available at this store."                                                |
| `orderId`                   | string | The current order ID                                                                               |
| `selectedShippingOption`    | object | Details of the selected shipping option                                                            |

#### Example [#example-18]

Handle a shipping option change by validating availability and updating the order total.

```javascript
onShippingOptionsChange: async (data) => {
  const { errors, selectedShippingOption } = data;

  // disable store pickup
  if (selectedShippingOption.type === "PICKUP") {
    throw new Error(errors.STORE_UNAVAILABLE);
  }

  // Update order with new shipping option
  await updateOrderShipping({
    orderId: data.orderId,
    shippingId: selectedShippingOption.id,
    shippingCost: selectedShippingOption.amount.value,
  });
};
```

## Web components [#web-components]

PayPal.js provides native web components for rendering payment buttons. These components automatically handle styling and accessibility while allowing customization through CSS variables.

### `paypal-button` [#paypal-button]

The PayPal button web component renders a PayPal-branded button that buyers select to start the payment flow.

#### Attributes [#attributes]

Attribute

Type

Description

type

string

Controls the button label text. Different types are optimized for
different contexts in your checkout flow.

Values:

pay — "Pay with PayPal"

checkout — "PayPal Checkout"

buynow — "PayPal Buy Now"

subscribe — "PayPal Subscribe"

class

string

Applies a predefined color scheme to the button.

Values:

paypal-gold — Gold background (recommended)

paypal-blue — Blue background

paypal-white — White with border

#### CSS variables [#css-variables]

Customize the button appearance using CSS custom properties:

| Variable                        | Description                            | Example values  |
| :------------------------------ | :------------------------------------- | :-------------- |
| `--paypal-button-border-radius` | Border radius for the button           | 4px, 20px, 50px |
| `--paypal-mark-border-radius`   | Border radius for the PayPal mark/logo | 4px, 8px        |

#### Example [#example-19]

Render PayPal buttons with different styles and labels, customize their appearance with CSS variables, and attach a click handler to start the payment flow.

```html
<!-- Basic button -->
<paypal-button type="pay" class="paypal-gold"></paypal-button>

<!-- Initially hidden button -->
<paypal-button type="checkout" class="paypal-blue" hidden> </paypal-button>

<!-- Custom styled button -->
<style>
  paypal-button {
    --paypal-button-border-radius: 10px;
    width: 100%;
    max-width: 350px;
  }

  paypal-button.custom-style {
    --paypal-button-border-radius: 25px;
  }
</style>

<paypal-button type="pay" class="paypal-gold custom-style"></paypal-button>

<script>
  // Attach click handler
  const onClick = async () => {
    try {
      await paypalSession.start({ presentationMode: "auto" }, createOrder());
    } catch (error) {
      console.log(error);
    }
  };

  document.querySelector("paypal-button").addEventListener("click", onClick);
</script>
```

### `venmo-button` [#venmo-button]

The Venmo button web component renders a Venmo-branded button for US buyers. The attributes and styling options are identical to `<paypal-button>`.

### Example [#example-20]

Render a Venmo-branded payment button.

```html
<venmo-button type="pay" class="venmo-blue"></venmo-button>
```

### `paylater-button` [#paylater-button]

The Pay Later button component displays financing options to buyers. This button requires additional configuration based on the available Pay Later products.

#### Attributes [#attributes-1]

| Attribute     | Type   | Description                                                                                                                  |
| :------------ | :----- | :--------------------------------------------------------------------------------------------------------------------------- |
| `productCode` | string | The specific Pay Later product to display, for example, `"PAY_IN_4"`. Get this from `paymentMethods.getDetails('paylater')`. |
| `countryCode` | string | The country code for the Pay Later offer. Required for proper messaging display.                                             |

#### Example [#example-21]

Set the Pay Later button's product and country attributes using details from eligibility checking.

```javascript
// Configure Pay Later button
const payLaterDetails = paymentMethods.getDetails("paylater");

const button = document.querySelector("paylater-button");
button.productCode = payLaterDetails.productCode;
button.countryCode = payLaterDetails.countryCode;
button.removeAttribute("hidden");
```

### `paypal-credit-button` [#paypal-credit-button]

The PayPal Credit button component displays PayPal's credit offering for eligible buyers (US only).

#### Attributes [#attributes-2]

| Attribute     | Type   | Description                                                                   |
| :------------ | :----- | :---------------------------------------------------------------------------- |
| `countryCode` | string | The country code for PayPal Credit availability. Required for proper display. |

#### Example [#example-22]

Configure the PayPal Credit button with the country code from eligibility details.

```javascript
const creditDetails = paymentMethods.getDetails("credit");

const button = document.querySelector("paypal-credit-button");
button.countryCode = creditDetails.countryCode;
```

### Browser compatibility [#browser-compatibility]

The JavaScript SDK v6 supports modern browsers. Check browser compatibility before initializing the SDK to ensure optimal user experience.

#### Minimum supported versions [#minimum-supported-versions]

| Browser (web/mobile web) | Minimum Supported Version |
| :----------------------- | :------------------------ |
| Chrome                   | 69                        |
| Safari                   | 12                        |
| Firefox                  | 63                        |
| Samsung Internet         | 10                        |
| Edge                     | 79                        |

#### Browser support check [#browser-support-check]

Use the `window.isBrowserSupportedByPayPal()` function to verify browser compatibility before initializing the SDK:

```javascript
// Check browser compatibility
if (window.isBrowserSupportedByPayPal()) {
  // Initialize PayPal SDK
  const sdkInstance = await window.paypal.createInstance({
    clientId: "YOUR_CLIENT_ID",
  });
} else {
  // Show fallback payment options or browser upgrade message
  showBrowserNotSupportedMessage();
}
```

## Card fields [#card-fields]

Card fields let you embed inline card input components on your page for credit and debit card payments. Card fields keep buyers on your page for the entire payment experience. Card data flows through PayPal-hosted iframes, so your site never handles raw card numbers.

> **Info:** Card fields require the `card-fields` component. Check eligibility using
> `paymentMethods.isEligible("advanced_cards")` before rendering the fields. For
> PCI compliance requirements, see [PCI DSS SAQ
> A-EP](https://www.pcisecuritystandards.org/).

### `sdkInstance.createCardFieldsOneTimePaymentSession()` [#sdkinstancecreatecardfieldsonetimepaymentsession]

Create a card fields session for a one-time payment. The session provides methods to create individual card input components and submit the payment.

#### Returns [#returns-16]

`createCardFieldsOneTimePaymentSession` returns a `CardFieldsOneTimePaymentSession` object with `createCardFieldsComponent(options)` and `submit(orderId, options?)` methods.

### `sdkInstance.createCardFieldsSavePaymentSession()` [#sdkinstancecreatecardfieldssavepaymentsession]

Create a card fields session for saving a card payment method ([vaulting](/api/payment-tokens/v3/setup-tokens-create)) for future use. The session behaves the same as the one-time session.

### `cardSession.createCardFieldsComponent(options)` [#cardsessioncreatecardfieldscomponentoptions]

Create an individual card field input component. The method returns an `HTMLElement` that you append directly to a DOM container.

#### Parameters [#parameters-14]

Parameter

Required

Description

type

yes

string. The card field to render.

Values:

number — Card number field

expiry — Expiration date field

cvv — Security code field

name — Cardholder name field

placeholder

no

string. Placeholder text shown inside the field when
empty, for example, "Card number" or "MM/YY"
.

style

no

object. CSS styles applied within the PayPal-hosted
iframe. See Card field styling.

#### Returns [#returns-17]

`createCardFieldsComponent` returns an `HTMLElement`. Mount it to a container using `appendChild()` or equivalent.

```javascript
const numberField = cardSession.createCardFieldsComponent({
  type: "number",
  placeholder: "Card number",
});

document.getElementById("card-number-container").appendChild(numberField);
```

### `cardSession.submit(orderId, options?)` [#cardsessionsubmitorderid-options]

Submit the card payment. This validates the card data, runs 3D Secure (3DS) authentication if required, and returns the payment outcome.

#### Parameters [#parameters-15]

Parameter

Required

Description

orderId

yes

string. The PayPal order ID [created on your
server](/api/orders/v2/orders-create). Pass the string directly — do
not pass an object such as {"{ orderId }"}.

options.billingAddress

no

object. Billing address fields to include with the
payment for risk and SCA purposes. Include at minimum the fields your
risk strategy requires.

Available fields: postalCode, streetAddress,{" "}
city, state, countryCode.

#### Returns [#returns-18]

`submit` returns a promise that resolves to `{ data, state }`:

| State       | Description                                                                                                |
| :---------- | :--------------------------------------------------------------------------------------------------------- |
| `succeeded` | Payment succeeded. `data.orderId` is the order ID to capture. `data.liabilityShift` indicates 3DS outcome. |
| `canceled`  | Buyer dismissed the 3D Secure modal. Display a non-blocking message and allow the buyer to retry.          |
| `failed`    | Validation or processing failure. `data.message` may contain details. Show an error and allow retry.       |

### Card field styling [#card-field-styling]

Pass a `style` object to `createCardFieldsComponent()` to customize card field appearance. Styles are applied within the PayPal-hosted iframe.

#### Supported CSS selectors [#supported-css-selectors]

| Selector   | When it applies                               |
| :--------- | :-------------------------------------------- |
| `input`    | The card input element                        |
| `.invalid` | Applied when the field value fails validation |
| `:focus`   | Applied when the field has keyboard focus     |

#### Supported CSS properties [#supported-css-properties]

* `appearance`
* `background`
* `border`
* `borderRadius`
* `boxShadow`
* `color`
* `direction`
* `font`
* `fontFamily`
* `fontSize`
* `fontSizeAdjust`
* `fontStretch`
* `fontStyle`
* `fontVariant`
* `fontVariantAlternates`
* `fontVariantCaps`
* `fontVariantEastAsian`
* `fontVariantLigatures`
* `fontVariantNumeric`
* `fontWeight`
* `height`
* `letterSpacing`
* `lineHeight`
* `opacity`
* `outline`
* `padding`
* `paddingBottom`
* `paddingLeft`
* `paddingRight`
* `paddingTop`
* `textShadow`
* `transition`

#### Example [#example-23]

Apply custom font styling and invalid-state colors to a card number field.

```javascript
const numberField = cardSession.createCardFieldsComponent({
  type: "number",
  placeholder: "Card number",
  style: {
    input: {
      fontSize: "16px",
      lineHeight: "24px",
      color: "#333333",
    },
    ".invalid": {
      color: "#e53e3e",
    },
  },
});
```

### Full card fields example [#full-card-fields-example]

Initialize the SDK, check card eligibility, create and mount card input fields, and handle payment submission with 3D Secure support.

```javascript
async function onPayPalWebSdkLoaded() {
  try {
    const sdk = await window.paypal.createInstance({
      clientId: "YOUR_CLIENT_ID",
      components: ["card-fields"],
      pageType: "checkout",
    });

    // Check eligibility before rendering
    const paymentMethods = await sdk.findEligibleMethods({
      currencyCode: "USD",
    });
    if (!paymentMethods.isEligible("advanced_cards")) {
      return; // Fall back to other payment methods
    }

    // Create card fields session
    const cardSession = sdk.createCardFieldsOneTimePaymentSession();

    // Create and mount field components
    const numberField = cardSession.createCardFieldsComponent({
      type: "number",
      placeholder: "Card number",
      style: { input: { fontSize: "16px" } },
    });
    const expiryField = cardSession.createCardFieldsComponent({
      type: "expiry",
      placeholder: "MM/YY",
    });
    const cvvField = cardSession.createCardFieldsComponent({
      type: "cvv",
      placeholder: "CVV",
    });

    document.getElementById("card-number").appendChild(numberField);
    document.getElementById("card-expiry").appendChild(expiryField);
    document.getElementById("card-cvv").appendChild(cvvField);

    // Handle submission
    document
      .getElementById("pay-button")
      .addEventListener("click", async () => {
        try {
          const orderId = await createOrder();

          const { data, state } = await cardSession.submit(orderId, {
            billingAddress: { postalCode: "10001" },
          });

          switch (state) {
            case "succeeded":
              // 3DS may or may not have run; check liabilityShift
              await captureOrder(data.orderId);
              window.location.href = "/order/success";
              break;
            case "canceled":
              // Buyer dismissed 3DS — allow retry without a new session
              showMessage("Authentication cancelled. Please try again.");
              break;
            case "failed":
              showMessage(
                data?.message || "Payment failed. Check your card details.",
              );
              break;
          }
        } catch (err) {
          console.error("Card payment error:", err);
          showMessage("An unexpected error occurred. Please try again.");
        }
      });
  } catch (err) {
    console.error("SDK initialization failed:", err);
  }
}
```

## Guest payments [#guest-payments]

Guest payments render a PayPal-hosted card form without requiring the buyer to create or log in to a PayPal account. The card form appears as an overlay on your page, handling card input and validation inside a PayPal-hosted environment.

> **Info:** Guest payments require the `paypal-guest-payments` component. Use the `<paypal-basic-card-button>` web component to trigger the payment flow.

### `sdkInstance.createPayPalGuestOneTimePaymentSession(options)` [#sdkinstancecreatepaypalguestonetimepaymentsessionoptions]

Create a guest payment session for one-time card payments. This session manages the full card collection and payment authorization flow.

#### Parameters [#parameters-16]

Parameter

Required

Description

onApprove

yes

function(data). Called when the payment is approved.
[Capture](/api/orders/v2/orders-capture) the order using{" "}
data.orderId.

onComplete

yes

function(data). Called after onApprove{" "}
when the payment flow finishes. Use this to navigate to a confirmation
page or update UI state.

onCancel

no

function(data). Called when the buyer closes the card
form without completing payment.

onError

no

function(error). Called when an unrecoverable error
occurs. The error object contains code and{" "}
message.

onWarn

no

function(data). Called when the buyer encounters a
recoverable error after submitting the card form — for example, a card
decline, name formatting error, or invalid address. The overlay stays
open so the buyer can correct and retry.

The data object contains:

message — Human-readable description

name — Warning type, for example,{" "}
PaymentFlowWarning

code — Warning code, for example,{" "}
WARN\_FLOW\_GUEST\_CHECKOUT\_SUBMIT\_ERROR

onShippingAddressChange

no

function(data). Called when the buyer changes their
shipping address. See{" "}

onShippingAddressChange

{" "}

for the full data structure.

onShippingOptionsChange

no

function(data). Called when the buyer selects a
different shipping option. See{" "}

onShippingOptionsChange

{" "}

for the full data structure.

#### Returns [#returns-19]

`createPayPalGuestOneTimePaymentSession` returns a guest payment session object with a `start(options, orderPromise)` method.

#### `start(options, orderPromise)` parameters [#startoptions-orderpromise-parameters]

| Parameter                  | Required | Description                                                                                                 |
| :------------------------- | :------- | :---------------------------------------------------------------------------------------------------------- |
| `options.presentationMode` | no       | **string.** How the card form overlay is displayed. Values: `auto` (default), `modal`, `popup`, `redirect`. |
| `options.targetElement`    | no       | **HTMLElement.** The element that triggered the session, used for overlay positioning.                      |
| `orderPromise`             | yes      | **Promise.** A promise that resolves to `{ orderId: string }`.                                              |

#### Web components [#web-components-1]

Use these web components to render the guest payment button:

```html
<paypal-basic-card-container>
  <paypal-basic-card-button id="guest-card-button"> </paypal-basic-card-button>
</paypal-basic-card-container>
```

#### Example [#example-24]

Initialize the SDK, check card eligibility, set up a guest payment session with event handlers, and start the flow when the buyer clicks the card button.

```javascript
const sdkInstance = await window.paypal.createInstance({
  clientId: "YOUR_CLIENT_ID",
  components: ["paypal-guest-payments"],
  pageType: "checkout",
});

const paymentMethods = await sdkInstance.findEligibleMethods({
  currencyCode: "USD",
});

if (paymentMethods.isEligible("card")) {
  const guestPaymentSession =
    await sdkInstance.createPayPalGuestOneTimePaymentSession({
      onApprove: async (data) => {
        const orderData = await captureOrder({ orderId: data.orderId });
        console.log("Payment captured:", orderData);
      },
      onComplete: () => {
        window.location.href = "/order/success";
      },
      onCancel: () => {
        document.getElementById("guest-card-button").disabled = false;
      },
      onError: (error) => {
        console.error("Payment error:", error.code, error.message);
      },
      onWarn: (data) => {
        // Buyer encountered a recoverable error — overlay stays open for retry
        console.warn("Payment warning:", data.code, data.message);
      },
    });

  document
    .getElementById("guest-card-button")
    .addEventListener("click", async () => {
      await guestPaymentSession.start(
        { presentationMode: "auto" },
        createOrder(), // Returns Promise<{ orderId: string }>
      );
    });
}
```
