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

# Save Apple Pay for later use (JavaScript SDK integration)

Save Apple Pay as a payment method for future purchases without an initial transaction. Use PayPal's JavaScript SDK to tokenize and save Apple Pay credentials for later use.

## Prerequisites

1. Ensure you have PayPal business account approved for Expanded Checkout.
2. Ensure you <a href="/limited-release/usage-based-billing/set-up-accounts" target="_blank" rel="noopener noreferrer">set up developer, sandbox, and production environment accounts</a>.
3. Ensure you <a href="https://developer.paypal.com/docs/checkout/apm/apple-pay/#create-apple-pay-sandbox-account" target="_blank" rel="noopener noreferrer">create an Apple Pay sandbox account</a> for testing in the sandbox environment.

## Load PayPal JavaScript SDK

PayPal's JavaScript SDK provides the necessary pre-built tools to render the Apple Pay button on your webpage and handle payment authorization. Include the PayPal SDK core and Apple Pay SDK as `<script>` tags in the HTML file that renders your webpage.

For production environment:

<CodeGroup>
  ```html HTML theme={null}
  {/* PayPal Web SDK */}
  <script src="https://www.paypal.com/web-sdk/v6/core"></script>

  {/* Apple Pay SDK */}
  <script src="https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js"></script>
  ```
</CodeGroup>

For sandbox environment:

<CodeGroup>
  ```html HTML theme={null}
  {/* PayPal Web SDK (Sandbox) */}
  <script src="https://www.sandbox.paypal.com/web-sdk/v6/core"></script>

  {/* Apple Pay SDK */}
  <script src="https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js"></script>
  ```
</CodeGroup>

## Create browser-safe client token

The browser-safe token is a client-side access token that authorizes an app to use the JavaScript SDK resources.

<Note> A browser-safe token is not the same as a server-side access token. The server-side access token helps PayPal authenticate an app when the app accesses PayPal REST API resources.</Note>

To get the browser-safe client token from your server-side code, make a POST call to the `/v1/oauth2/token` endpoint and include the following:

* Encoded app credentials Client ID : Secret in Base64 format, in the Authorization header.
* Data parameters:

| Parameter       | Action                                                                                                                                      |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `grant_type`    | Set the parameter value to `client_credentials` to specify that the app is requesting to exchange client ID and secret for an access token. |
| `response_type` | Set the parameter value to `client_token` to request a client-side access token.                                                            |
| `intent`        | Set the parameter value to `sdk_init` to specify that the purpose for the request is SDK initialization.                                    |

**Response**: Contains the browser-safe client token in the `access_token` response parameter.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  async function getClientToken() {
    const response = await fetch(
      "/your-server/api/paypal/browser-safe-client-token",
    );
    const tokens = await response.json();
    return tokens.access_token;
  }
  ```

  ```javascript server-side - Node.js theme={null}
  // Helper function to get OAuth token
  async function getAuthToken(formBody) {
    const encodedClientCredentials = Buffer.from(
      `${process.env.PAYPAL_CLIENT_ID}:${process.env.PAYPAL_CLIENT_SECRET}`,
    ).toString("base64");

    const response = await fetch(
      `${process.env.PAYPAL_API_BASE_URL}/v1/oauth2/token`,
      {
        body: formBody,
        headers: {
          Accept: "application/json",
          "Accept-Language": "en_US",
          Authorization: `Basic ${encodedClientCredentials}`,
          "Content-Type": "application/x-www-form-urlencoded",
        },
        method: "POST",
      },
    );

    const data = await response.json();

    if (response.status !== 200 && response.status !== 201) {
      throw new Error(data.error_description || "Failed to generate OAuth token");
    }

    return data;
  }

  // Function to get browser-safe client token
  async function getBrowserSafeClientToken() {
    return await getAuthToken(
      "grant_type=client_credentials&response_type=client_token&intent=sdk_init",
    );
  }

  // Route handler for browser-safe client token endpoint
  router.get("/your-server/api/paypal/browser-safe-client-token", async (request, response, next) => {
    try {
      const clientTokenResponse = await getBrowserSafeClientToken();
      return response.send({
        access_token: clientTokenResponse.access_token,
      });
    } catch (error) {
      next(error);
    }
  });
  ```

  ```bash server-side - cURL theme={null}
  curl -v -X POST 'https://api-m.sandbox.paypal.com/v1/oauth2/token' \
    -u 'CLIENT-ID:CLIENT-SECRET' \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -H 'Accept: application/json' \
    -H 'Accept-Language: en_US' \
    -d 'grant_type=client_credentials' \
    -d 'response_type=client_token' \
    -d 'intent=sdk_init'
  ```
</CodeGroup>

## Initialize JavaScript SDK and create SDK instance

Use the `window.paypal.createInstance()` method to create a PayPal SDK instance and include the following parameters:

| Parameter     | Action                                                                                     |
| ------------- | ------------------------------------------------------------------------------------------ |
| `clientToken` | Pass the browser-safe client token.                                                        |
| `components`  | Set to `["applepay-payments"]` to indicate that you intend to render Apple Pay components. |

**Response**: Contains an SDK instance object with the `createApplePayOneTimePaymentSession()` method for creating Apple Pay payment sessions and the `findEligibleMethods()` method for checking payment method availability.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  const clientToken = await getClientToken();
  const sdkInstance = await window.paypal.createInstance({
    clientToken,
    components: ["applepay-payments"],
  });
  window.sdkInstance = sdkInstance;
  ```
