> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paypal.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 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](/reference/sdk/js/v6/reference).
  * For setup and initialization, see [Set up JavaScript SDK v6](/developer/how-to/sdk/js/v6/configuration).
  * Check out our [GitHub sample integration with client-side React.](https://github.com/paypal-examples/v6-web-sdk-sample-integration/tree/main/client/prebuiltPages/react).
</Tip>

## PayPalProvider

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

### Props

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>clientId</code></td>
      <td><code>string | Promise\<string> | undefined</code></td>

      <td>
        <p>PayPal client ID for authenticating SDK requests. Use either <code>clientId</code> or <code>clientToken</code>, not both</p>
      </td>
    </tr>

    <tr>
      <td><code>clientToken</code></td>
      <td><code>string | Promise\<string> | undefined</code></td>

      <td>
        <p>PayPal client token for authenticating SDK requests. Use either <code>clientId</code> or <code>clientToken</code>, not both.</p>
      </td>
    </tr>

    <tr>
      <td><code>components</code></td>
      <td><code>string\[]</code></td>

      <td>
        <p>Array of components to load: <code>"paypal-payments"</code> (default), <code>"venmo-payments"</code>, <code>"paypal-subscriptions"</code>, <code>"paypal-guest-payments"</code>, and <code>"card-fields"</code></p>
      </td>
    </tr>

    <tr>
      <td><code>pageType</code></td>
      <td><code>string</code></td>

      <td>
        <p>Page context type, for example, <code>"checkout"</code></p>
      </td>
    </tr>

    <tr>
      <td><code>locale</code></td>
      <td><code>string</code></td>

      <td>
        <p>Locale for the SDK, for example, <code>"en\_US"</code></p>
      </td>
    </tr>

    <tr>
      <td><code>clientMetadataId</code></td>
      <td><code>string</code></td>

      <td>
        <p>Client metadata ID for tracking</p>
      </td>
    </tr>

    <tr>
      <td><code>partnerAttributionId</code></td>
      <td><code>string</code></td>

      <td>
        <p>Partner attribution ID</p>
      </td>
    </tr>

    <tr>
      <td><code>shopperSessionId</code></td>
      <td><code>string</code></td>

      <td>
        <p>Shopper session ID for personalization</p>
      </td>
    </tr>

    <tr>
      <td><code>testBuyerCountry</code></td>
      <td><code>string</code></td>

      <td>
        <p>Test buyer country for sandbox testing</p>
      </td>
    </tr>

    <tr>
      <td><code>merchantId</code></td>
      <td><code>string | string\[]</code></td>

      <td>
        <p>Merchant ID or array of merchant IDs</p>
      </td>
    </tr>

    <tr>
      <td><code>eligibleMethodsResponse</code></td>
      <td><code>object</code></td>

      <td>
        <p>Pre-fetched eligible methods response from server-side <code>useFetchEligibleMethods</code></p>
      </td>
    </tr>

    <tr>
      <td><code>environment</code></td>
      <td><code>string</code></td>

      <td>
        <p>Target environment: <code>"sandbox"</code> or <code>"production"</code></p>
      </td>
    </tr>

    <tr>
      <td><code>debug</code></td>
      <td><code>boolean</code></td>

      <td>
        <p>Enable debug mode</p>
      </td>
    </tr>

    <tr>
      <td><code>dataNamespace</code></td>
      <td><code>string</code></td>

      <td>
        <p>Custom namespace for the SDK data attribute</p>
      </td>
    </tr>
  </tbody>
</table>

<Warning>
  Pass a stable promise reference for `clientToken` and `clientId`. A new reference on every render causes the SDK to re-initialize. Use `useMemo` or store the promise in state.
</Warning>

### 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.
</Tip>

<CodeGroup>
  ```tsx lines expandable Client ID example theme={null}
  import { PayPalProvider } from "@paypal/react-paypal-js/sdk-v6";

  function App() {
    return (
      <PayPalProvider
        clientId="YOUR_PAYPAL_CLIENT_ID"
        components={["paypal-payments", "venmo-payments", "paypal-subscriptions"]}
        pageType="checkout"
      >
        {/* Child components */}
      </PayPalProvider>
    );
  }
  ```

  ```tsx lines expandable Client token example theme={null}
  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}
        components={["paypal-payments"]}
        pageType="checkout"
      >
        {/* Child components */}
      </PayPalProvider>
    );
  }
  ```
</CodeGroup>

## 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` provides access to the PayPal SDK state and payment eligibility information. Must be used within a `PayPalProvider`.

#### Returns

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>loadingStatus</code></td>
      <td><code>INSTANCE\_LOADING\_STATE</code></td>
      <td>Current SDK loading state: <code>INSTANCE\_LOADING\_STATE</code> <a href="#instance-loading-state">enum values</a></td>
    </tr>

    <tr>
      <td><code>eligiblePaymentMethods</code></td>
      <td><code>object | null</code></td>
      <td>Available payment methods for the current user</td>
    </tr>

    <tr>
      <td><code>sdkInstance</code></td>
      <td><code>object | null</code></td>
      <td>The underlying SDK instance</td>
    </tr>

    <tr>
      <td><code>error</code></td>
      <td><code>Error | null</code></td>
      <td>Any error that occurred during SDK initialization</td>
    </tr>

    <tr>
      <td><code>isHydrated</code></td>
      <td><code>boolean</code></td>
      <td>Whether the component has been hydrated on the client</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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)`

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

#### Parameters

<table>
  <thead>
    <tr>
      <th align="left">Parameter</th>
      <th align="left">Required</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>payload.amount</code></td>
      <td>no</td>

      <td>
        <p><strong>string.</strong> Order amount, for example, <code>"95.00"</code></p>
      </td>
    </tr>

    <tr>
      <td><code>payload.currencyCode</code></td>
      <td>no</td>

      <td>
        <p><strong>string.</strong> Three-letter ISO 4217 currency code, for example, <code>"USD"</code></p>
      </td>
    </tr>

    <tr>
      <td><code>payload.paymentFlow</code></td>
      <td>no</td>

      <td>
        <p><strong>string.</strong> The payment flow type: <code>"ONE\_TIME\_PAYMENT"</code>, <code>"RECURRING\_PAYMENT"</code>, <code>"VAULT\_WITH\_PAYMENT"</code>, or <code>"VAULT\_WITHOUT\_PAYMENT"</code></p>
      </td>
    </tr>
  </tbody>
</table>

#### Returns

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>eligiblePaymentMethods</code></td>
      <td><code>object | null</code></td>
      <td>Available payment methods for the current user. <ul><li>To retrieve product-specific details, call <code>.getDetails("")</code>.</li><li>To check eligibility for a specific payment method, call <code>.isEligible("")</code>.</li></ul></td>
    </tr>

    <tr>
      <td><code>isLoading</code></td>
      <td><code>boolean</code></td>
      <td>Whether eligibility data is still being fetched</td>
    </tr>

    <tr>
      <td><code>error</code></td>
      <td><code>Error | null</code></td>
      <td>Any error that occurred during the fetch</td>
    </tr>
  </tbody>
</table>

#### Example

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 lines expandable theme={null}
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)`

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

