Skip to main content

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.

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.

PayPalProvider

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

Props

PropTypeDescription
clientIdstring | Promise<string> | undefined

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

clientTokenstring | Promise<string> | undefined

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

componentsstring[]

Array of components to load: “paypal-payments” (default), “venmo-payments”, “paypal-subscriptions”, “paypal-guest-payments”, and “card-fields”

pageTypestring

Page context type, for example, “checkout”

localestring

Locale for the SDK, for example, “en_US”

clientMetadataIdstring

Client metadata ID for tracking

partnerAttributionIdstring

Partner attribution ID

shopperSessionIdstring

Shopper session ID for personalization

testBuyerCountrystring

Test buyer country for sandbox testing

merchantIdstring | string[]

Merchant ID or array of merchant IDs

eligibleMethodsResponseobject

Pre-fetched eligible methods response from server-side useFetchEligibleMethods

environmentstring

Target environment: “sandbox” or “production”

debugboolean

Enable debug mode

dataNamespacestring

Custom namespace for the SDK data attribute

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.

Example

Replace YOUR_PAYPAL_CLIENT_ID with your app’s PayPal client ID when initializing the provider.
Place PayPalProvider at your app root so payment buttons render sooner.
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>
  );
}

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

PropertyTypeDescription
loadingStatusINSTANCE_LOADING_STATECurrent SDK loading state: INSTANCE_LOADING_STATE enum values
eligiblePaymentMethodsobject | nullAvailable payment methods for the current user
sdkInstanceobject | nullThe underlying SDK instance
errorError | nullAny error that occurred during SDK initialization
isHydratedbooleanWhether the component has been hydrated on the client

Example

Use usePayPal to access the SDK state and payment eligibility in any component inside PayPalProvider.
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

ParameterRequiredDescription
payload.amountno

string. Order amount, for example, “95.00”

payload.currencyCodeno

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

payload.paymentFlowno

string. The payment flow type: “ONE_TIME_PAYMENT”, “RECURRING_PAYMENT”, “VAULT_WITH_PAYMENT”, or “VAULT_WITHOUT_PAYMENT”

Returns

PropertyTypeDescription
eligiblePaymentMethodsobject | nullAvailable payment methods for the current user.
  • To retrieve product-specific details, call .getDetails("").
  • To check eligibility for a specific payment method, call .isEligible("").
isLoadingbooleanWhether eligibility data is still being fetched
errorError | nullAny error that occurred during the fetch

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

ParameterRequiredDescription
buyerCountryno

string. Buyer’s country code

currencyCodeno

string. Currency code

shopperSessionIdno

string. Shopper session ID

Returns

PropertyTypeDescription
errorError | nullAny session error
isReadybooleanWhether the session is created
handleFetchContentfunctionFetches message content
handleCreateLearnMorefunctionCreates a learn more modal

Example

The following example uses auto-bootstrap mode to display a PayPal message with a Learn more modal.
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.
PropertyTypeDescription
errorError | nullAny session error
isPendingbooleanWhether the SDK instance is still loading
handleClick() => PromiseStarts the payment session
handleCancel() => voidCancels the session
handleDestroy() => voidCleans up the session

usePayPalOneTimePaymentSession

The following example creates an order on your server and renders a custom PayPal button that starts the payment session when selected.
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.
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.
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.
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.
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.
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.
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.
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.
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

PropTypeDescription
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.
orderIdstringOrder 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) => voidCallback when user cancels
onError(data: OnErrorData) => voidCallback on payment error
onComplete(data: OnCompleteData) => voidCallback when payment session completes
presentationModestring

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.

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
typestringButton type: “pay” (default), “checkout”, “buynow”, or “donate”
disabledbooleanWhether the button is disabled
savePaymentbooleanWhether to save the payment method during checkout

Example

The following example renders a PayPal button that creates an order on your server and handles approval when the buyer completes payment.
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.
PropTypeDescription
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.
orderIdstringOrder 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) => voidCallback when user cancels
onError(data: OnErrorData) => voidCallback on payment error
onComplete(data: OnCompleteData) => voidCallback when payment session completes
presentationModestring

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.

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
typestringButton type: “pay” (default), “checkout”, “buynow”, or “donate”
disabledbooleanWhether the button is disabled
savePaymentbooleanWhether to save the payment method during checkout

Example

The following example renders a Venmo payment button with order creation and approval callbacks.
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

PropTypeDescription
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.
orderIdstringOrder 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) => voidCallback when user cancels
onError(data: OnErrorData) => voidCallback on payment error
onComplete(data: OnCompleteData) => voidCallback when payment session completes
presentationModestring

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.

disabledbooleanWhether the button is disabled

Example

The following example renders a Pay Later button that lets buyers choose financing options like Pay in 4.
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