</CodeGroup>

## Create PayPal's Apple Pay one-time payment session

Create PayPal's session that handles Apple Pay configuration and merchant validation. This session manages PayPal-specific operations and provides the settings needed for the native Apple Pay session created later.

### Create payment session

Use the `createApplePayOneTimePaymentSession()` method to create the session. This method doesn't require any parameters as it uses the configuration from SDK initialization.

**Response**: Contains `config()` to get Apple Pay configuration and `validateMerchant()` to validate merchant with Apple Pay servers.

### Get Apple Pay configuration

Use the `paypalSdkApplePayPaymentSession.config()` method to retrieve Apple Pay configuration. This method doesn't require any parameters.

**Response**: Contains the following:

* `merchantCapabilities` (array): Supported payment processing capabilities.
* `supportedNetworks` (array): Supported card networks.
* `isEligible` (boolean): Indicates if Apple Pay is eligible.
* `merchantCountry` (string): Merchant's country code.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  // Create PayPal's Apple Pay session for configuration and validation
  const paypalSdkApplePayPaymentSession =
    await sdkInstance.createApplePayOneTimePaymentSession();
  const { merchantCapabilities, supportedNetworks } =
    await paypalSdkApplePayPaymentSession.config();
  ```
</CodeGroup>

## Verify eligibility

Use the following methods to determine if you are eligible to offer Apple Pay as a payment method:

* `findEligibleMethods` - Returns all the eligible payment methods.
* `isEligible()`: Indicates if Apple Pay is an eligible payment method.

Call `findEligibleMethods()` with an input `options` object containing the following parameters:

| Parameter      | Action                                                 |
| -------------- | ------------------------------------------------------ |
| `currencyCode` | Set to the three-letter currency code. Example: `USD`. |

**Response**: Contains a `paymentMethods` object with `isEligible()` method to check if Apple Pay is eligible.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  const options = {
    currencyCode: "USD"
  };

  const paymentMethods = await sdkInstance.findEligibleMethods(options);
  let isApplePayEligible = paymentMethods.isEligible("applepay");
  setMessage("Apple Pay eligibility: ", { isApplePayEligible });
  ```
</CodeGroup>

## Render Apple Pay button

After confirming eligibility, render the Apple Pay button on your webpage. To render the Apple Pay button:

1. **Define the container for the Apple Pay button**: In the HTML file corresponding to the webpage where you want to render the button, include a container element as shown in the sample code:

<CodeGroup>
  ```html index.html theme={null}
  <section class="payment-method-container" id="applepay-section">
    <h2>Apple Pay Button</h2>
    <p>This example uses the Apple Pay button web component to launch the vault without purchase flow.</p>
    {/* Button will be added dynamically if eligible */}
  </section>
  ```