#### Parameters

<table>
  <thead>
    <tr>
      <th align="left">Parameter</th>
      <th align="left">Required</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>buyerCountry</code></td>
      <td>no</td>
      <td><p><strong>string.</strong> Buyer's country code</p></td>
    </tr>

    <tr>
      <td><code>currencyCode</code></td>
      <td>no</td>
      <td><p><strong>string.</strong> Currency code</p></td>
    </tr>

    <tr>
      <td><code>shopperSessionId</code></td>
      <td>no</td>
      <td><p><strong>string.</strong> Shopper session ID</p></td>
    </tr>
  </tbody>
</table>

#### Returns

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>error</code></td>
      <td><code>Error | null</code></td>
      <td>Any session error</td>
    </tr>

    <tr>
      <td><code>isReady</code></td>
      <td><code>boolean</code></td>
      <td>Whether the session is created</td>
    </tr>

    <tr>
      <td><code>handleFetchContent</code></td>
      <td><code>function</code></td>
      <td>Fetches message content</td>
    </tr>

    <tr>
      <td><code>handleCreateLearnMore</code></td>
      <td><code>function</code></td>
      <td>Creates a learn more modal</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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 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.

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>error</code></td>
      <td><code>Error | null</code></td>
      <td>Any session error</td>
    </tr>

    <tr>
      <td><code>isPending</code></td>
      <td><code>boolean</code></td>
      <td>Whether the SDK instance is still loading</td>
    </tr>

    <tr>
      <td><code>handleClick</code></td>
      <td><code>() => Promise</code></td>
      <td>Starts the payment session</td>
    </tr>

    <tr>
      <td><code>handleCancel</code></td>
      <td><code>() => void</code></td>
      <td>Cancels the session</td>
    </tr>

    <tr>
      <td><code>handleDestroy</code></td>
      <td><code>() => void</code></td>
      <td>Cleans up the session</td>
    </tr>
  </tbody>
</table>

### `usePayPalOneTimePaymentSession`

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

```tsx lines expandable theme={null}
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`

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

```tsx lines expandable theme={null}
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`

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

```tsx lines expandable theme={null}
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`

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

```tsx lines expandable theme={null}
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` 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 lines expandable theme={null}
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`

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

```tsx lines expandable theme={null}
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`

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 lines expandable theme={null}
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`

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

```tsx lines expandable theme={null}
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`

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

```tsx lines expandable theme={null}
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

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` renders a button for one-time PayPal payments. It uses `usePayPalOneTimePaymentSession` internally.