PropTypeDescription
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.
orderIdstringOrder 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) => voidCallback when user cancels
onError(data: OnErrorData) => voidCallback on payment error
onComplete(data: OnCompleteData) => voidCallback when payment session completes
presentationModestring

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.

disabledbooleanWhether the button is disabled

Example

The following example checks eligibility before rendering a PayPal Credit button for one-time payments.
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>.
This component does not accept presentationMode. It renders a <paypal-basic-card-button> inside a <paypal-basic-card-container> automatically.

Props

PropTypeDescription
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
orderIdstringOrder 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) => voidCallback when user cancels
onError(data: OnErrorData) => voidCallback on payment error
onComplete(data: OnCompleteData) => voidCallback 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
disabledbooleanWhether the button is disabled

Example

The following example renders a guest checkout button that allows buyers to pay without a PayPal account.
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

Example

The following example creates a vault setup token on your server and renders a button that saves the buyer’s payment method.
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

PropTypeDescription
createVaultToken() => Promise<{ vaultSetupToken: string }>Function that creates a vault setup token and returns an object with its ID. Use either createVaultToken or vaultSetupToken, not both.
vaultSetupTokenstringPre-created vault setup token. Use either createVaultToken or vaultSetupToken, not both.
onApprove(data: OnApproveDataSavePayments) => Promise<void>Callback when payment method is saved
onCancel(data: OnCancelDataSavePayments) => voidCallback when user cancels
onError(data: OnErrorData) => voidCallback on error
onComplete(data: OnCompleteData) => voidCallback when session completes
presentationModestring

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.

typestringButton type. Defaults to “pay”
disabledbooleanWhether the button is disabled

Example

The following example checks eligibility before rendering a button that saves a PayPal Credit payment method to the vault.
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.
Subscriptions only support "auto", "popup", "modal", or "payment-handler" presentation modes.

Props

PropTypeDescription
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) => voidCallback when user cancels
onError(data: OnErrorData) => voidCallback on error
onComplete(data: OnCompleteData) => voidCallback when session completes
presentationModestring

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.

typestringButton type. Defaults to “subscribe”
disabledbooleanWhether the button is disabled

Example

The following example creates a subscription on your server and renders a button that starts the subscription approval flow.
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

PropTypeDescription
applePayConfigApplePayConfigApple Pay configuration from findEligibleMethods
paymentRequestApplePayPaymentRequestPayment request with country, currency, and total
applePaySessionVersionnumberApple Pay JS API version (4 or later)
createOrder() => Promise<{ orderId: string }>Function that creates an order
onApprove(data: ConfirmOrderResponse) => voidCallback when payment is approved
onCancel() => voidCallback when payment is cancelled
onError(error: Error) => voidCallback on error
displayNamestringMerchant display name
domainNamestringMerchant domain name
buttonstylestringButton style, for example, “black” (default) or “white”
typestringButton type, for example, “pay” (default)
localestringLocale, such as “en” (default)
disabledbooleanWhether the button is disabled

Example

The following example renders an Apple Pay button configured with a payment request and order creation callback.
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

PropTypeDescription
children (required)ReactNodeChild components
amount { value?: string, currencyCode?: string }Order amount, which you can update dynamically
isCobrandedEligiblebooleanWhether co-branded card eligibility is enabled
blur(event) => voidCallback when a card field loses focus
validitychange(event) => voidCallback when field validity changes
cardtypechange(event) => voidCallback when card type changes or is detected
focus(event) => voidCallback when a card field gains focus
change(event) => voidCallback when card field value changes
empty(event) => voidCallback when a card field is empty
inputsubmit(event) => voidCallback when a card field is submitted
notempty(event) => voidCallback when a card field is not empty

Example

The following example renders card number, expiry, and CVV fields inside a provider that listens for validity and card type changes.
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

PropTypeDescription
placeholderstringInput placeholder text
labelstringInput label
styleobjectCustom styles
ariaLabelstringAccessibility label
ariaDescriptionstringAccessibility description
ariaInvalidErrorMessagestringError message for screen readers
containerStylesCSSPropertiesStyles for the container div
containerClassNamestringClass name for the container div

PayPalCardExpiryField

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

Props

PropTypeDescription
placeholderstringInput placeholder text
labelstringInput label
styleobjectCustom styles
ariaLabelstringAccessibility label
ariaDescriptionstringAccessibility description
ariaInvalidErrorMessagestringError message for screen readers
containerStylesCSSPropertiesStyles for the container div
containerClassNamestringClass name for the container div

PayPalCardCvvField

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

Props

PropTypeDescription
placeholderstringInput placeholder text
labelstringInput label
styleobjectCustom styles
ariaLabelstringAccessibility label
ariaDescriptionstringAccessibility description
ariaInvalidErrorMessagestringError message for screen readers
containerStylesCSSPropertiesStyles for the container div
containerClassNamestringClass name for the container div

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