</CodeGroup>

2. **Add the Apple Pay button element**: Dynamically insert the Apple Pay button HTML element into the container. The `<apple-pay-button>` web component supports the following attributes:

| Attribute     | Action                                                   |
| ------------- | -------------------------------------------------------- |
| `id`          | Set to a unique identifier for the button element.       |
| `buttonstyle` | Set to the visual style of the button. Example: `black`. |
| `type`        | Set to the button label type. Example: `buy`.            |
| `locale`      | Set to the language code for button text. Example: `en`. |

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  const applepaySection = document.querySelector("#applepay-section");
  const applepayButton = document.createElement("apple-pay-button");
  applepayButton.id = "btn-appl";
  applepayButton.buttonstyle = "black";
  applepayButton.type = "buy";
  applepayButton.locale = "en";
  applepaySection.appendChild(applepayButton);
  ```
</CodeGroup>

3. **Attach the event handler**: Use `addEventListener()` to register the `onClickApplePay` callback handler that executes when customers select the Apple Pay button. This handler manages:
   * Apple Pay session creation.
   * Merchant validation with Apple Pay servers.
   * Payment authorization and token creation.
   * Vault setup token and payment token generation.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  document
    .getElementById("btn-appl")
    .addEventListener("click", onClickApplePay);
  ```
</CodeGroup>

**Result**: Successful button rendering:

* Sets up the Apple Pay button on your webpage.
* Defines the on-click flow for your button.

## Define on-click event handler function

Create an event handler to process Apple Pay button clicks and start the payment session. This function contains all the logic needed to handle the Apple Pay vault flow.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  async function onClickApplePay() {
    // Step 1: Create payment request object
    // Step 2: Verify Apple Pay availability
    // Step 3: Create new Apple Pay session
    // Step 4: Set up event handlers
    // Step 5: Start Apple Pay flow
  }
  ```
</CodeGroup>

### 1. Create payment request object

Define the payment request with required billing fields and zero amount.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  const paymentRequest = {
            countryCode: "US",
            currencyCode: "USD",
            merchantCapabilities,
            supportedNetworks,
            requiredBillingContactFields: [
              "name",
              "phone",
              "email",
              "postalAddress",
            ],
            requiredShippingContactFields: [],
            total: {
              label: "Save Payment Method",
              amount: "0.00",
              type: "final",
            },
            lineItems: [
              {
                label: "Subscription (Recurring)",
                amount: 100,
                recurringPaymentStartDate: "2025-09-07T04:01:17.188Z",
                paymentTiming: "recurring"
              }
            ],
            recurringPaymentRequest: {
              paymentDescription: "Recurring transaction description",
              regularBilling: {
                label: "Recurring",
                amount: 100,
                paymentTiming: "recurring",
                recurringPaymentStartDate: "2025-09-07T04:01:17.188Z"
              },
              billingAgreement: "Billing Agreement Description",
              managementURL: "https://www.your-domain.com/management-url/"
            }
          };
  ```
</CodeGroup>

### 2. Verify Apple Pay availability

Check browser support and device capability for Apple Pay.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  // Check Apple Pay availability
  if (!window.ApplePaySession) {
    console.log("Apple Pay is not available - ApplePaySession not found");
    return;
  }

  if (!ApplePaySession.canMakePayments()) {
    console.log("Apple Pay is not available - canMakePayments returned false");
    return;
  }

  console.log("Apple Pay version supported:", ApplePaySession.supportsVersion(4));
  console.log("Payment request:", paymentRequest);
  ```
</CodeGroup>

### 3. Create new Apple Pay session

Initialize a new Apple Pay session with the payment request details.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  console.log("Creating Apple Pay session for vault...");
  let appleSdkApplePayPaymentSession = new ApplePaySession(
    4,
    paymentRequest,
  );
  ```
</CodeGroup>

### 4. Set up event handlers

Event handlers manage the different outcomes when your customers attempt to save Apple Pay. Configure event handlers for the Apple Pay session lifecycle.