#### Props

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>createOrder</code></td>
      <td><code>() => Promise\<\{ orderId: string }></code></td>
      <td>Function that calls your server to create a PayPal order and returns the resulting <code>orderId</code>. The component calls this function when the buyer clicks the button. Use either <code>createOrder</code> or <code>orderId</code>, not both.</td>
    </tr>

    <tr>
      <td><code>orderId</code></td>
      <td><code>string</code></td>
      <td>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 <code>createOrder</code> or <code>orderId</code>, not both.</td>
    </tr>

    <tr>
      <td><code>onApprove</code></td>
      <td><code>(data: OnApproveDataOneTimePayments) => Promise\<void></code></td>
      <td>Callback when payment is approved</td>
    </tr>

    <tr>
      <td><code>onCancel</code></td>
      <td><code>(data: OnCancelDataOneTimePayments) => void</code></td>
      <td>Callback when user cancels</td>
    </tr>

    <tr>
      <td><code>onError</code></td>
      <td><code>(data: OnErrorData) => void</code></td>
      <td>Callback on payment error</td>
    </tr>

    <tr>
      <td><code>onComplete</code></td>
      <td><code>(data: OnCompleteData) => void</code></td>
      <td>Callback when payment session completes</td>
    </tr>

    <tr>
      <td><code>presentationMode</code></td>
      <td><code>string</code></td>

      <td>
        <p><strong>string.</strong> Controls how the payment interface is displayed to the buyer.</p>
        <p>Available modes:</p>

        <ul>
          <li><code>auto</code> — Recommended. SDK automatically selects the best experience. Tries popup first and falls back to modal if popups are blocked.</li>
          <li><code>popup</code> — Opens PayPal in a popup window. May be blocked by popup blockers.</li>
          <li><code>modal</code> — 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.</li>
          <li><code>redirect</code> — Full page redirect to PayPal. Recommended for mobile devices. Requires a return/cancel URL.</li>
          <li><code>payment-handler</code> — Experimental. Uses the browser's Payment Handler API. Provides a native payment experience. Modern browsers only.</li>
        </ul>

        <p>Default: <code>auto</code></p>
        <p>The SDK will automatically fall back to alternative modes if the requested mode is unavailable.</p>
      </td>
    </tr>

    <tr>
      <td><code>fullPageOverlay</code></td>
      <td><code>\{ enabled: boolean }</code></td>
      <td>Whether to show a full-page overlay</td>
    </tr>

    <tr>
      <td><code>onShippingAddressChange</code></td>
      <td><code>(data: OnShippingAddressChangeData) => Promise\<void></code></td>
      <td>Callback when shipping address changes</td>
    </tr>

    <tr>
      <td><code>onShippingOptionsChange</code></td>
      <td><code>(data: OnShippingOptionsChangeData) => Promise\<void></code></td>
      <td>Callback when shipping options change</td>
    </tr>

    <tr>
      <td><code>type</code></td>
      <td><code>string</code></td>
      <td>Button type: <code>"pay"</code> (default), <code>"checkout"</code>, <code>"buynow"</code>, or <code>"donate"</code></td>
    </tr>

    <tr>
      <td><code>disabled</code></td>
      <td><code>boolean</code></td>
      <td>Whether the button is disabled</td>
    </tr>

    <tr>
      <td><code>savePayment</code></td>
      <td><code>boolean</code></td>
      <td>Whether to save the payment method during checkout</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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` renders a button for one-time Venmo payments (US only). It uses `useVenmoOneTimePaymentSession` internally.

#### Props

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

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>createOrder</code></td>
      <td><code>() => Promise\<\{ orderId: string }></code></td>
      <td>Function that calls your server to create a PayPal order and returns the resulting <code>orderId</code>. The component calls this function when the buyer clicks the button. Use either <code>createOrder</code> or <code>orderId</code>, not both.</td>
    </tr>

    <tr>
      <td><code>orderId</code></td>
      <td><code>string</code></td>
      <td>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 <code>createOrder</code> or <code>orderId</code>, not both.</td>
    </tr>

    <tr>
      <td><code>onApprove</code></td>
      <td><code>(data: OnApproveDataOneTimePayments) => Promise\<void></code></td>
      <td>Callback when payment is approved</td>
    </tr>

    <tr>
      <td><code>onCancel</code></td>
      <td><code>(data: OnCancelDataOneTimePayments) => void</code></td>
      <td>Callback when user cancels</td>
    </tr>

    <tr>
      <td><code>onError</code></td>
      <td><code>(data: OnErrorData) => void</code></td>
      <td>Callback on payment error</td>
    </tr>

    <tr>
      <td><code>onComplete</code></td>
      <td><code>(data: OnCompleteData) => void</code></td>
      <td>Callback when payment session completes</td>
    </tr>

    <tr>
      <td><code>presentationMode</code></td>
      <td><code>string</code></td>

      <td>
        <p><strong>string.</strong> Controls how the payment interface is displayed to the buyer.</p>
        <p>Available modes:</p>

        <ul>
          <li><code>auto</code> — Recommended. SDK automatically selects the best experience. Tries popup first and falls back to modal if popups are blocked.</li>
          <li><code>popup</code> — Opens PayPal in a popup window. May be blocked by popup blockers.</li>
          <li><code>modal</code> — 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.</li>
          <li><code>redirect</code> — Full page redirect to PayPal. Recommended for mobile devices. Requires a return/cancel URL.</li>
          <li><code>payment-handler</code> — Experimental. Uses the browser's Payment Handler API. Provides a native payment experience. Modern browsers only.</li>
        </ul>

        <p>Default: <code>auto</code></p>
        <p>The SDK will automatically fall back to alternative modes if the requested mode is unavailable.</p>
      </td>
    </tr>

    <tr>
      <td><code>fullPageOverlay</code></td>
      <td><code>\{ enabled: boolean }</code></td>
      <td>Whether to show a full-page overlay</td>
    </tr>

    <tr>
      <td><code>onShippingAddressChange</code></td>
      <td><code>(data: OnShippingAddressChangeData) => Promise\<void></code></td>
      <td>Callback when shipping address changes</td>
    </tr>

    <tr>
      <td><code>onShippingOptionsChange</code></td>
      <td><code>(data: OnShippingOptionsChangeData) => Promise\<void></code></td>
      <td>Callback when shipping options change</td>
    </tr>

    <tr>
      <td><code>type</code></td>
      <td><code>string</code></td>
      <td>Button type: <code>"pay"</code> (default), <code>"checkout"</code>, <code>"buynow"</code>, or <code>"donate"</code></td>
    </tr>

    <tr>
      <td><code>disabled</code></td>
      <td><code>boolean</code></td>
      <td>Whether the button is disabled</td>
    </tr>

    <tr>
      <td><code>savePayment</code></td>
      <td><code>boolean</code></td>
      <td>Whether to save the payment method during checkout</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
import { VenmoOneTimePaymentButton } from "@paypal/react-paypal-js/sdk-v6";

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

### 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

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>createOrder</code></td>
      <td><code>() => Promise\<\{ orderId: string }></code></td>
      <td>Function that calls your server to create a PayPal order and returns the resulting <code>orderId</code>. The component calls this function when the buyer clicks the button. Use either <code>createOrder</code> or <code>orderId</code>, not both.</td>
    </tr>

    <tr>
      <td><code>orderId</code></td>
      <td><code>string</code></td>
      <td>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 <code>createOrder</code> or <code>orderId</code>, not both.</td>
    </tr>

    <tr>
      <td><code>onApprove</code></td>
      <td><code>(data: OnApproveDataOneTimePayments) => Promise\<void></code></td>
      <td>Callback when payment is approved</td>
    </tr>

    <tr>
      <td><code>onCancel</code></td>
      <td><code>(data: OnCancelDataOneTimePayments) => void</code></td>
      <td>Callback when user cancels</td>
    </tr>

    <tr>
      <td><code>onError</code></td>
      <td><code>(data: OnErrorData) => void</code></td>
      <td>Callback on payment error</td>
    </tr>

    <tr>
      <td><code>onComplete</code></td>
      <td><code>(data: OnCompleteData) => void</code></td>
      <td>Callback when payment session completes</td>
    </tr>

    <tr>
      <td><code>presentationMode</code></td>
      <td><code>string</code></td>

      <td>
        <p><strong>string.</strong> Controls how the payment interface is displayed to the buyer.</p>
        <p>Available modes:</p>

        <ul>
          <li><code>auto</code> — Recommended. SDK automatically selects the best experience. Tries popup first and falls back to modal if popups are blocked.</li>
          <li><code>popup</code> — Opens PayPal in a popup window. May be blocked by popup blockers.</li>
          <li><code>modal</code> — 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.</li>
          <li><code>redirect</code> — Full page redirect to PayPal. Recommended for mobile devices. Requires a return/cancel URL.</li>
          <li><code>payment-handler</code> — Experimental. Uses the browser's Payment Handler API. Provides a native payment experience. Modern browsers only.</li>
        </ul>

        <p>Default: <code>auto</code></p>
        <p>The SDK will automatically fall back to alternative modes if the requested mode is unavailable.</p>
      </td>
    </tr>

    <tr>
      <td><code>disabled</code></td>
      <td><code>boolean</code></td>
      <td>Whether the button is disabled</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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` 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

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>createOrder</code></td>
      <td><code>() => Promise\<\{ orderId: string }></code></td>
      <td>Function that calls your server to create a PayPal order and returns the resulting <code>orderId</code>. The component calls this function when the buyer clicks the button. Use either <code>createOrder</code> or <code>orderId</code>, not both.</td>
    </tr>

    <tr>
      <td><code>orderId</code></td>
      <td><code>string</code></td>
      <td>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 <code>createOrder</code> or <code>orderId</code>, not both.</td>
    </tr>

    <tr>
      <td><code>onApprove</code></td>
      <td><code>(data: OnApproveDataOneTimePayments) => Promise\<void></code></td>
      <td>Callback when payment is approved</td>
    </tr>

    <tr>
      <td><code>onCancel</code></td>
      <td><code>(data: OnCancelDataOneTimePayments) => void</code></td>
      <td>Callback when user cancels</td>
    </tr>

    <tr>
      <td><code>onError</code></td>
      <td><code>(data: OnErrorData) => void</code></td>
      <td>Callback on payment error</td>
    </tr>

    <tr>
      <td><code>onComplete</code></td>
      <td><code>(data: OnCompleteData) => void</code></td>
      <td>Callback when payment session completes</td>
    </tr>

    <tr>
      <td><code>presentationMode</code></td>
      <td><code>string</code></td>

      <td>
        <p><strong>string.</strong> Controls how the payment interface is displayed to the buyer.</p>
        <p>Available modes:</p>

        <ul>
          <li><code>auto</code> — Recommended. SDK automatically selects the best experience. Tries popup first and falls back to modal if popups are blocked.</li>
          <li><code>popup</code> — Opens PayPal in a popup window. May be blocked by popup blockers.</li>
          <li><code>modal</code> — 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.</li>
          <li><code>redirect</code> — Full page redirect to PayPal. Recommended for mobile devices. Requires a return/cancel URL.</li>
          <li><code>payment-handler</code> — Experimental. Uses the browser's Payment Handler API. Provides a native payment experience. Modern browsers only.</li>
        </ul>

        <p>Default: <code>auto</code></p>
        <p>The SDK will automatically fall back to alternative modes if the requested mode is unavailable.</p>
      </td>
    </tr>

    <tr>
      <td><code>disabled</code></td>
      <td><code>boolean</code></td>
      <td>Whether the button is disabled</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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` 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.
</Note>

#### Props

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>createOrder</code></td>
      <td><code>() => Promise\<\{ orderId: string }></code></td>
      <td>Function that calls your server to create a PayPal order and returns the resulting <code>orderId</code>. The component calls this function when the buyer clicks the button. Use either <code>createOrder</code> or <code>orderId</code>, not both</td>
    </tr>

    <tr>
      <td><code>orderId</code></td>
      <td><code>string</code></td>
      <td>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 <code>createOrder</code> or <code>orderId</code>, not both</td>
    </tr>

    <tr>
      <td><code>onApprove</code></td>
      <td><code>(data: OnApproveDataOneTimePayments) => Promise\<void></code></td>
      <td>Callback when payment is approved</td>
    </tr>

    <tr>
      <td><code>onCancel</code></td>
      <td><code>(data: OnCancelDataOneTimePayments) => void</code></td>
      <td>Callback when user cancels</td>
    </tr>

    <tr>
      <td><code>onError</code></td>
      <td><code>(data: OnErrorData) => void</code></td>
      <td>Callback on payment error</td>
    </tr>

    <tr>
      <td><code>onComplete</code></td>
      <td><code>(data: OnCompleteData) => void</code></td>
      <td>Callback when payment session completes</td>
    </tr>

    <tr>
      <td><code>fullPageOverlay</code></td>
      <td><code>\{ enabled: boolean }</code></td>
      <td>Whether to show a full-page overlay</td>
    </tr>

    <tr>
      <td><code>onShippingAddressChange</code></td>
      <td><code>(data: OnShippingAddressChangeData) => Promise\<void></code></td>
      <td>Callback when shipping address changes</td>
    </tr>

    <tr>
      <td><code>onShippingOptionsChange</code></td>
      <td><code>(data: OnShippingOptionsChangeData) => Promise\<void></code></td>
      <td>Callback when shipping options change</td>
    </tr>

    <tr>
      <td><code>disabled</code></td>
      <td><code>boolean</code></td>
      <td>Whether the button is disabled</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
import { PayPalGuestPaymentButton } from "@paypal/react-paypal-js/sdk-v6";

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

### PayPalSavePaymentButton

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

#### Props

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>createVaultToken</code></td>
      <td><code>() => Promise\<\{ vaultSetupToken: string }></code></td>
      <td>Function that creates a vault setup token and returns an object with its ID. Use either <code>createVaultToken</code> or <code>vaultSetupToken</code>, not both.</td>
    </tr>

    <tr>
      <td><code>vaultSetupToken</code></td>
      <td><code>string</code></td>
      <td>Pre-created vault setup token. Use either <code>createVaultToken</code> or <code>vaultSetupToken</code>, not both.</td>
    </tr>

    <tr>
      <td><code>onApprove</code></td>
      <td><code>(data: OnApproveDataSavePayments) => Promise\<void></code></td>
      <td>Callback when payment method is saved</td>
    </tr>

    <tr>
      <td><code>onCancel</code></td>
      <td><code>(data: OnCancelDataSavePayments) => void</code></td>
      <td>Callback when user cancels</td>
    </tr>

    <tr>
      <td><code>onError</code></td>
      <td><code>(data: OnErrorData) => void</code></td>
      <td>Callback on error</td>
    </tr>

    <tr>
      <td><code>onComplete</code></td>
      <td><code>(data: OnCompleteData) => void</code></td>
      <td>Callback when session completes</td>
    </tr>

    <tr>
      <td><code>presentationMode</code></td>
      <td><code>string</code></td>

      <td>
        <p>Controls how the payment interface is displayed to the buyer.</p>
        <p>Available modes:</p>

        <ul>
          <li><code>auto</code> (default) — Recommended. SDK automatically selects the best experience. Tries popup first and falls back to modal if popups are blocked.</li>
          <li><code>popup</code> — Opens PayPal in a popup window. May be blocked by popup blockers.</li>
          <li><code>modal</code> — 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.</li>
          <li><code>redirect</code> — Full page redirect to PayPal. Recommended for mobile devices. Requires a return/cancel URL.</li>
          <li><code>payment-handler</code> — Experimental. Uses the browser's Payment Handler API. Provides a native payment experience. Modern browsers only.</li>
        </ul>

        <p>The SDK will automatically fall back to alternative modes if the requested mode is unavailable.</p>
      </td>
    </tr>

    <tr>
      <td><code>type</code></td>
      <td><code>string</code></td>
      <td>Button type. Defaults to <code>"pay"</code></td>
    </tr>

    <tr>
      <td><code>disabled</code></td>
      <td><code>boolean</code></td>
      <td>Whether the button is disabled</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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` 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

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>createVaultToken</code></td>
      <td><code>() => Promise\<\{ vaultSetupToken: string }></code></td>
      <td>Function that creates a vault setup token and returns an object with its ID. Use either <code>createVaultToken</code> or <code>vaultSetupToken</code>, not both.</td>
    </tr>

    <tr>
      <td><code>vaultSetupToken</code></td>
      <td><code>string</code></td>
      <td>Pre-created vault setup token. Use either <code>createVaultToken</code> or <code>vaultSetupToken</code>, not both.</td>
    </tr>

    <tr>
      <td><code>onApprove</code></td>
      <td><code>(data: OnApproveDataSavePayments) => Promise\<void></code></td>
      <td>Callback when payment method is saved</td>
    </tr>

    <tr>
      <td><code>onCancel</code></td>
      <td><code>(data: OnCancelDataSavePayments) => void</code></td>
      <td>Callback when user cancels</td>
    </tr>

    <tr>
      <td><code>onError</code></td>
      <td><code>(data: OnErrorData) => void</code></td>
      <td>Callback on error</td>
    </tr>

    <tr>
      <td><code>onComplete</code></td>
      <td><code>(data: OnCompleteData) => void</code></td>
      <td>Callback when session completes</td>
    </tr>

    <tr>
      <td><code>presentationMode</code></td>
      <td><code>string</code></td>

      <td>
        <p>Controls how the payment interface is displayed to the buyer.</p>
        <p>Available modes:</p>

        <ul>
          <li><code>auto</code> (default) — Recommended. SDK automatically selects the best experience. Tries popup first and falls back to modal if popups are blocked.</li>
          <li><code>popup</code> — Opens PayPal in a popup window. May be blocked by popup blockers.</li>
          <li><code>modal</code> — 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.</li>
          <li><code>redirect</code> — Full page redirect to PayPal. Recommended for mobile devices. Requires a return/cancel URL.</li>
          <li><code>payment-handler</code> — Experimental. Uses the browser's Payment Handler API. Provides a native payment experience. Modern browsers only.</li>
        </ul>

        <p>The SDK will automatically fall back to alternative modes if the requested mode is unavailable.</p>
      </td>
    </tr>

    <tr>
      <td><code>type</code></td>
      <td><code>string</code></td>
      <td>Button type. Defaults to <code>"pay"</code></td>
    </tr>

    <tr>
      <td><code>disabled</code></td>
      <td><code>boolean</code></td>
      <td>Whether the button is disabled</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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` renders a button that creates subscriptions.

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

#### Props

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>createSubscription</code></td>
      <td><code>() => Promise\<\{ subscriptionId: string }></code></td>
      <td>Function that creates a subscription and returns an object with <code>subscriptionId</code></td>
    </tr>

    <tr>
      <td><code>onApprove</code></td>
      <td><code>(data: OnApproveDataSubscriptions) => Promise\<void></code></td>
      <td>Callback when subscription is approved. Receives <code>subscriptionId</code> and <code>payerId</code></td>
    </tr>

    <tr>
      <td><code>onCancel</code></td>
      <td><code>(data: OnCancelDataOneTimePayments) => void</code></td>
      <td>Callback when user cancels</td>
    </tr>

    <tr>
      <td><code>onError</code></td>
      <td><code>(data: OnErrorData) => void</code></td>
      <td>Callback on error</td>
    </tr>

    <tr>
      <td><code>onComplete</code></td>
      <td><code>(data: OnCompleteData) => void</code></td>
      <td>Callback when session completes</td>
    </tr>

    <tr>
      <td><code>presentationMode</code></td>
      <td><code>string</code></td>

      <td>
        <p>Controls how the payment interface is displayed to the buyer.</p>
        <p>Available modes:</p>

        <ul>
          <li><code>auto</code> (default) — Recommended. SDK automatically selects the best experience. Tries popup first and falls back to modal if popups are blocked.</li>
          <li><code>popup</code> — Opens PayPal in a popup window. May be blocked by popup blockers.</li>
          <li><code>modal</code> — 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.</li>
          <li><code>redirect</code> — Full page redirect to PayPal. Recommended for mobile devices. Requires a return/cancel URL.</li>
          <li><code>payment-handler</code> — Experimental. Uses the browser's Payment Handler API. Provides a native payment experience. Modern browsers only.</li>
        </ul>

        <p>The SDK will automatically fall back to alternative modes if the requested mode is unavailable.</p>
      </td>
    </tr>

    <tr>
      <td><code>type</code></td>
      <td><code>string</code></td>
      <td>Button type. Defaults to <code>"subscribe"</code></td>
    </tr>

    <tr>
      <td><code>disabled</code></td>
      <td><code>boolean</code></td>
      <td>Whether the button is disabled</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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` renders a native `<apple-pay-button>` element for Apple Pay payments with Safari-compatible styling.

