Skip to main content
The PayPal Direct App Switch flow lets customers complete payments directly in the PayPal mobile app when it’s available. A basic Direct App Switch flow is similar to this:
  1. A user clicks the PayPal button in a merchant’s app or website.
  2. The server API creates an order.
  3. A payment session starts with the direct-app-switch mode.
  4. The user is redirected to the PayPal app (if available) or website to make a payment.
  5. When the payment is approved, the user returns to the merchant app or website to complete the transaction.
  6. The payment session resumes and captures the order.
This integration guide covers the implementation that is in the directAppSwitch example in the public examples repository on GitHub. The integration consists of 2 main files:
  • index.html: HTML structure with the PayPal button and an auto-redirect toggle
  • app.js: JavaScript implementation that handles the payment flow

Prerequisites

  • PayPal SDK v6
  • Server-side PayPal integration for order creation and capture, which uses these endpoints:
    • POST /paypal-api/checkout/orders/create creates the PayPal order.
    • POST /paypal-api/checkout/orders/{orderId}/capture captures completed order.
  • Client token generation endpoint, which uses the GET /paypal-api/auth/browser-safe-client-token endpoint.

Integration

Completing the integration involves the steps in this section.

1. HTML structure

In this example, you’ll find these key features:
  • An auto-redirect checkbox to control redirect behavior
  • A hidden PayPal button that becomes visible after SDK initialization
  • The JavaScript SDK v6 core script with an onload callback
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>One-Time Payment - Direct App Switch Flow - PayPal JavaScript SDK</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <h1>Paypal Direct App Switch Flow</h1>
    <div>
      <input type="checkbox" id="enable-auto-redirect" checked />
      <label for="enable-auto-redirect"> Enable auto-redirect </label>
    </div>
    <div id="button-container">
      <paypal-button id="paypal-button" hidden></paypal-button>
    </div>

    <script src="app.js"></script>
    <script
      async
      onload="onPayPalWebSdkLoaded()"
      src="https://www.sandbox.paypal.com/web-sdk/v6/core"
    ></script>
  </body>
</html>

2. SDK initialization

In this example, you’ll find these key features:
  • It creates an SDK instance with a client token.
  • It initializes a one-time payment session with PayPal.
  • It handles the return from an external app using hasReturned(). For more information about return URL handling, see Return URL handling.
  • It resumes a session or sets up the button accordingly.
async function onPayPalWebSdkLoaded() {
  try {
    const clientToken = await getBrowserSafeClientToken();
    const sdkInstance = await window.paypal.createInstance({
      clientToken,
      components: ["paypal-payments"],
      pageType: "checkout",
    });
    const paypalPaymentSession = sdkInstance.createPayPalOneTimePaymentSession(
      paymentSessionOptions,
    );

    if (paypalPaymentSession.hasReturned()) {
      await paypalPaymentSession.resume();
    } else {
      setupPayPalButton(paypalPaymentSession);
    }
  } catch (error) {
    console.error(error);
  }
}

3. Payment session configuration

This example uses the following callbacks:
  • onApprove: Triggered when payment is approved to capture the order
  • onCancel: Handles payment cancellation
  • onError: Handles payment errors
const paymentSessionOptions = {
  async onApprove(data) {
    console.log("onApprove", data);
    const orderData = await captureOrder({
      orderId: data.orderId,
    });
    console.log("Capture result", orderData);
  },
  onCancel(data) {
    console.log("onCancel", data);
  },
  onError(error) {
    console.log("onError", error);
  },
};

4. Button setup and payment initiation

In this example, note the Direct App Switch configuration, which includes these features:
  • presentationMode: "direct-app-switch" enables the Direct App Switch flow
  • autoRedirect.enabled controls automatic redirection behavior
  • redirectURL redirects to the PayPal app or site
For more information about return URL handling, see Return URL handling.
async function setupPayPalButton(paypalPaymentSession) {
  const enableAutoRedirect = document.querySelector("#enable-auto-redirect");
  const paypalButton = document.querySelector("#paypal-button");
  paypalButton.removeAttribute("hidden");

  paypalButton.addEventListener("click", async () => {
    const createOrderPromiseReference = createRedirectOrder();

    try {
      const { redirectURL } = await paypalPaymentSession.start(
        {
          presentationMode: "direct-app-switch",
          autoRedirect: {
            enabled: enableAutoRedirect.checked,
          },
        },
        createOrderPromiseReference,
      );
      if (redirectURL) {
        console.log(`redirectURL: ${redirectURL}`);
        window.location.assign(redirectURL);
      }
    } catch (error) {
      console.error(error);
    }
  });
}

5. Server integration functions

These examples show how to set up client token retrieval, order creation, and order capture. Select a tab to see and use the corresponding example. In this order creation example, you see these settings:
  • shippingPreference: "NO_SHIPPING" means that no shipping is required.
  • userAction: "CONTINUE" means that the user continues after approval.
  • returnUrl and cancelUrl use the URL of the current page.
  • Tab Title
  • Tab Title
  • Tab Title
Client token retrieval
async function getBrowserSafeClientToken() {
  const response = await fetch("/paypal-api/auth/browser-safe-client-token", {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
    },
  });
  const { accessToken } = await response.json();
  return accessToken;
}

Return URL handling

To understand return URL handing, keep these points in mind:
  • Both returnUrl and cancelUrl point to window.location.href.
  • The hasReturned() method detects when user returns from external flow
  • The resume() method continues the payment process.
When you enable auto-redirect, it automatically redirects users to the PayPal app (if available) or website. If you disable this functionality, it shows the redirect URL for manual handling.

Best practices

These examples demonstrate some best practices. Specifically, best practices for Direct App Switch integrations include:
  • Always wrap payment operations in try-catch blocks for better error handling.
  • To detect returning users, use hasReturned().
  • To continue or return to a payment session, call resume().
  • Use responsive design to ensure a device-optimized experience for users.

Testing

  • Web-fallback behavior: While it might be obvious to test on devices that have the PayPal app, also test your app or website on devices that don’t have the PayPal app installed.
  • Auto-redirect: Test auto-redirect functionality to ensure that it provides the experience that you expect for users.
  • Payment cancellation: Be sure to test what happens when payment fails or is cancelled.
  • Order capture: Validate that captured orders accurately reflect the intended purchase for a successful payment.
I