PropertyTypeDescription
submit(orderId: string | Promise<string>, options?) => Promise<void>Submit the card fields for payment
submitResponseobject | nullThe response from the submit operation
errorError | nullAny error that occurred

Example

The following example renders styled card fields, submits the card data for a one-time payment, and handles both success and failure responses.
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 submits card field data to save a payment method.

Returns

PropertyTypeDescription
submit(vaultSetupToken: string | Promise<string>, options?) => Promise<void>Submit the card fields for vaulting
submitResponseobject | nullThe response from the submit operation
errorError | nullAny error that occurred

Example

The following example renders card fields and submits the card data to save it as a vaulted payment method.
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

useFetchEligibleMethods(options)

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

Parameters

ParameterRequiredDescription
options.headersyes

HeadersInit. HTTP headers including the Authorization bearer token

options.environmentyes

string. Target environment (“sandbox” or “production”)

options.payloadno

object. Optional request payload with customer and purchase details

options.signalno

AbortSignal. Optional abort signal

Example

The following example pre-fetches eligible payment methods on the server and passes the result to PayPalProvider.
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>

Types

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

OnApproveDataOneTimePayments

Data passed to onApprove for one-time payments
PropertyTypeDescription
orderIdstringThe PayPal order ID
payerIdstring (optional)The PayPal payer ID
billingTokenstring (optional)The billing token

OnApproveDataSubscriptions

Data passed to onApprove for subscription payments
PropertyTypeDescription
subscriptionIdstringThe PayPal subscription ID
payerIdstring (optional)The PayPal payer ID

OnApproveDataSavePayments

Data passed to onApprove for save payment operations
PropertyTypeDescription
vaultSetupTokenstringToken representing the saved payment method
payerIdstring (optional)The PayPal payer ID

OnCancelDataOneTimePayments

Data passed to onCancel for one-time payments
PropertyTypeDescription
orderIdstring (optional)The PayPal order ID

OnCancelDataSavePayments

Data passed to onCancel for save payment operations
PropertyTypeDescription
vaultSetupTokenstring (optional)The vault setup token

OnErrorData

Data passed to onError when an error occurs. Extends Error.
PropertyTypeDescription
codestringError code
namestringError name
messagestringError message
isRecoverablebooleanWhether the error is recoverable

OnCompleteData

Data passed to onComplete when payment session completes
PropertyTypeDescription
paymentSessionStatestringSession result: “approved”, “canceled”, or “error”

BasePaymentSessionReturn

Return type for all payment session hooks
PropertyTypeDescription
errorError | nullAny session error
isPendingbooleanWhether the SDK instance is still loading
handleClick() => Promise<{ redirectURL?: string } | void>Starts the payment session
handleCancel() => voidCancels the session
handleDestroy() => voidCleans up the session

EventPayload

Data passed to Card Fields event callbacks such as blur, focus, change, and validitychange
PropertyTypeDescription
dataEventStateThe state of the card fields when the event was triggered
senderCardFieldTypesThe card field that triggered the event: “number”, “expiry”, or “cvv”

EventState

The state of all card fields at the time an event is triggered
PropertyTypeDescription
cardsCard[]Detected card types based on the current card number input
emittedByCardFieldTypesThe card field that emitted the event: “number”, “expiry”, or “cvv”
numberFieldStateState of the card number field
cvvFieldStateState of the CVV field
expiryFieldStateState of the expiry field

FieldState

The state of an individual card field
PropertyTypeDescription
isFocusedbooleanWhether the field currently has focus
isValidbooleanWhether the field value is valid
isEmptybooleanWhether the field is empty
isPotentiallyValidbooleanWhether the field value could become valid with additional input

Card

Represents a detected card type based on the current card number input
PropertyTypeDescription
niceTypestringHuman-readable card name, for example, “Visa”
typestringMachine-readable card type, for example, “visa”
code.namestringSecurity code label for the card type, for example, “CVV” or “CID”
code.sizenumberExpected length of the security code, for example, 3 or 4

INSTANCE_LOADING_STATE

Enum for SDK loading states. Use with usePayPal() to check SDK readiness.
ValueDescription
INSTANCE_LOADING_STATE.PENDINGSDK is loading
INSTANCE_LOADING_STATE.RESOLVEDSDK loaded successfully
INSTANCE_LOADING_STATE.REJECTEDSDK failed to load

Example

The following example checks the SDK loading state and renders different UI for each state.
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.
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.
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.
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.
<PayPalOneTimePaymentButton
  orderId="ORDER-123"
  onApprove={handleApprove}
  presentationMode="auto"
/>

Using vaultSetupToken instead of createVaultToken

Save payment buttons support passing a pre-created vaultSetupToken directly.
<PayPalSavePaymentButton
  vaultSetupToken="VAULT-TOKEN-123"
  onApprove={handleApprove}
  presentationMode="auto"
/>