#### a. Handle merchant validation

In your app code, include the logic to validate the merchant identity with Apple Pay servers through PayPal.

Use the `paypalSdkApplePayPaymentSession.validateMerchant()` method to validate the merchant with Apple Pay servers and include the following parameters:

| Parameter       | Action                                                                      |
| --------------- | --------------------------------------------------------------------------- |
| `validationUrl` | Pass the validation URL provided by Apple Pay (from `event.validationURL`). |
| `displayName`   | Set to the merchant display name.                                           |
| `domainName`    | Set to the merchant domain name.                                            |

**Response**: Contains `merchantSession` to pass to Apple Pay.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  appleSdkApplePayPaymentSession.onvalidatemerchant = (event) => {
    console.log("Validating Apple Pay merchant & domain...");
    console.log("Validation URL:", event.validationURL);

    paypalSdkApplePayPaymentSession
      .validateMerchant({
        validationUrl: event.validationURL,
      })
      .then((payload) => {
        console.log("Merchant validation success:", payload);
        appleSdkApplePayPaymentSession.completeMerchantValidation(
          payload.merchantSession,
        );
        console.log("Completed merchant validation");
      })
      .catch((err) => {
        console.log("PayPal validatemerchant error:", err);
        console.log(`Merchant validation failed: ${err.message || err}`);
        appleSdkApplePayPaymentSession.abort();
      });
  };
  ```
</CodeGroup>

#### b. Handle payment method selection

In your app code, include the logic to handle when the customer selects a different payment card in Apple Wallet.

Use the `completePaymentMethodSelection()` method to confirm the selection with `newTotal` parameter set to the payment total object (from `paymentRequest.total`).

**Response**: Updates the Apple Pay sheet with the confirmed selection.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  appleSdkApplePayPaymentSession.onpaymentmethodselected = () => {
    appleSdkApplePayPaymentSession.completePaymentMethodSelection({
      newTotal: paymentRequest.total,
    });
  };
  ```
</CodeGroup>

#### c. Handle payment authorization

In your app code, include the logic to process the Apple Pay payment authorization and create vault tokens.

Use the `completePayment()` method to notify Apple Pay of the transaction status with `status` parameter set to the payment status (`window.ApplePaySession.STATUS_SUCCESS` or `window.ApplePaySession.STATUS_FAILURE`).

**Response**: Closes the Apple Pay sheet and displays the appropriate success or failure message to the customer.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  appleSdkApplePayPaymentSession.onpaymentauthorized = async (event) => {
    try {
      // Step 1: Encode the Apple Pay token
      function encodePaymentToken(token) {
        var data = { partner: "paypal", paymentData: token.paymentData };
        return btoa(JSON.stringify(data));
      }

      // Step 2: Create vault setup token
      const vaultSetupTokenData = {
        payment_source: {
          apple_pay: {
            token: encodePaymentToken(event.payment.token),
          },
        },
      };
      
      const vaultSetupToken = await createVaultSetupToken(vaultSetupTokenData);
      
      // Step 3: Create payment token
      const vaultPmtTokenData = {
        payment_source: {
          token: {
            type: "SETUP_TOKEN",
            id: vaultSetupToken.setupToken,
          },
        },
      };
      
      const vaultPaymentToken = await createVpmtToken(vaultPmtTokenData);
      setMessage("✅Payment Token created successfully: " + vaultPaymentToken.setupToken);
      
      // Step 4: Complete the payment
      appleSdkApplePayPaymentSession.completePayment({
        status: window.ApplePaySession.STATUS_SUCCESS,
      });
      
    } catch (error) {
      console.error("Payment authorization error:", error);
      appleSdkApplePayPaymentSession.completePayment({
        status: window.ApplePaySession.STATUS_FAILURE,
      });
    }
  };
  ```
</CodeGroup>

##### Create vault setup token

Create a setup token for saving payment methods without an initial payment. This token is different from the browser-safe client token and is used to generate the payment method token.

First, encode the Apple Pay payment data using a helper function that formats the token data in the required structure for PayPal's Vault API:

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  function encodePaymentToken(token) {
    var data = { partner: "paypal", paymentData: token.paymentData };
    return btoa(JSON.stringify(data));
  }
  ```
