Checkout with PayPalanchor

Checkout with PayPal is a one-time payment checkout experience that gives you more control over the entire checkout process. It offers a streamlined checkout flow that keeps customers local to your website during the payment authorization process.

Unlike the Vault flow, Checkout with PayPal does not provide the ability to store a customer's PayPal account in the Vault. If you want to store a customer’s PayPal account within a Vault during Checkout, view the Checkout with Vault integration guide. However, if you are located in a country that supports PayPal One Touch™, your customer can make repeat purchases without re-entering their user credentials after their initial purchase.

Checkout with PayPal supports the following features:

  • Select or add shipping addresses in the PayPal account
  • Select or add funding instruments in the PayPal account
  • Two factor authentication support (currently only for US, UK, CA, DE, AT, and AU)


Typical use cases for the Checkout With PayPal flow:

  • Checkout from Cart/Product pages
  • Checkout page replacement

Invoking the Checkout with PayPal flowanchor


The examples here require version 3.90.0 or higher of the Braintree JavaScript SDK.

If you are using the Braintree JavaScript SDK with the deprecated PayPal checkout.js library, review this migration guide to upgrade your integration.

To request a one-time payment, set flow to 'checkout' and include amount and currency options in your createPayment call. The value of currency must match the value passed into loadPayPalSDK.

If intent is used, the value must match in both loadPayPalSDK and createPayment.

Use a createOrder function to create the payment resource:

  1. CallBack
  2. Promise
// Create a client.
}, function (clientErr, clientInstance) {

  // Stop if there was a problem creating the client.
  // This could happen if there is a network error or if the authorization
  // is invalid.
  if (clientErr) {
    console.error('Error creating client:', clientErr);

  // Create a PayPal Checkout component.
    client: clientInstance
  }, function (paypalCheckoutErr, paypalCheckoutInstance) {
      currency: 'USD',
      intent: 'capture'
    }, function () {
        fundingSource: paypal.FUNDING.PAYPAL,

        createOrder: function () {
          return paypalCheckoutInstance.createPayment({
            flow: 'checkout', // Required
            amount: 10.00, // Required
            currency: 'USD', // Required, must match the currency passed in with loadPayPalSDK

            intent: 'capture', // Must match the intent passed in with loadPayPalSDK

            enableShippingAddress: true,
            shippingAddressEditable: false,
            shippingAddressOverride: {
              recipientName: 'Scruff McGruff',
              line1: '1234 Main St.',
              line2: 'Unit 1',
              city: 'Chicago',
              countryCode: 'US',
              postalCode: '60652',
              state: 'IL',
              phone: '123.456.7890'

        onShippingChange: function (data, actions) {
          // Perform some validation or calculation logic on 'data'

          if ( /* need to update shipping options or lineItems */ ) {
            return paypalCheckoutInstance.updatePayment({
              amount: 10.00,              // Required
              currency: 'USD',
              lineItems: [...],           // Required
              paymentId: data.paymentId,  // Required
              shippingOptions: [...],     // Optional       
          } else if (/* address not supported */) {
            return actions.reject();

          return actions.resolve();

        onApprove: function (data, actions) {
          return paypalCheckoutInstance.tokenizePayment(data, function (err, payload) {
            // Submit 'payload.nonce' to your server

        onCancel: function (data) {
          console.log('PayPal payment cancelled', JSON.stringify(data, 0, 2));

        onError: function (err) {
          console.error('PayPal error', err);
      }).render('#paypal-button').then(function () {
        // The PayPal button will be rendered in an html element with the ID
        // 'paypal-button'. This function will be called when the PayPal button
        // is set up and ready to be used

If you are using an Activity and your Activity's launch mode is singleTop, singleTask, or singleInstance you will also need to override onNewIntent:

Use the onShippingChange function from the PayPal JS SDK setup method to listen for shipping changes that occur within the PayPal pop-up; then, use the updatePayment function , part of the Braintree JS SDK's paypalCheckoutInstance, to update the PayPal checkout flow with modified order line items or shipping options. Note that updatePayment replaces use of actions.order.patch.

Use the paypalCheckoutInstance in the onApprove function of the PayPal JS SDK setup method to tokenize the PayPal account. After the customer completes the consent flow and the PayPal pop-up closes, successful tokenization will return a payment method nonce.

Send the nonce to your server and use a Braintree server SDK to call to create a transaction.

See our JavaScript Paypal client reference for more information on the options available in the Checkout with PayPal flow.

Country supportanchor

PayPal is available to merchants in all countries that we support and to customers in 140+ countries. Ensure you are using a desired locale code as outlined in our Javascript PayPal client reference.

Currency presentmentanchor

The currency of the transaction is presented to the customer in the Checkout with PayPal flow. We support all currencies that PayPal REST APIs support.

See the server-side section for details on charging a transaction in a specific currency.

Next Page: Server-side →