# Reference (/sdk/react/reference)

React SDK v6 reference



To integrate PayPal, Venmo, Pay Later, and other payment methods into React applications, use the PayPal React SDK v6 (`@paypal/react-paypal-js/sdk-v6`). This reference covers the provider component, hooks, payment session hooks, payment button components, card fields, server utilities, types, and common patterns.

> **Tip:** * For the vanilla JavaScript SDK v6 reference, see [JavaScript SDK v6
>   Reference](/sdk/js/reference).
> * For setup and initialization, see [Set up JavaScript SDK v6](/sdk/js/set-up).
> * If your button colors changed from an existing integration, see [Button color updates](/sdk/button-color-updates).
> * Check out our [GitHub sample integration with React](https://github.com/paypal-examples/v6-web-sdk-sample-integration/tree/main/client/prebuiltPages/react).

## PayPalProvider [#paypalprovider]

`PayPalProvider` is a context provider that initializes the PayPal SDK and provides payment functionality to child components.

### Props [#props]

Prop

Type

Required

Description

clientId

string | Promise<string> | undefined

yes

PayPal client ID for authenticating SDK requests. Use either{" "}
clientId or clientToken, not both

clientToken

string | Promise<string> | undefined

yes

PayPal client token for authenticating SDK requests. Use either{" "}
clientId or clientToken, not both

components

string[]

yes

Array of components to load. Values include{" "}
"paypal-payments", "venmo-payments",{" "}
"paypal-subscriptions",{" "}
"paypal-guest-payments", "card-fields",{" "}
"paypal-messages", "applepay-payments",
and "googlepay-payments".
Defaults to \["paypal-payments"]

environment

string

yes

Target environment. Values are "sandbox" or{" "}
"production"

pageType

string

no

Page context type, for example, "checkout"

locale

string

no

Locale for the SDK, for example, "en\_US"

clientMetadataId

string

no

Client metadata ID for tracking

partnerAttributionId

string

no

Partner attribution ID

shopperSessionId

string

no

Shopper session ID for personalization

testBuyerCountry

string

no

Test buyer country for sandbox testing

merchantId

string | string[]

no

Merchant ID or array of merchant IDs

eligibleMethodsResponse

object

no

Pre-fetched eligible methods response from server-side{" "}
useFetchEligibleMethods

debug

boolean

no

Enable debug mode

dataNamespace

string

no

Custom namespace for the SDK data attribute

> **Warning:** PayPalProvider requires a clientId or{" "}
> clientToken to authenticate your integration.

### Example [#example]

Replace `YOUR_PAYPAL_CLIENT_ID` with your app's PayPal client ID when initializing the provider.

> **Tip:** Place `PayPalProvider` at your app root so payment buttons render sooner.

#### Client ID

```tsx
import { PayPalProvider } from "@paypal/react-paypal-js/sdk-v6";

function App() {
return (

<PayPalProvider
  clientId="YOUR_PAYPAL_CLIENT_ID"
  environment="sandbox"
  components={["paypal-payments", "venmo-payments", "paypal-subscriptions"]}
  pageType="checkout"
>
  {/* Child components */}
</PayPalProvider>
); }

```

#### Client token

```tsx
import { useMemo } from "react";
import { PayPalProvider } from "@paypal/react-paypal-js/sdk-v6";

function App() {
  // Memoize the promise to prevent re-fetching on every render
  const tokenPromise = useMemo(() => fetchClientToken(), []);

  return (
    <PayPalProvider
      clientToken={tokenPromise}
      environment="sandbox"
      components={["paypal-payments"]}
      pageType="checkout"
    >
      {/* Child components */}
    </PayPalProvider>
  );
}
```

## Hooks [#hooks]

Hooks provide access to SDK state and payment eligibility data inside your React components. Use them to check SDK internals or conditionally render UI based on which payment methods are available.

### `usePayPal()` [#usepaypal]

`usePayPal` provides access to the PayPal SDK state and payment eligibility information. Must be used within a `PayPalProvider`.

#### Returns [#returns]

Property

Type

Description

loadingStatus

INSTANCE_LOADING_STATE

Current SDK loading state. Compare against{" "}
INSTANCE\_LOADING\_STATE{" "}
enum values

eligiblePaymentMethods

object | null

Available payment methods for the current user

sdkInstance

object | null

The underlying SDK instance

error

Error | null

Any error that occurred during SDK initialization

isHydrated

boolean

Whether the component has been hydrated on the client

#### Example [#example-1]

Use `usePayPal` to access the SDK state and payment eligibility in any component inside `PayPalProvider`.

```tsx
import {
  usePayPal,
  INSTANCE_LOADING_STATE,
} from "@paypal/react-paypal-js/sdk-v6";

function CheckoutForm() {
  const { loadingStatus, error } = usePayPal();

  if (loadingStatus === INSTANCE_LOADING_STATE.PENDING) {
    return <div>Loading...</div>;
  }

  if (loadingStatus === INSTANCE_LOADING_STATE.REJECTED) {
    return <div>Failed to load PayPal SDK: {error?.message}</div>;
  }

  return <PaymentButtons />;
}
```

### `useEligibleMethods(options)` [#useeligiblemethodsoptions]

`useEligibleMethods` returns eligible payment methods from the PayPal SDK. It prevents duplicate API calls across components.

#### Parameters [#parameters]

Parameter

Required

Description

payload.amount

no

string. Order amount, for example,{" "}
"95.00"

payload.currencyCode

no

string. Three-letter ISO 4217 currency code, for
example, "USD"

payload.paymentFlow

no

string. The payment flow type. Values are{" "}
"ONE\_TIME\_PAYMENT", "RECURRING\_PAYMENT",{" "}
"VAULT\_WITH\_PAYMENT", or{" "}
"VAULT\_WITHOUT\_PAYMENT"

#### Returns [#returns-1]

Property

Type

Description

eligiblePaymentMethods

object | null

Available payment methods for the current user.{" "}

To retrieve product-specific details, call{" "}
.getDetails("").

To check eligibility for a specific payment method, call{" "}
.isEligible("").

isLoading

boolean

Whether eligibility data is still being fetched

error

Error | null

Any error that occurred during the fetch

#### Example [#example-2]

The following example fetches eligible payment methods for a one-time USD payment and conditionally renders a Pay Later button that is based on the result.

```tsx
import {
  useEligibleMethods,
  usePayLaterOneTimePaymentSession,
} from "@paypal/react-paypal-js/sdk-v6";

function PayLaterCheckout(props) {
  const { handleClick } = usePayLaterOneTimePaymentSession(props);
  const { eligiblePaymentMethods, isLoading, error } = useEligibleMethods({
    payload: { currencyCode: "USD" },
  });

  const payLaterDetails = eligiblePaymentMethods?.getDetails?.("paylater");
  const countryCode = payLaterDetails?.countryCode;
  const productCode = payLaterDetails?.productCode;

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <paypal-pay-later-button
      onClick={handleClick}
      countryCode={countryCode}
      productCode={productCode}
    />
  );
}
```

### `usePayPalMessages(options)` [#usepaypalmessagesoptions]

`usePayPalMessages` creates a PayPal Messages session to fetch messaging content and create learn more modals.

#### Parameters [#parameters-1]

Parameter

Required

Description

buyerCountry

no

string. Buyer's country code

currencyCode

no

string. Currency code

shopperSessionId

no

string. Shopper session ID

#### Returns [#returns-2]

Property

Type

Description

error

Error | null

Any session error

isReady

boolean

Whether the session is created

handleFetchContent

function

Fetches message content

handleCreateLearnMore

function

Creates a learn more modal

#### Example [#example-3]

The following example uses auto-bootstrap mode to display a PayPal message with a learn more modal.

```tsx
import { usePayPalMessages } from "@paypal/react-paypal-js/sdk-v6";

function PayPalMessaging({ amount }: { amount: string }) {
  const { error } = usePayPalMessages({});

  if (error) return null;

  return (
    <paypal-message
      auto-bootstrap={true}
      amount={amount}
      currency-code="USD"
      buyer-country="US"
    />
  );
}
```

## Payment session hooks [#payment-session-hooks]

Payment session hooks give you control over the payment flow for advanced integrations. Each button component has a session hook. All payment session hooks return a `BasePaymentSessionReturn` object.

Property

Type

Description

error

Error | null

Any session error

isPending

boolean

Whether the SDK instance is still loading

handleClick

() => Promise

Starts the payment session

handleCancel

() => void

Cancels the session

handleDestroy

() => void

Cleans up the session

### `usePayPalOneTimePaymentSession` [#usepaypalonetimepaymentsession]

The following example creates an order on your server and renders a custom PayPal button that starts the payment session when selected.

```tsx
import { usePayPalOneTimePaymentSession } from "@paypal/react-paypal-js/sdk-v6";

function CustomPayPalButton() {
  const { isPending, error, handleClick } = usePayPalOneTimePaymentSession({
    createOrder: async () => {
      const res = await fetch("/api/orders", { method: "POST" });
      const { id } = await res.json();
      return { orderId: id };
    },
    onApprove: async (data) => {
      console.log("Approved:", data.orderId);
    },
    presentationMode: "auto",
  });

  if (isPending) return null;
  if (error) return <div>Error: {error.message}</div>;

  return <paypal-button onClick={handleClick} type="pay" />;
}
```

### `useVenmoOneTimePaymentSession` [#usevenmoonetimepaymentsession]

The following example creates an order and renders a custom Venmo button for one-time payments.

```tsx
import { useVenmoOneTimePaymentSession } from "@paypal/react-paypal-js/sdk-v6";

function CustomVenmoButton() {
  const { isPending, error, handleClick } = useVenmoOneTimePaymentSession({
    createOrder: async () => {
      const res = await fetch("/api/orders", { method: "POST" });
      const { id } = await res.json();
      return { orderId: id };
    },
    onApprove: async (data) => {
      console.log("Approved:", data.orderId);
    },
    presentationMode: "auto",
  });

  if (isPending) return null;
  if (error) return <div>Error: {error.message}</div>;

  return <venmo-button onClick={handleClick} type="pay" />;
}
```

### `usePayLaterOneTimePaymentSession` [#usepaylateronetimepaymentsession]

The following example retrieves Pay Later eligibility details from `usePayPal` and passes `countryCode` and `productCode` to a custom Pay Later button.

```tsx
import {
  usePayLaterOneTimePaymentSession,
  usePayPal,
} from "@paypal/react-paypal-js/sdk-v6";

function CustomPayLaterButton() {
  const { eligiblePaymentMethods } = usePayPal();
  const { isPending, error, handleClick } = usePayLaterOneTimePaymentSession({
    createOrder: async () => {
      const res = await fetch("/api/orders", { method: "POST" });
      const { id } = await res.json();
      return { orderId: id };
    },
    onApprove: async (data) => {
      console.log("Approved:", data.orderId);
    },
    presentationMode: "auto",
  });

  const payLaterDetails = eligiblePaymentMethods?.getDetails("paylater");

  if (isPending) return null;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <paypal-pay-later-button
      onClick={handleClick}
      countryCode={payLaterDetails?.countryCode}
      productCode={payLaterDetails?.productCode}
    />
  );
}
```

### `usePayPalCreditOneTimePaymentSession` [#usepaypalcreditonetimepaymentsession]

The following example retrieves PayPal Credit eligibility details and renders a custom credit button with the buyer's `countryCode`.

```tsx
import {
  usePayPalCreditOneTimePaymentSession,
  usePayPal,
} from "@paypal/react-paypal-js/sdk-v6";

function CustomCreditButton() {
  const { eligiblePaymentMethods } = usePayPal();
  const { isPending, error, handleClick } =
    usePayPalCreditOneTimePaymentSession({
      createOrder: async () => {
        const res = await fetch("/api/orders", { method: "POST" });
        const { id } = await res.json();
        return { orderId: id };
      },
      onApprove: async (data) => {
        console.log("Approved:", data.orderId);
      },
      presentationMode: "auto",
    });

  const creditDetails = eligiblePaymentMethods?.getDetails?.("credit");

  if (isPending) return null;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <paypal-credit-button
      onClick={handleClick}
      countryCode={creditDetails?.countryCode}
    />
  );
}
```

### `usePayPalGuestPaymentSession` [#usepaypalguestpaymentsession]

`usePayPalGuestPaymentSession` returns an additional `buttonRef` to pass to the `<paypal-basic-card-button>` element. The following example renders a guest checkout button inside a `<paypal-basic-card-container>` wrapper.

```tsx
import { usePayPalGuestPaymentSession } from "@paypal/react-paypal-js/sdk-v6";

function CustomGuestButton() {
  const { buttonRef, isPending, error, handleClick } =
    usePayPalGuestPaymentSession({
      createOrder: async () => {
        const res = await fetch("/api/orders", { method: "POST" });
        const { id } = await res.json();
        return { orderId: id };
      },
      onApprove: async (data) => {
        console.log("Approved:", data.orderId);
      },
    });

  if (isPending) return null;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <paypal-basic-card-container>
      <paypal-basic-card-button ref={buttonRef} onClick={handleClick} />
    </paypal-basic-card-container>
  );
}
```

### `usePayPalSavePaymentSession` [#usepaypalsavepaymentsession]

The following example creates a vault setup token on your server and renders a button that saves the payment method when selected.

```tsx
import { usePayPalSavePaymentSession } from "@paypal/react-paypal-js/sdk-v6";

function CustomSaveButton() {
  const { isPending, error, handleClick } = usePayPalSavePaymentSession({
    createVaultToken: async () => {
      const res = await fetch("/api/vault-setup-token", { method: "POST" });
      const { id } = await res.json();
      return { vaultSetupToken: id };
    },
    onApprove: async (data) => {
      console.log("Saved:", data.vaultSetupToken);
    },
    presentationMode: "auto",
  });

  if (isPending) return null;
  if (error) return <div>Error: {error.message}</div>;

  return <paypal-button onClick={handleClick} type="pay" />;
}
```

### `usePayPalCreditSavePaymentSession` [#usepaypalcreditsavepaymentsession]

The following example saves a PayPal Credit payment method to the vault and passes the buyer's `countryCode` from eligibility data to the credit button.

```tsx
import {
  usePayPalCreditSavePaymentSession,
  usePayPal,
} from "@paypal/react-paypal-js/sdk-v6";

function CustomCreditSaveButton() {
  const { eligiblePaymentMethods } = usePayPal();
  const { isPending, error, handleClick } = usePayPalCreditSavePaymentSession({
    createVaultToken: async () => {
      const res = await fetch("/api/vault-setup-token", { method: "POST" });
      const { id } = await res.json();
      return { vaultSetupToken: id };
    },
    onApprove: async (data) => {
      console.log("Saved:", data.vaultSetupToken);
    },
    presentationMode: "auto",
  });

  const creditDetails = eligiblePaymentMethods?.getDetails?.("credit");

  if (isPending) return null;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <paypal-credit-button
      onClick={handleClick}
      countryCode={creditDetails?.countryCode}
    />
  );
}
```

### `usePayPalSubscriptionPaymentSession` [#usepaypalsubscriptionpaymentsession]

The following example creates a subscription on your server and renders a custom subscribe button that starts the subscription flow when selected.

```tsx
import { usePayPalSubscriptionPaymentSession } from "@paypal/react-paypal-js/sdk-v6";

function CustomSubscriptionButton() {
  const { isPending, error, handleClick } = usePayPalSubscriptionPaymentSession(
    {
      createSubscription: async () => {
        const res = await fetch("/api/subscriptions", { method: "POST" });
        const { id } = await res.json();
        return { subscriptionId: id };
      },
      onApprove: async (data) => {
        console.log("Subscription approved:", data.payerId);
      },
      presentationMode: "auto",
    },
  );

  if (isPending) return null;
  if (error) return <div>Error: {error.message}</div>;

  return <paypal-button onClick={handleClick} type="subscribe" />;
}
```

### `useApplePayOneTimePaymentSession` [#useapplepayonetimepaymentsession]

The following example configures an Apple Pay session with a payment request and renders a native Apple Pay button.

```tsx
import { useApplePayOneTimePaymentSession } from "@paypal/react-paypal-js/sdk-v6";

function CustomApplePayButton({ applePayConfig }) {
  const { isPending, error, handleClick } = useApplePayOneTimePaymentSession({
    applePayConfig,
    paymentRequest: {
      countryCode: "US",
      currencyCode: "USD",
      total: { label: "Demo Store", amount: "100.00", type: "final" },
    },
    applePaySessionVersion: 4,
    createOrder: async () => {
      const res = await fetch("/api/orders", { method: "POST" });
      const { id } = await res.json();
      return { orderId: id };
    },
    onApprove: (data) => console.log("Approved:", data),
    onError: (err) => console.error(err),
  });

  if (isPending) return null;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <apple-pay-button onClick={handleClick} buttonstyle="black" type="pay" />
  );
}
```

## Payment components [#payment-components]

The following components render PayPal payment buttons in your React app. Each component wraps a specific payment flow and accepts callback props to handle the payment lifecycle.

### PayPalOneTimePaymentButton [#paypalonetimepaymentbutton]

`PayPalOneTimePaymentButton` renders a button for one-time PayPal payments. It uses `usePayPalOneTimePaymentSession` internally.

#### Props [#props-1]

{/* <PayPalOnetimeProps /> */}

#### Example [#example-4]

The following example renders a PayPal button that creates an order on your server and handles approval when the buyer completes payment.

```tsx
import {
  PayPalOneTimePaymentButton,
  type OnApproveDataOneTimePayments,
} from "@paypal/react-paypal-js/sdk-v6";

function Checkout() {
  const handleCreateOrder = async () => {
    const response = await fetch("/api/orders", { method: "POST" });
    const { id } = await response.json();
    return { orderId: id };
  };

  return (
    <PayPalOneTimePaymentButton
      createOrder={handleCreateOrder}
      onApprove={async (data: OnApproveDataOneTimePayments) => {
        console.log("Order approved:", data.orderId);
      }}
      presentationMode="auto"
    />
  );
}
```

### VenmoOneTimePaymentButton [#venmoonetimepaymentbutton]

`VenmoOneTimePaymentButton` renders a button for one-time Venmo payments (US only). It uses `useVenmoOneTimePaymentSession` internally.

#### Props [#props-2]

`VenmoOneTimePaymentButton` accepts the same props as `PayPalOneTimePaymentButton`.

{/* <PayPalOnetimeProps /> */}

#### Example [#example-5]

The following example renders a Venmo payment button with order creation and approval callbacks.

```tsx
import { VenmoOneTimePaymentButton } from "@paypal/react-paypal-js/sdk-v6";

<VenmoOneTimePaymentButton
  createOrder={handleCreateOrder}
  onApprove={handleApprove}
  presentationMode="auto"
/>;
```

### PayLaterOneTimePaymentButton [#paylateronetimepaymentbutton]

`PayLaterOneTimePaymentButton` renders a button for the Pay Later payment option (Pay in 4, financing). It requires `useEligibleMethods` to fetch eligibility data, which provides the `countryCode` and `productCode` needed for the button.

#### Props [#props-3]

{/* <PayLaterOnetimeProps /> */}

#### Example [#example-6]

The following example renders a Pay Later button that lets buyers choose financing options like Pay in 4.

```tsx
import {
  PayLaterOneTimePaymentButton,
  useEligibleMethods,
} from "@paypal/react-paypal-js/sdk-v6";

function PayLaterCheckout() {
  const { error, isLoading } = useEligibleMethods();

  return (
    !error &&
    !isLoading && (
      <PayLaterOneTimePaymentButton
        createOrder={handleCreateOrder}
        onApprove={handleApprove}
        presentationMode="auto"
      />
    )
  );
}
```

### PayPalCreditOneTimePaymentButton [#paypalcreditonetimepaymentbutton]

`PayPalCreditOneTimePaymentButton` renders a button for PayPal Credit one-time payments. It requires `useEligibleMethods` to fetch eligibility data, which provides the `countryCode` needed for the button.

#### Props [#props-4]

{/* <PayLaterOnetimeProps /> */}

#### Example [#example-7]

The following example checks eligibility before rendering a PayPal Credit button for one-time payments.

```tsx
import {
  PayPalCreditOneTimePaymentButton,
  useEligibleMethods,
} from "@paypal/react-paypal-js/sdk-v6";

function CreditCheckout() {
  const { error, isLoading } = useEligibleMethods();

  return (
    !error &&
    !isLoading && (
      <PayPalCreditOneTimePaymentButton
        createOrder={handleCreateOrder}
        onApprove={handleApprove}
        presentationMode="auto"
      />
    )
  );
}
```

### PayPalGuestPaymentButton [#paypalguestpaymentbutton]

`PayPalGuestPaymentButton` renders a button for guest checkout that does not require a PayPal account. It automatically wraps the button with `<paypal-basic-card-container>`.

> **Note:** This component does not accept `presentationMode`. It renders a `<paypal-basic-card-button>` inside a `<paypal-basic-card-container>` automatically.

#### Props [#props-5]

Prop

Type

Description

createOrder

() => Promise<{ orderId: string }>

Function that calls your server to create a PayPal order and returns the
resulting orderId. The component calls this function when
the buyer clicks the button. Use either createOrder or{" "}
orderId, not both

orderId

string

Order ID for an order you already created on your server. Use this when
your app creates the order before rendering the button. Use either{" "}
createOrder or orderId, not both

onApprove

(data: OnApproveDataOneTimePayments) => Promise\<void>

Callback when payment is approved

onCancel

(data: OnCancelDataOneTimePayments) => void

Callback when user cancels

onError

(data: OnErrorData) => void

Callback on payment error

onComplete

(data: OnCompleteData) => void

Callback when payment session completes

fullPageOverlay

\{ enabled: boolean }

Whether to show a full-page overlay

onShippingAddressChange

(data: OnShippingAddressChangeData) => Promise\<void>

Callback when shipping address changes

onShippingOptionsChange

(data: OnShippingOptionsChangeData) => Promise\<void>

Callback when shipping options change

disabled

boolean

Whether the button is disabled

#### Example [#example-8]

The following example renders a guest checkout button that allows buyers to pay without a PayPal account.

```tsx
import { PayPalGuestPaymentButton } from "@paypal/react-paypal-js/sdk-v6";

<PayPalGuestPaymentButton
  createOrder={handleCreateOrder}
  onApprove={handleApprove}
/>;
```

### PayPalSavePaymentButton [#paypalsavepaymentbutton]

`PayPalSavePaymentButton` renders a button that saves payment methods to a vault.

#### Props [#props-6]

{/* <SavePaymentProps /> */}

#### Example [#example-9]

The following example creates a vault setup token on your server and renders a button that saves the buyer's payment method.

```tsx
import {
  PayPalSavePaymentButton,
  type OnApproveDataSavePayments,
} from "@paypal/react-paypal-js/sdk-v6";

function SavePayment() {
  const handleCreateVaultToken = async () => {
    const response = await fetch("/api/vault-setup-token", { method: "POST" });
    const { id } = await response.json();
    return { vaultSetupToken: id };
  };

  return (
    <PayPalSavePaymentButton
      createVaultToken={handleCreateVaultToken}
      onApprove={(data: OnApproveDataSavePayments) => {
        console.log("Payment saved with token:", data.vaultSetupToken);
      }}
      presentationMode="auto"
    />
  );
}
```

### PayPalCreditSavePaymentButton [#paypalcreditsavepaymentbutton]

`PayPalCreditSavePaymentButton` renders a button that saves PayPal Credit payment methods. It requires `useEligibleMethods` to fetch eligibility data, which provides the `countryCode` needed for the button.

#### Props [#props-7]

{/* <SavePaymentProps /> */}

#### Example [#example-10]

The following example checks eligibility before rendering a button that saves a PayPal Credit payment method to the vault.

```tsx
import {
  PayPalCreditSavePaymentButton,
  useEligibleMethods,
} from "@paypal/react-paypal-js/sdk-v6";

function CreditSavePayment() {
  const { error, isLoading } = useEligibleMethods();

  return (
    !error &&
    !isLoading && (
      <PayPalCreditSavePaymentButton
        createVaultToken={handleCreateVaultToken}
        onApprove={handleApprove}
        presentationMode="auto"
      />
    )
  );
}
```

### PayPalSubscriptionButton [#paypalsubscriptionbutton]

`PayPalSubscriptionButton` renders a button that creates subscriptions.

> **Note:** Subscriptions only support `"auto"`, `"popup"`, `"modal"`, or
> `"payment-handler"` presentation modes.

#### Props [#props-8]

Prop

Type

Description

createSubscription

() => Promise\<\{ subscriptionId: string }>

Function that creates a subscription and returns an object with{" "}
subscriptionId

onApprove

(data: OnApproveDataSubscriptions) => Promise\<void>

Callback when subscription is approved. Receives{" "}
subscriptionId and payerId

onCancel

(data: OnCancelDataOneTimePayments) => void

Callback when user cancels

onError

(data: OnErrorData) => void

Callback on error

onComplete

(data: OnCompleteData) => void

Callback when session completes

presentationMode

string

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.

type

string

Button type. Defaults to "subscribe"

disabled

boolean

Whether the button is disabled

#### Example [#example-11]

The following example creates a subscription on your server and renders a button that starts the subscription approval flow.

```tsx
import {
  PayPalSubscriptionButton,
  type OnApproveDataSubscriptions,
} from "@paypal/react-paypal-js/sdk-v6";

function Subscription() {
  const handleCreateSubscription = async () => {
    const response = await fetch("/api/subscriptions", { method: "POST" });
    const { id } = await response.json();
    return { subscriptionId: id };
  };

  return (
    <PayPalSubscriptionButton
      createSubscription={handleCreateSubscription}
      onApprove={(data: OnApproveDataSubscriptions) => {
        console.log("Subscription ID:", data.subscriptionId);
      }}
      presentationMode="auto"
    />
  );
}
```

### ApplePayOneTimePaymentButton [#applepayonetimepaymentbutton]

`ApplePayOneTimePaymentButton` renders a native `<apple-pay-button>` element for Apple Pay payments with Safari-compatible styling.

#### Props [#props-9]

Prop

Type

Description

applePayConfig

ApplePayConfig

Apple Pay configuration from findEligibleMethods

paymentRequest

ApplePayPaymentRequest

Payment request with country, currency, and total

applePaySessionVersion

number

Apple Pay JS API version (4 or later)

createOrder

() => Promise<{ orderId: string }>

Function that creates an order

onApprove

(data: ConfirmOrderResponse) => void

Callback when payment is approved

onCancel

() => void

Callback when payment is cancelled

onError

(error: Error) => void

Callback on error

displayName

string

Merchant display name

domainName

string

Merchant domain name

buttonstyle

string

Button style, for example, "black" (default) or{" "}
"white"

type

string

Button type, for example, "pay" (default)

locale

string

Locale, such as "en" (default)

disabled

boolean

Whether the button is disabled

#### Example [#example-12]

The following example renders an Apple Pay button configured with a payment request and order creation callback.

```tsx
import { ApplePayOneTimePaymentButton } from "@paypal/react-paypal-js/sdk-v6";

<ApplePayOneTimePaymentButton
  applePayConfig={applePayConfig}
  paymentRequest={{
    countryCode: "US",
    currencyCode: "USD",
    total: { label: "Demo Store", amount: "100.00", type: "final" },
  }}
  applePaySessionVersion={4}
  createOrder={async () => {
    const res = await fetch("/api/orders", { method: "POST" });
    const data = await res.json();
    return { orderId: data.id };
  }}
  onApprove={(data) => console.log("Approved:", data)}
  onError={(err) => console.error(err)}
/>;
```

## Card fields components [#card-fields-components]

Card fields let you render individual, PCI-compliant input fields for card number, expiration, and CVV within your checkout form.

### PayPalCardFieldsProvider [#paypalcardfieldsprovider]

`PayPalCardFieldsProvider` creates a Card Fields session and provides it to child field components. Only the `children` prop is required. All other props are optional and can be used to configure the session and listen to field events.

#### Props [#props-10]

Prop

Type

Description

children (required)

ReactNode

Child components

amount

{" "}

\{ value?: string, currencyCode?: string }

Order amount, which you can update dynamically

isCobrandedEligible

boolean

Whether co-branded card eligibility is enabled

blur

(event) => void

Callback when a card field loses focus

validitychange

(event) => void

Callback when field validity changes

cardtypechange

(event) => void

Callback when card type changes or is detected

focus

(event) => void

Callback when a card field gains focus

change

(event) => void

Callback when card field value changes

empty

(event) => void

Callback when a card field is empty

inputsubmit

(event) => void

Callback when a card field is submitted

notempty

(event) => void

Callback when a card field is not empty

#### Example [#example-13]

The following example renders card number, expiry, and CVV fields inside a provider that listens for validity and card type changes.

```tsx
import {
  PayPalCardFieldsProvider,
  PayPalCardNumberField,
  PayPalCardExpiryField,
  PayPalCardCvvField,
} from "@paypal/react-paypal-js/sdk-v6";

function CardFieldsCheckout() {
  return (
    <PayPalCardFieldsProvider
      amount={{ value: "10.00", currencyCode: "USD" }}
      validitychange={(event) => console.log("Validity change event:", event)}
      cardtypechange={(event) => console.log("Card type change event:", event)}
    >
      <PayPalCardNumberField placeholder="Card number" />
      <PayPalCardExpiryField placeholder="MM/YY" />
      <PayPalCardCvvField placeholder="CVV" />
      <SubmitButton />
    </PayPalCardFieldsProvider>
  );
}
```

### PayPalCardNumberField [#paypalcardnumberfield]

`PayPalCardNumberField` renders a card number input field. Use within a `PayPalCardFieldsProvider`. All props are optional.

#### Props [#props-11]

{/* <CardFieldProps /> */}

### PayPalCardExpiryField [#paypalcardexpiryfield]

`PayPalCardExpiryField` renders a card expiry input field. Use within a `PayPalCardFieldsProvider`. All props are optional.

#### Props [#props-12]

{/* <CardFieldProps /> */}

### PayPalCardCvvField [#paypalcardcvvfield]

`PayPalCardCvvField` renders a CVV input field. Use within a `PayPalCardFieldsProvider`. All props are optional.

#### Props [#props-13]

{/* <CardFieldProps /> */}

### `usePayPalCardFields()` [#usepaypalcardfields]

`usePayPalCardFields` returns the Card Fields state from the `PayPalCardFieldsProvider` context. Use within a `PayPalCardFieldsProvider`.

### `usePayPalCardFieldsOneTimePaymentSession()` [#usepaypalcardfieldsonetimepaymentsession]

`usePayPalCardFieldsOneTimePaymentSession` submits card field data for one-time payments.

#### Returns [#returns-3]

Property

Type

Description

submit

(orderId: string | Promise\<string>, options?) =>
Promise\<void>

Submit the card fields for payment

submitResponse

object | null

The response from the submit operation

error

Error | null

Any error that occurred

#### Example [#example-14]

The following example renders styled card fields, submits the card data for a one-time payment, and handles both success and failure responses.

```tsx One-time payment
import {
  PayPalCardCvvField,
  PayPalCardExpiryField,
  PayPalCardNumberField,
  usePayPalCardFields,
  usePayPalCardFieldsOneTimePaymentSession,
} from "@paypal/react-paypal-js/sdk-v6";
import { useEffect } from "react";
import { captureOrder } from "../../../utils";

const PayPalCardFieldsOneTimePayment = () => {
  const { error: cardFieldsError } = usePayPalCardFields();
  const {
    error: submitError,
    submit,
    submitResponse,
  } = usePayPalCardFieldsOneTimePaymentSession();

  useEffect(() => {
    if (!submitResponse) {
      return;
    }

    const { orderId, message } = submitResponse.data;

    switch (submitResponse.state) {
      case "succeeded":
        console.log(`One time payment succeeded: orderId: ${orderId}`);
        captureOrder({ orderId }).then((captureResult) => {
          console.log("Payment capture result:", captureResult);
        });
        break;
      case "failed":
        console.error(
          `One time payment failed: orderId: ${orderId}, message:  ${message}`,
        );
        break;
    }
  }, [submitResponse]);

  useEffect(() => {
    if (cardFieldsError) {
      console.error("Error loading PayPal Card Fields", cardFieldsError);
    }
    if (submitError) {
      console.error("Error submitting PayPal Card Fields payment", submitError);
    }
  }, [cardFieldsError, submitError]);

  const handleSubmit = async () => {
    const { orderId } = await handleCreateOrder();
    await submit(orderId);
  };

  return (
    <div>
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          gap: "1rem",
        }}
      >
        <PayPalCardNumberField
          containerStyles={{
            height: "3rem",
          }}
          placeholder="Enter card number"
        />
        <PayPalCardExpiryField
          containerStyles={{
            height: "3rem",
          }}
          placeholder="MM/YY"
        />
        <PayPalCardCvvField
          containerStyles={{
            height: "3rem",
          }}
          placeholder="Enter CVV"
        />
      </div>
      {!cardFieldsError && (
        <button className="card-fields-pay-button" onClick={handleSubmit}>
          Pay
        </button>
      )}
    </div>
  );
};

export default PayPalCardFieldsOneTimePayment;
```

### `usePayPalCardFieldsSavePaymentSession()` [#usepaypalcardfieldssavepaymentsession]

`usePayPalCardFieldsSavePaymentSession` submits card field data to save a payment method.

#### Returns [#returns-4]

Property

Type

Description

submit

(vaultSetupToken: string | Promise\<string>, options?) =>
Promise\<void>

Submit the card fields for vaulting

submitResponse

object | null

The response from the submit operation

error

Error | null

Any error that occurred

#### Example [#example-15]

The following example renders card fields and submits the card data to save it as a vaulted payment method.

```tsx Save payment method
import {
  PayPalCardCvvField,
  PayPalCardExpiryField,
  PayPalCardNumberField,
  usePayPalCardFields,
  usePayPalCardFieldsSavePaymentSession,
} from "@paypal/react-paypal-js/sdk-v6";
import { useEffect } from "react";
import { createCardVaultToken } from "../../../utils";

const PayPalCardFieldsSavePayment = () => {
  const { error: cardFieldsError } = usePayPalCardFields();
  const {
    error: submitError,
    submit,
    submitResponse,
  } = usePayPalCardFieldsSavePaymentSession();

  useEffect(() => {
    if (!submitResponse) {
      return;
    }

    const { vaultSetupToken, message } = submitResponse.data;

    switch (submitResponse.state) {
      case "succeeded":
        console.log(
          `Save payment method succeeded: vaultSetupToken: ${vaultSetupToken}`,
        );
        break;
      case "failed":
        console.error(
          `Save payment method failed: vaultSetupToken: ${vaultSetupToken}, message: ${message}`,
        );
        break;
    }
  }, [submitResponse]);

  useEffect(() => {
    if (cardFieldsError) {
      console.error("Error loading PayPal Card Fields", cardFieldsError);
    }
    if (submitError) {
      console.error("Error submitting PayPal Card Fields payment", submitError);
    }
  }, [cardFieldsError, submitError]);

  const handleSubmit = async () => {
    const { vaultSetupToken } = await createCardVaultToken();
    await submit(vaultSetupToken);
  };

  return (
    <div>
      <div
        style={{
          display: "flex",
          flexDirection: "column",
          gap: "1rem",
        }}
      >
        <PayPalCardNumberField
          containerStyles={{
            height: "3rem",
          }}
          placeholder="Enter card number"
        />
        <PayPalCardExpiryField
          containerStyles={{
            height: "3rem",
          }}
          placeholder="MM/YY"
        />
        <PayPalCardCvvField
          containerStyles={{
            height: "3rem",
          }}
          placeholder="Enter CVV"
        />
      </div>
      {!cardFieldsError && (
        <button className="card-fields-pay-button" onClick={handleSubmit}>
          Save Payment Method
        </button>
      )}
    </div>
  );
};

export default PayPalCardFieldsSavePayment;
```

## Server utilities [#server-utilities]

### `useFetchEligibleMethods(options)` [#usefetcheligiblemethodsoptions]

`useFetchEligibleMethods` pre-fetches eligible payment methods on the server. Import from `@paypal/react-paypal-js/sdk-v6/server`.

#### Parameters [#parameters-2]

Parameter

Required

Description

options.headers

no

HeadersInit. HTTP headers including the{" "}
Authorization bearer token

options.environment

yes

string. Target environment ("sandbox" or{" "}
"production")

options.payload

no

object. Optional request payload with customer and
purchase details

options.signal

no

AbortSignal. Optional abort signal

#### Example [#example-16]

The following example pre-fetches eligible payment methods on the server and passes the result to `PayPalProvider`.

#### Implementation

```tsx
import { useFetchEligibleMethods } from "@paypal/react-paypal-js/sdk-v6/server";

// In a server component or loader
const eligibleMethodsResponse = await useFetchEligibleMethods({
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${clientToken}`,
  },
  environment: "sandbox",
  payload: {
    purchase_units: [{ amount: { currency_code: "USD", value: "100.00" } }],
  },
});