</CodeGroup>

In the server-side call to the `/v3/vault/setup-tokens` endpoint:

1. Use a Bearer token in the `Authorization` header.
2. Include the following parameter:

| Parameter                        | Action                                                             |
| -------------------------------- | ------------------------------------------------------------------ |
| `payment_source.apple_pay.token` | Set to the Base64 encoded Apple Pay token containing payment data. |

**Response**: Contains the setup token in the `id` response parameter.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  // Client-side helper function to create vault setup token
  async function createVaultSetupToken(vaultData) {
    setMessage("Creating vault setup token");

    const defaultHeaders = {
      "Content-Type": "application/json",
    };

    try {
      const response = await fetch(
        "/your-server/api/paypal/vault/setup-token",
        {
          headers: {
            ...defaultHeaders,
          },
          method: "POST",
          body: JSON.stringify(vaultData),
        },
      );

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.message || "Failed to create setup token");
      }

      return data;
    } catch (error) {
      throw new Error(error);
    }
  }
  ```

  ```javascript server-side - Node.js theme={null}
  // Function to get full scope access token for vault operations
  function getFullScopeAccessToken(config) {
    return getAuthToken(
      "grant_type=client_credentials&response_type=token",
      config
    );
  }

  // Express route to create setup token for Apple Pay
  router.post(
    "/your-server/api/paypal/vault/setup-token",
    async (request, response, next) => {
      const appmtdata = request.body;

      try {
        const { access_token: accessToken } = await getFullScopeAccessToken(
          response.locals.config,
        );

        const requestHeaders = {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": "application/json",
        };

        const apiResponse = await fetch(
          `${response.locals.config.apiBaseUrl}/v3/vault/setup-tokens`,
          {
            body: JSON.stringify(appmtdata),
            headers: requestHeaders,
            method: "POST",
          },
        );

        const data = await apiResponse.json();

        if (apiResponse.ok) {
          return response.send({
            setupToken: data.id,
          });
        } else {
          return response.status(apiResponse.status).send(data);
        }
      } catch (error) {
        next(error);
      }
    },
  );
  ```

  ```bash server-side - cURL theme={null}
  curl -v -X POST 'https://api-m.sandbox.paypal.com/v3/vault/setup-tokens' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer ACCESS-TOKEN' \
    -d '{
      "payment_source": {
        "apple_pay": {
          "token": "ENCODED-APPLE-PAY-TOKEN"
        }
      }
    }'
  ```
</CodeGroup>

##### Create Payment Method Token (PMT)

Convert the setup token to a reusable payment method token for future transactions.

In the server-side call to the `/v3/vault/payment-tokens` endpoint:

1. Use a Bearer token in the `Authorization` header.
2. Include the following parameters:

| Parameter                   | Action                                            |
| --------------------------- | ------------------------------------------------- |
| `payment_source.token.type` | Set to `SETUP_TOKEN` to specify the token type.   |
| `payment_source.token.id`   | Set to the setup token ID from the previous step. |

**Response**: Contains the payment token in the `id` response parameter, which is the reusable token for future transactions.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  // Convert the setup token to a reusable payment token
  const vaultPmtTokenData = {
    payment_source: {
      token: {
        type: "SETUP_TOKEN",
        id: vaultSetupToken.setupToken,  // The setup token ID from the previous step
      },
    },
  };

  setMessage("Processing vault PaymentToken for Apple Pay...");
  const vaultPaymentToken = await createVpmtToken(vaultPmtTokenData);
  setMessage(
    "✅Payment Token created successfully: " + vaultPaymentToken.setupToken,  // This is the reusable token for future transactions
  );

  // Store the payment token ID for future use
  // This token can be used to process payments without requiring the customer to re-authenticate
  const paymentTokenId = vaultPaymentToken.setupToken;

  // Client-side helper function
  async function createVpmtToken(vaultData) {
    setMessage("Creating vault payment token");

    const defaultHeaders = {
      "Content-Type": "application/json",
    };

    try {
      const response = await fetch(
        "/your-server/api/paypal/vault/payment-token",
        {
          headers: {
            ...defaultHeaders,
          },
          method: "POST",
          body: JSON.stringify(vaultData),
        },
      );

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.message || "Failed to create payment token");
      }

      return data;
    } catch (error) {
      throw new Error(error);
    }
  }
  ```

  ```javascript server-side - Node.js theme={null}
  // Express route to create payment token for Apple Pay
  router.post(
    "/your-server/api/paypal/vault/payment-token",
    async (request, response, next) => {
      const appmtdata = request.body;

      try {
        const { access_token: accessToken } = await getFullScopeAccessToken(
          response.locals.config,
        );

        const requestHeaders = {
          Authorization: `Bearer ${accessToken}`,
          "Content-Type": "application/json",
        };

        const apiResponse = await fetch(
          `${response.locals.config.apiBaseUrl}/v3/vault/payment-tokens`,
          {
            body: JSON.stringify(appmtdata),
            headers: requestHeaders,
            method: "POST",
          },
        );

        const data = await apiResponse.json();

        if (apiResponse.ok) {
          return response.send({
            setupToken: data.id,
          });
        } else {
          return response.status(apiResponse.status).send(data);
        }
      } catch (error) {
        next(error);
      }
    },
  );
  ```

  ```bash server-side - cURL theme={null}
  curl -v -X POST 'https://api-m.sandbox.paypal.com/v3/vault/payment-tokens' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer ACCESS-TOKEN' \
    -d '{
      "payment_source": {
        "token": {
          "id": "VAULT-SETUP-TOKEN",
          "type": "SETUP_TOKEN"
        }
      }
    }'
  ```