#### Props

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>applePayConfig</code></td>
      <td><code>ApplePayConfig</code></td>
      <td>Apple Pay configuration from <code>findEligibleMethods</code></td>
    </tr>

    <tr>
      <td><code>paymentRequest</code></td>
      <td><code>ApplePayPaymentRequest</code></td>
      <td>Payment request with country, currency, and total</td>
    </tr>

    <tr>
      <td><code>applePaySessionVersion</code></td>
      <td><code>number</code></td>
      <td>Apple Pay JS API version (4 or later)</td>
    </tr>

    <tr>
      <td><code>createOrder</code></td>
      <td><code>() => Promise\<\{ orderId: string }></code></td>
      <td>Function that creates an order</td>
    </tr>

    <tr>
      <td><code>onApprove</code></td>
      <td><code>(data: ConfirmOrderResponse) => void</code></td>
      <td>Callback when payment is approved</td>
    </tr>

    <tr>
      <td><code>onCancel</code></td>
      <td><code>() => void</code></td>
      <td>Callback when payment is cancelled</td>
    </tr>

    <tr>
      <td><code>onError</code></td>
      <td><code>(error: Error) => void</code></td>
      <td>Callback on error</td>
    </tr>

    <tr>
      <td><code>displayName</code></td>
      <td><code>string</code></td>
      <td>Merchant display name</td>
    </tr>

    <tr>
      <td><code>domainName</code></td>
      <td><code>string</code></td>
      <td>Merchant domain name</td>
    </tr>

    <tr>
      <td><code>buttonstyle</code></td>
      <td><code>string</code></td>
      <td>Button style, for example, <code>"black"</code> (default) or <code>"white"</code></td>
    </tr>

    <tr>
      <td><code>type</code></td>
      <td><code>string</code></td>
      <td>Button type, for example, <code>"pay"</code> (default)</td>
    </tr>

    <tr>
      <td><code>locale</code></td>
      <td><code>string</code></td>
      <td>Locale, such as <code>"en"</code> (default)</td>
    </tr>

    <tr>
      <td><code>disabled</code></td>
      <td><code>boolean</code></td>
      <td>Whether the button is disabled</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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 let you render individual, PCI-compliant input fields for card number, expiration, and CVV within your checkout form.