// Pass to provider
<PayPalProvider
  eligibleMethodsResponse={eligibleMethodsResponse}
  clientToken={token}
  pageType="checkout"
>
  <Checkout />
</PayPalProvider>;
```

#### Types

```tsx
type FindEligiblePaymentMethodsRequestPayload = {
  customer?: {
    channel?: {
      browser_type?: string;
      client_os?: string;
      device_type?: string;
    };
    country_code?: string;
    id?: string;
    email?: string;
    phone?: PhoneNumber;
  };
  purchase_units?: ReadonlyArray<{
    amount: {
      currency_code: string;
      value?: string;
    };
    payee?: {
      client_id?: string;
      display_data?: {
        business_email?: string;
        business_phone?: PhoneNumber & {
          extension_number: string;
        };
        brand_name?: string;
      };
      email_address?: string;
      merchant_id?: string;
    };
  }>;
  preferences?: {
    // runs advanced customer eligibility checks when set to true
    include_account_details?: boolean;
    include_vault_tokens?: boolean;
    payment_flow?: PaymentFlow;
    payment_source_constraint?: {
      constraint_type: string;
      payment_sources: Uppercase<EligiblePaymentMethods>[];
    };
  };
  shopper_session_id?: string;
};
```

## Types [#types]

The following types define the data structures passed to and from SDK callbacks.

### OnApproveDataOneTimePayments [#onapprovedataonetimepayments]

Data passed to `onApprove` for one-time payments.

Property

Type

Description

orderId

string

The PayPal order ID

payerId

string (optional)

The PayPal payer ID

billingToken

string (optional)

The billing token

### OnApproveDataSubscriptions [#onapprovedatasubscriptions]

Data passed to `onApprove` for subscription payments.

Property

Type

Description

subscriptionId

string

The PayPal subscription ID

payerId

string (optional)

The PayPal payer ID

### OnApproveDataSavePayments [#onapprovedatasavepayments]

Data passed to `onApprove` for save payment operations.

Property

Type

Description

vaultSetupToken

string

Token representing the saved payment method

payerId

string (optional)

The PayPal payer ID

### OnCancelDataOneTimePayments [#oncanceldataonetimepayments]

Data passed to `onCancel` for one-time payments.

Property

Type

Description

orderId

string (optional)

The PayPal order ID

### OnCancelDataSavePayments [#oncanceldatasavepayments]

Data passed to `onCancel` for save payment operations.

Property

Type

Description

vaultSetupToken

string (optional)

The vault setup token

### OnErrorData [#onerrordata]

Data passed to `onError` when an error occurs. Extends `Error`.

Property

Type

Description

code

string

Error code

name

string

Error name

message

string

Error message

isRecoverable

boolean

Whether the error is recoverable

### OnCompleteData [#oncompletedata]

Data passed to `onComplete` when payment session completes.

Property

Type

Description

paymentSessionState

string

Session result. Values are "approved",{" "}
"canceled", or "error"

### BasePaymentSessionReturn [#basepaymentsessionreturn]

Return type for all payment session hooks.

Property

Type

Description

error

Error | null

Any session error

isPending

boolean

Whether the SDK instance is still loading

handleClick

() => Promise\<\{ redirectURL?: string } | void>

Starts the payment session

handleCancel

() => void

Cancels the session

handleDestroy

() => void

Cleans up the session

### EventPayload [#eventpayload]

Data passed to Card Fields event callbacks such as `blur`, `focus`, `change`, and `validitychange`.

Property

Type

Description

data

EventState

The state of the card fields when the event was triggered

sender

CardFieldTypes

The card field that triggered the event: "number",{" "}
"expiry", or "cvv"

### EventState [#eventstate]

The state of all card fields at the time an event is triggered.

Property

Type

Description

cards

Card[]

Detected card types based on the current card number input

emittedBy

CardFieldTypes

The card field that emitted the event: "number",{" "}
"expiry", or "cvv"

number

FieldState

State of the card number field

cvv

FieldState

State of the CVV field

expiry

FieldState

State of the expiry field

### FieldState [#fieldstate]

The state of an individual card field.

Property

Type

Description

isFocused

boolean

Whether the field currently has focus

isValid

boolean

Whether the field value is valid

isEmpty

boolean

Whether the field is empty

isPotentiallyValid

boolean

Whether the field value could become valid with additional input

### Card [#card]

Represents a detected card type based on the current card number input.

Property

Type

Description

niceType

string

Human-readable card name, for example, "Visa"

type

string

Machine-readable card type, for example, "visa"

code.name

string

Security code label for the card type, for example, "CVV"{" "}
or "CID"

code.size

number

Expected length of the security code, for example, 3 or{" "}
4

## INSTANCE\_LOADING\_STATE [#instance_loading_state]

Enum for SDK loading states. Use with `usePayPal()` to check SDK readiness.

Value

Description

INSTANCE_LOADING_STATE.PENDING

SDK is loading

INSTANCE_LOADING_STATE.RESOLVED

SDK loaded successfully

INSTANCE_LOADING_STATE.REJECTED

SDK failed to load

#### Example [#example-17]

The following example checks the SDK loading state and renders different UI for each state.

```tsx
import {
  INSTANCE_LOADING_STATE,
  usePayPal,
} from "@paypal/react-paypal-js/sdk-v6";