</CodeGroup>

##### Complete transaction

Notify Apple Pay that the payment was processed successfully.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  appleSdkApplePayPaymentSession.completePayment({
    status: window.ApplePaySession.STATUS_SUCCESS,
  });
  ```
</CodeGroup>

#### d. Handle cancellation

In your app code, include the logic to handle cancellation when the customer closes the Apple Pay payment sheet.

Use the `onCancel()` callback function to handle cleanup operations when the customer cancels. This method doesn't require any parameters.

**Response**: Performs any necessary cleanup and resets the payment flow state.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  appleSdkApplePayPaymentSession.oncancel = () => {
    console.log("Apple Pay Cancelled!");
    onCancel();
  };
  ```
</CodeGroup>

#### e. Handle errors

In your app code, include the logic to handle errors that occur during the authentication flow.

Use the `onError()` callback function to handle errors with `data` parameter containing the error details.

**Response**: Logs the error and displays an appropriate error message to the customer.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  function onError(data) {
    console.log("onError: ", data);
    setMessage(data);
  }
  ```
</CodeGroup>

#### f. Handle completion

In your app code, include the logic to handle when the authentication flow finishes.

Use the `onComplete()` callback function to handle completion with an optional `data` parameter that may contain completion details.

**Response**: Performs any final cleanup or UI updates needed after the authentication flow completes.

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  function onComplete(data) {
    console.log("onComplete: ", data);
  }
  ```
</CodeGroup>

### 5. Start Apple Pay flow

In your app code, start the Apple Pay payment session after configuring all event handlers.

Use the `appleSdkApplePayPaymentSession.begin()` method to display the Apple Pay payment sheet. This method doesn't require any parameters.

**Response**: The Apple Pay payment sheet appears, allowing the customer to:

* View the payment request details
* Select their preferred payment method from Apple Wallet
* Authorize the payment
* Complete the save payment method flow

<CodeGroup>
  ```javascript client-side - app.js theme={null}
  // Start the Apple Pay payment session
  appleSdkApplePayPaymentSession.begin();
  ```
</CodeGroup>

## Test and go live

Validate your integration in the PayPal sandbox environment before deploying to production. For more information, see <a href="https://developer.paypal.com/docs/checkout/apm/apple-pay/#test-your-integration" target="_blank">Test and go live</a>.