### 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

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>children </code>(required)</td>
      <td><code>ReactNode</code></td>
      <td>Child components</td>
    </tr>

    <tr>
      <td><code>amount</code> </td>
      <td><code>\{ value?: string, currencyCode?: string }</code></td>
      <td>Order amount, which you can update dynamically</td>
    </tr>

    <tr>
      <td><code>isCobrandedEligible</code></td>
      <td><code>boolean</code></td>
      <td>Whether co-branded card eligibility is enabled</td>
    </tr>

    <tr>
      <td><code>blur</code></td>
      <td><code>(event) => void</code></td>
      <td>Callback when a card field loses focus</td>
    </tr>

    <tr>
      <td><code>validitychange</code></td>
      <td><code>(event) => void</code></td>
      <td>Callback when field validity changes</td>
    </tr>

    <tr>
      <td><code>cardtypechange</code></td>
      <td><code>(event) => void</code></td>
      <td>Callback when card type changes or is detected</td>
    </tr>

    <tr>
      <td><code>focus</code></td>
      <td><code>(event) => void</code></td>
      <td>Callback when a card field gains focus</td>
    </tr>

    <tr>
      <td><code>change</code></td>
      <td><code>(event) => void</code></td>
      <td>Callback when card field value changes</td>
    </tr>

    <tr>
      <td><code>empty</code></td>
      <td><code>(event) => void</code></td>
      <td>Callback when a card field is empty</td>
    </tr>

    <tr>
      <td><code>inputsubmit</code></td>
      <td><code>(event) => void</code></td>
      <td>Callback when a card field is submitted</td>
    </tr>

    <tr>
      <td><code>notempty</code></td>
      <td><code>(event) => void</code></td>
      <td>Callback when a card field is not empty</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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` renders a card number input field. Use within a `PayPalCardFieldsProvider`. All props are optional.

#### Props

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>placeholder</code></td>
      <td><code>string</code></td>
      <td>Input placeholder text</td>
    </tr>

    <tr>
      <td><code>label</code></td>
      <td><code>string</code></td>
      <td>Input label</td>
    </tr>

    <tr>
      <td><code>style</code></td>
      <td><code>object</code></td>
      <td>Custom styles</td>
    </tr>

    <tr>
      <td><code>ariaLabel</code></td>
      <td><code>string</code></td>
      <td>Accessibility label</td>
    </tr>

    <tr>
      <td><code>ariaDescription</code></td>
      <td><code>string</code></td>
      <td>Accessibility description</td>
    </tr>

    <tr>
      <td><code>ariaInvalidErrorMessage</code></td>
      <td><code>string</code></td>
      <td>Error message for screen readers</td>
    </tr>

    <tr>
      <td><code>containerStyles</code></td>
      <td><code>CSSProperties</code></td>
      <td>Styles for the container div</td>
    </tr>

    <tr>
      <td><code>containerClassName</code></td>
      <td><code>string</code></td>
      <td>Class name for the container div</td>
    </tr>
  </tbody>
</table>

### PayPalCardExpiryField

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

#### Props

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>placeholder</code></td>
      <td><code>string</code></td>
      <td>Input placeholder text</td>
    </tr>

    <tr>
      <td><code>label</code></td>
      <td><code>string</code></td>
      <td>Input label</td>
    </tr>

    <tr>
      <td><code>style</code></td>
      <td><code>object</code></td>
      <td>Custom styles</td>
    </tr>

    <tr>
      <td><code>ariaLabel</code></td>
      <td><code>string</code></td>
      <td>Accessibility label</td>
    </tr>

    <tr>
      <td><code>ariaDescription</code></td>
      <td><code>string</code></td>
      <td>Accessibility description</td>
    </tr>

    <tr>
      <td><code>ariaInvalidErrorMessage</code></td>
      <td><code>string</code></td>
      <td>Error message for screen readers</td>
    </tr>

    <tr>
      <td><code>containerStyles</code></td>
      <td><code>CSSProperties</code></td>
      <td>Styles for the container div</td>
    </tr>

    <tr>
      <td><code>containerClassName</code></td>
      <td><code>string</code></td>
      <td>Class name for the container div</td>
    </tr>
  </tbody>
</table>

### PayPalCardCvvField

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

#### Props

<table>
  <thead>
    <tr>
      <th align="left">Prop</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>placeholder</code></td>
      <td><code>string</code></td>
      <td>Input placeholder text</td>
    </tr>

    <tr>
      <td><code>label</code></td>
      <td><code>string</code></td>
      <td>Input label</td>
    </tr>

    <tr>
      <td><code>style</code></td>
      <td><code>object</code></td>
      <td>Custom styles</td>
    </tr>

    <tr>
      <td><code>ariaLabel</code></td>
      <td><code>string</code></td>
      <td>Accessibility label</td>
    </tr>

    <tr>
      <td><code>ariaDescription</code></td>
      <td><code>string</code></td>
      <td>Accessibility description</td>
    </tr>

    <tr>
      <td><code>ariaInvalidErrorMessage</code></td>
      <td><code>string</code></td>
      <td>Error message for screen readers</td>
    </tr>

    <tr>
      <td><code>containerStyles</code></td>
      <td><code>CSSProperties</code></td>
      <td>Styles for the container div</td>
    </tr>

    <tr>
      <td><code>containerClassName</code></td>
      <td><code>string</code></td>
      <td>Class name for the container div</td>
    </tr>
  </tbody>
</table>

### `usePayPalCardFields()`

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

### `usePayPalCardFieldsOneTimePaymentSession()`

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

#### Returns

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>submit</code></td>
      <td><code>(orderId: string | Promise\<string>, options?) => Promise\<void></code></td>
      <td>Submit the card fields for payment</td>
    </tr>

    <tr>
      <td><code>submitResponse</code></td>
      <td><code>object | null</code></td>
      <td>The response from the submit operation</td>
    </tr>

    <tr>
      <td><code>error</code></td>
      <td><code>Error | null</code></td>
      <td>Any error that occurred</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable One-time payment theme={null}
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` submits card field data to save a payment method.