function Component() {
  const { loadingStatus } = usePayPal();

  if (loadingStatus === INSTANCE_LOADING_STATE.PENDING) {
    return <div>Loading...</div>;
  }

  if (loadingStatus === INSTANCE_LOADING_STATE.REJECTED) {
    return <div>Failed to load PayPal SDK</div>;
  }

  return <div>Ready to process payments</div>;
}
```

## Common patterns [#common-patterns]

The following examples cover common integration patterns for error handling, eligibility checks, and conditional rendering.

### Error handling [#error-handling]

The following example shows how to capture error details, log them, and conditionally prompt a retry if the error is recoverable.

```tsx
import {
  PayPalOneTimePaymentButton,
  type OnErrorData,
} from "@paypal/react-paypal-js/sdk-v6";

function Payment() {
  const handleError = (error: OnErrorData) => {
    console.error("Payment failed:", error.message);
    if (error.isRecoverable) {
      // Prompt user to retry
    }
  };

  return (
    <PayPalOneTimePaymentButton
      createOrder={createOrder}
      onApprove={handleApprove}
      onError={handleError}
      presentationMode="auto"
    />
  );
}
```

### Checking payment eligibility [#checking-payment-eligibility]

The following example checks payment method availability for the current user and conditionally renders payment buttons based on eligibility.

```tsx
import { useEligibleMethods } from "@paypal/react-paypal-js/sdk-v6";

