Skip to main content
PayPal Fastlane is a streamlined checkout experience that allows returning customers to authenticate and pay quickly using saved payment methods and shipping addresses. New customers can also use it for a smooth guest checkout experience. For more information about Fastlane, see the PayPal Fastlane documentation. This guide provides instructions for integrating PayPal Fastlane into your web application using the v6 web SDK.

Prerequisites

  • PayPal sandbox account with appropriate credentials. For more information about using PayPal’s sandbox for testing, see the PayPal sandbox testing guide.
  • Backend server for API proxy. For more information, see /server/node/README.md.
  • A web browser with ES6 support.
There also are requirements for the backend and your HTML.

Backend endpoints

Your backend must provide these API endpoints:
  • The client token endpoint provides a client token for SDK initialization.
    • URL: GET /paypal-api/auth/browser-safe-client-token
    • Response: { "accessToken": "YOUR-CLIENT-TOKEN" }
  • The order creation endpoint creates a PayPal order using the payment token.
    • URL: POST /paypal-api/checkout/orders/create
    • Headers:
      Content-Type: application/json
      PayPal-Request-Id: <unique-id>

HTML structure

Your HTML must include these elements.
<!-- Email form -->
<form id="email-form">
  <input type="email" id="email-input" />
  <div id="watermark-container"></div>
  <button id="email-submit-button">Submit</button>
</form>

<!-- Payment containers -->
<div id="card-container"></div>
<div id="payment-container"></div>

<!-- Shipping display -->
<div id="shipping-display-container" hidden></div>
<button id="change-shipping-button" hidden>Change Shipping Address</button>

<!-- Order submission -->
<button id="submit-button" hidden>Submit Order</button>

<!-- Card testing info -->
<p id="card-testing-info" hidden>
  For more info on testing cards with PayPal, see
  <a href="https://developer.paypal.com/tools/sandbox/card-testing/">
    https://developer.paypal.com/tools/sandbox/card-testing/
  </a>
</p>

Integration

Fastlane integration consists of three main JavaScript files:
  • fastlaneSdkComponent.js: SDK initialization and client token management
  • fastlane.js: Main integration logic and UI handling
  • fastlane.css: Basic styling for the checkout experience
For examples of these files, see this GitHub repo folder. To complete the integration:
  1. Include the PayPal SDK script in your HTML.
<script async onload="onPayPalLoaded()" src="https://www.sandbox.paypal.com/web-sdk/v6/core"></script>
  1. Initialize the SDK and Fastlane (fastlaneSdkComponent.js).
In this example, you see some Fastlane SDK options:
  • pageType: The applicable page type, such as product-details
  • clientMetadataId: Unique session identifier
  • components: Array that includes fastlane

async function onPayPalLoaded() {
  const clientToken = await getBrowserSafeClientToken();
  const sdkInstance = await window.paypal.createInstance({
    clientToken,
    pageType: "product-details",
    clientMetadataId: crypto.randomUUID(),
    components: ["fastlane"],
  });
  fastlane = await sdkInstance.createFastlane();
  setupFastlaneSdk();
}
  1. Set up the email-lookup flow (fastlane.js).
The email-lookup process determines whether a user is a Fastlane member.
async function setupFastlaneSdk() {
  fastlane.setLocale("en_us");
  // Render Fastlane watermark
  const fastlaneWatermark = await fastlane.FastlaneWatermarkComponent({
    includeAdditionalInfo: true,
  });
  fastlaneWatermark.render("#watermark-container");
  // Handle email submission
  const emailSubmitButton = document.getElementById("email-submit-button");
  emailSubmitButton.addEventListener("click", async (e) => {
    e.preventDefault();
    const {
      customerContextId
    } = await fastlane.identity.lookupCustomerByEmail(emailInput.value, );
    let shouldRenderFastlaneMemberExperience = false;
    let profileData;
    if (customerContextId) {
      const response = await fastlane.identity.triggerAuthenticationFlow(customerContextId);
      if (response.authenticationState === "succeeded") {
        shouldRenderFastlaneMemberExperience = true;
        profileData = response.profileData;
      }
    }
    // Route to appropriate experience
    if (shouldRenderFastlaneMemberExperience) {
      renderFastlaneMemberExperience(profileData);
    } else {
      renderFastlaneGuestExperience();
    }
  });
}
  1. Set up handling for members (fastlane.js).
Members are authenticated Fastlane members who have saved data.
async function renderFastlaneMemberExperience(profileData) {
  if (profileData.shippingAddress) {
    setShippingAddressDisplay(profileData.shippingAddress);
    // Allow address changes
    const changeAddressButton = document.getElementById("change-shipping-button");
    changeAddressButton.addEventListener("click", async () => {
      const {
        selectedAddress,
        selectionChanged
      } = await fastlane.profile.showShippingAddressSelector();
      if (selectionChanged) {
        profileData.shippingAddress = selectedAddress;
        setShippingAddressDisplay(profileData.shippingAddress);
      }
    });
    // Render payment component with shipping address
    const fastlanePaymentComponent = await fastlane.FastlanePaymentComponent({
      options: {},
      shippingAddress: profileData.shippingAddress,
    });
    fastlanePaymentComponent.render("#payment-container");
  }
}
  1. Set up handling for guests (fastlane.js).
Guests are new or unauthenticated users.
async function renderFastlaneGuestExperience() {
  const cardTestingInfo = document.getElementById("card-testing-info");
  cardTestingInfo.removeAttribute("hidden");
  const FastlanePaymentComponent = await fastlane.FastlanePaymentComponent({});
  await FastlanePaymentComponent.render("#card-container");
}
  1. Set up payment processing (fastlane.js).
Payment processing includes generating a payment token and creating an order. In this step, you see these payment component options:
  • options: Additional payment component configuration
  • shippingAddress: Pre-populate with a member’s saved address

// Get payment token
const {
  id
} = await fastlanePaymentComponent.getPaymentToken();
// Create order via backend API
async function createOrder(paymentToken) {
  const response = await fetch("/paypal-api/checkout/orders/create", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "PayPal-Request-Id": Date.now().toString(),
    },
    body: JSON.stringify({
      paymentSource: {
        card: {
          singleUseToken: paymentToken,
        },
      },
      purchaseUnits: [{
        amount: {
          currencyCode: "USD",
          value: "10.00",
          breakdown: {
            itemTotal: {
              currencyCode: "USD",
              value: "10.00",
            },
          },
        },
      }, ],
      intent: "CAPTURE",
    }),
  });
  return await response.json();
}

Error handling

This integration includes basic error handling, including:
  • If a member’s authentication fails, they get the guest experience.
  • Errors in order creation display user-friendly messages.
  • The console logs error information to help with debugging.

Testing

For testing, use PayPal’s sandbox environment, which requires sandbox credentials. Sandbox credentials are different from any other PayPal credentials that you have. In the sandbox environment, you can test both member and guest flows. You also can use the test cases that are available here: https://developer.paypal.com/tools/sandbox/card-testing/.

Sample app

To see the sample app, run these commands.
npm install
npm start
The sample app will run at http://localhost:3000/. The sample requires a backend server at http://localhost:8080.

See also

Examine a full example of a Fastlane integration on GitHub.
I