#### Returns

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>submit</code></td>
      <td><code>(vaultSetupToken: string | Promise\<string>, options?) => Promise\<void></code></td>
      <td>Submit the card fields for vaulting</td>
    </tr>

    <tr>
      <td><code>submitResponse</code></td>
      <td><code>object | null</code></td>
      <td>The response from the submit operation</td>
    </tr>

    <tr>
      <td><code>error</code></td>
      <td><code>Error | null</code></td>
      <td>Any error that occurred</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable Save payment method theme={null}
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

### `useFetchEligibleMethods(options)`

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

#### Parameters

<table>
  <thead>
    <tr>
      <th align="left">Parameter</th>
      <th align="left">Required</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>options.headers</code></td>
      <td>yes</td>
      <td><p><strong>HeadersInit.</strong> HTTP headers including the <code>Authorization</code> bearer token</p></td>
    </tr>

    <tr>
      <td><code>options.environment</code></td>
      <td>yes</td>
      <td><p><strong>string.</strong> Target environment (<code>"sandbox"</code> or <code>"production"</code>)</p></td>
    </tr>

    <tr>
      <td><code>options.payload</code></td>
      <td>no</td>
      <td><p><strong>object.</strong> Optional request payload with customer and purchase details</p></td>
    </tr>

    <tr>
      <td><code>options.signal</code></td>
      <td>no</td>
      <td><p><strong>AbortSignal.</strong> Optional abort signal</p></td>
    </tr>
  </tbody>