function CheckoutFlow() {
  const { eligiblePaymentMethods, isLoading } = useEligibleMethods();

  if (isLoading) return <div>Loading...</div>;

  return (
    <>
      <PayPalOneTimePaymentButton {...props} />
      {eligiblePaymentMethods?.isEligible("venmo") && (
        <VenmoOneTimePaymentButton {...props} />
      )}
      {eligiblePaymentMethods?.isEligible("paylater") && (
        <PayLaterOneTimePaymentButton {...props} />
      )}
    </>
  );
}
```

### Conditional rendering based on loading state [#conditional-rendering-based-on-loading-state]

The following example renders loading indicators while the PayPal SDK initializes and displays payment components only when ready.

```tsx
function Checkout() {
  const { loadingStatus } = usePayPal();

  const isLoading = loadingStatus === INSTANCE_LOADING_STATE.PENDING;

  return isLoading ? (
    <div>Initializing payment methods...</div>
  ) : (
    <PaymentButtons />
  );
}
```

### Using orderId instead of createOrder [#using-orderid-instead-of-createorder]

All one-time payment buttons support passing a pre-created `orderId` directly instead of a `createOrder` callback.

```tsx
<PayPalOneTimePaymentButton
  orderId="ORDER-123"
  onApprove={handleApprove}
  presentationMode="auto"
/>
```

### Using vaultSetupToken instead of createVaultToken [#using-vaultsetuptoken-instead-of-createvaulttoken]

Save payment buttons support passing a pre-created `vaultSetupToken` directly.

```tsx
<PayPalSavePaymentButton
  vaultSetupToken="VAULT-TOKEN-123"
  onApprove={handleApprove}
  presentationMode="auto"
/>
```