</table>

#### Example

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

<CodeGroup>
  ```tsx Implementation lines expandable theme={null}
  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: {
      amount: "100.00",
      currencyCode: "USD",
    },
  });

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

  ```tsx Types lines expandable theme={null}
  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;
  };
  ```
</CodeGroup>

## Types

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

### OnApproveDataOneTimePayments

Data passed to `onApprove` for one-time payments

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>orderId</code></td>
      <td><code>string</code></td>
      <td>The PayPal order ID</td>
    </tr>

    <tr>
      <td><code>payerId</code></td>
      <td><code>string</code> (optional)</td>
      <td>The PayPal payer ID</td>
    </tr>

    <tr>
      <td><code>billingToken</code></td>
      <td><code>string</code> (optional)</td>
      <td>The billing token</td>
    </tr>
  </tbody>
</table>

### OnApproveDataSubscriptions

Data passed to `onApprove` for subscription payments

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>subscriptionId</code></td>
      <td><code>string</code></td>
      <td>The PayPal subscription ID</td>
    </tr>

    <tr>
      <td><code>payerId</code></td>
      <td><code>string</code> (optional)</td>
      <td>The PayPal payer ID</td>
    </tr>
  </tbody>
</table>

### OnApproveDataSavePayments

Data passed to `onApprove` for save payment operations

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>vaultSetupToken</code></td>
      <td><code>string</code></td>
      <td>Token representing the saved payment method</td>
    </tr>

    <tr>
      <td><code>payerId</code></td>
      <td><code>string</code> (optional)</td>
      <td>The PayPal payer ID</td>
    </tr>
  </tbody>
</table>

### OnCancelDataOneTimePayments

Data passed to `onCancel` for one-time payments

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>orderId</code></td>
      <td><code>string</code> (optional)</td>
      <td>The PayPal order ID</td>
    </tr>
  </tbody>
</table>

### OnCancelDataSavePayments

Data passed to `onCancel` for save payment operations

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>vaultSetupToken</code></td>
      <td><code>string</code> (optional)</td>
      <td>The vault setup token</td>
    </tr>
  </tbody>
</table>

### OnErrorData

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

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>code</code></td>
      <td><code>string</code></td>
      <td>Error code</td>
    </tr>

    <tr>
      <td><code>name</code></td>
      <td><code>string</code></td>
      <td>Error name</td>
    </tr>

    <tr>
      <td><code>message</code></td>
      <td><code>string</code></td>
      <td>Error message</td>
    </tr>

    <tr>
      <td><code>isRecoverable</code></td>
      <td><code>boolean</code></td>
      <td>Whether the error is recoverable</td>
    </tr>
  </tbody>
</table>

### OnCompleteData

Data passed to `onComplete` when payment session completes

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>paymentSessionState</code></td>
      <td><code>string</code></td>
      <td>Session result: <code>"approved"</code>, <code>"canceled"</code>, or <code>"error"</code></td>
    </tr>
  </tbody>
</table>

### BasePaymentSessionReturn

Return type for all payment session hooks

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>error</code></td>
      <td><code>Error | null</code></td>
      <td>Any session error</td>
    </tr>

    <tr>
      <td><code>isPending</code></td>
      <td><code>boolean</code></td>
      <td>Whether the SDK instance is still loading</td>
    </tr>

    <tr>
      <td><code>handleClick</code></td>
      <td><code>() => Promise\<\{ redirectURL?: string } | void></code></td>
      <td>Starts the payment session</td>
    </tr>

    <tr>
      <td><code>handleCancel</code></td>
      <td><code>() => void</code></td>
      <td>Cancels the session</td>
    </tr>

    <tr>
      <td><code>handleDestroy</code></td>
      <td><code>() => void</code></td>
      <td>Cleans up the session</td>
    </tr>
  </tbody>
</table>

### EventPayload

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

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>data</code></td>
      <td><code>EventState</code></td>
      <td>The state of the card fields when the event was triggered</td>
    </tr>

    <tr>
      <td><code>sender</code></td>
      <td><code>CardFieldTypes</code></td>
      <td>The card field that triggered the event: <code>"number"</code>, <code>"expiry"</code>, or <code>"cvv"</code></td>
    </tr>
  </tbody>
</table>

### EventState

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

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>cards</code></td>
      <td><code>Card\[]</code></td>
      <td>Detected card types based on the current card number input</td>
    </tr>

    <tr>
      <td><code>emittedBy</code></td>
      <td><code>CardFieldTypes</code></td>
      <td>The card field that emitted the event: <code>"number"</code>, <code>"expiry"</code>, or <code>"cvv"</code></td>
    </tr>

    <tr>
      <td><code>number</code></td>
      <td><code>FieldState</code></td>
      <td>State of the card number field</td>
    </tr>

    <tr>
      <td><code>cvv</code></td>
      <td><code>FieldState</code></td>
      <td>State of the CVV field</td>
    </tr>

    <tr>
      <td><code>expiry</code></td>
      <td><code>FieldState</code></td>
      <td>State of the expiry field</td>
    </tr>
  </tbody>
</table>

### FieldState

The state of an individual card field

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>isFocused</code></td>
      <td><code>boolean</code></td>
      <td>Whether the field currently has focus</td>
    </tr>

    <tr>
      <td><code>isValid</code></td>
      <td><code>boolean</code></td>
      <td>Whether the field value is valid</td>
    </tr>

    <tr>
      <td><code>isEmpty</code></td>
      <td><code>boolean</code></td>
      <td>Whether the field is empty</td>
    </tr>

    <tr>
      <td><code>isPotentiallyValid</code></td>
      <td><code>boolean</code></td>
      <td>Whether the field value could become valid with additional input</td>
    </tr>
  </tbody>
</table>

### Card

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

<table>
  <thead>
    <tr>
      <th align="left">Property</th>
      <th align="left">Type</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>niceType</code></td>
      <td><code>string</code></td>
      <td>Human-readable card name, for example, <code>"Visa"</code></td>
    </tr>

    <tr>
      <td><code>type</code></td>
      <td><code>string</code></td>
      <td>Machine-readable card type, for example, <code>"visa"</code></td>
    </tr>

    <tr>
      <td><code>code.name</code></td>
      <td><code>string</code></td>
      <td>Security code label for the card type, for example, <code>"CVV"</code> or <code>"CID"</code></td>
    </tr>

    <tr>
      <td><code>code.size</code></td>
      <td><code>number</code></td>
      <td>Expected length of the security code, for example, <code>3</code> or <code>4</code></td>
    </tr>
  </tbody>
</table>

## INSTANCE\_LOADING\_STATE

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

<table>
  <thead>
    <tr>
      <th align="left">Value</th>
      <th align="left">Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>INSTANCE\_LOADING\_STATE.PENDING</code></td>
      <td>SDK is loading</td>
    </tr>

    <tr>
      <td><code>INSTANCE\_LOADING\_STATE.RESOLVED</code></td>
      <td>SDK loaded successfully</td>
    </tr>

    <tr>
      <td><code>INSTANCE\_LOADING\_STATE.REJECTED</code></td>
      <td>SDK failed to load</td>
    </tr>
  </tbody>
</table>

#### Example

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

```tsx lines expandable theme={null}
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

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

### Error handling

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

```tsx lines expandable theme={null}
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

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

```tsx lines expandable theme={null}
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

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

```tsx lines expandable theme={null}
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

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

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

### Using vaultSetupToken instead of createVaultToken

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

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