Upgrade your Checkout integration

If you have older checkout integrations, like Express Checkout or checkout.js, you can upgrade your integration to take advantage of the current JavaScript SDK integration. The JavaScript SDK keeps your integration current with button styles and payment features.

Know before you code

Before you start the upgrade, understand key concepts of the JavaScript SDK flow:

  • To render the payment buttons, you must use the JavaScript SDK rather than a static image.
  • The payment flow launches in a pop-up window instead of doing a full-page redirect.

Also,

  • Complete the steps in Get started to get the following sandbox account information from the Developer Dashboard:

    • Your client ID
    • Your personal and business sandbox accounts
  • Use your client ID when adding payment options to your website. Use your sandbox accounts when testing the checkout options.

How it works

After the buyer authorizes the transaction, the payment buttons call your JavaScript callback rather than redirecting the buyer to a return URL.

Buyer's checkout flow

  1. Your buyer clicks a payment button.
  2. Your buyer logs into PayPal.
  3. Your buyer approves the transaction on PayPal.
  4. Your buyer returns to your site, and you show them a confirmation page.

1. Add payment buttons

Add the JavaScript SDK and payment buttons to your page.

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Ensures optimal rendering on mobile devices. -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <!-- Optimal Internet Explorer compatibility -->
  </head>

  <body>
    <script src="https://www.paypal.com/sdk/js?client-id=YOUR_SB_CLIENT_ID"> // Replace YOUR_SB_CLIENT_ID with your sandbox client ID
    </script>

    <div id="paypal-button-container"></div>

  </body>
</html>

Modify the code

  1. Copy the sample JavaScript SDK code and paste it into the code of your checkout page.
  2. In the SDK code, replace YOUR_SB_CLIENT_ID with your client ID.

See also

Add payment buttons.

2. Update script

Update the script tag to pass the correct parameters for your integration:

  • The currency of the transaction.
  • The intent of the transaction.
  • Whether the transaction is a commit with a Pay Now button or a Continue button.
  • Whether the transaction sets up a vault, including reference transactions or subscriptions.

See all parameters that you can pass to the script. For example:

<script src="https://www.paypal.com/sdk/js?client-id=YOUR_SB_CLIENT_ID&currency=EUR&intent=order&commit=false&vault=true"></script>

3. Set up transaction

When your buyer clicks the PayPal button, the script calls a createOrder() function that you define. In this function, return a promise for a token, payment ID, or order ID, from the PayPal API you're calling:

Note: The createOrder() function in the JavaScript SDK integration replaces the payment() function in the checkout.js script.

NVP/SOAP integrations

Return the token value from an NVP/SOAP SetExpressCheckout response to the client. Then, return that token in the createOrder function:

paypal.Buttons({
  createOrder: function() {
    var SETEC_URL = 'https://mystore.com/api/paypal/set-express-checkout';

    return fetch(SETEC_URL, {
      method: 'post',
      headers: {
        'content-type': 'application/json'
      }
    }).then(function(res) {
      return res.json();
    }).then(function(data) {
      return data.token;
    });
  }
}).render('#paypal-button-container');

Notes:

  • The JavaScript SDK integration does not use the RETURNURL and CANCELURL values in the NVP/SOAP API.

    Pass https://www.paypal.com/checkoutnow/error as a placeholder value for these keys. To handle transaction success or failure, use onApprove, onCancel, and onError.

  • To customize the intent, currency, commit, vault and locale values, see the JavaScript SDK reference.

Server-side REST integrations with /v1/payments

Return the EC-XXXXX token from the REST API /v1/payments/payment response.

API endpoint used: Create payment

  1. Locate the token in the response links array, in the object where rel is "approval_url":

    "links": [{
      "href": "https://api-m.sandbox.paypal.com/v1/payments/payment/PAY-1B56960729604235TKQQIYVY",
      "rel": "self",
      "method": "GET"
    }, {
      "href": "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-60385559L1062554J",
      "rel": "approval_url",
      "method": "REDIRECT"
    }, {
      "href": "https://api-m.sandbox.paypal.com/v1/payments/payment/PAY-1B56960729604235TKQQIYVY/execute",
      "rel": "execute",
      "method": "POST"
      }]
    
  2. Extract the EC-XXXXXX token from the array:

    let token;
    
    for (let link of response.links) {
      if (link.rel === 'approval_url') {
        token = link.href.match(/EC-\w+/)[0];
      }
    }
    
    // Now return the `token` to the client
    
  3. Return the token to createOrder on the client side.

    The required token is EC-60385559L1062554J in this example:

    paypal.Buttons({
      createOrder: function() {
        var CREATE_PAYMENT_URL = 'https://mystore.com/api/paypal/create-payment';
    
        return fetch(CREATE_PAYMENT_URL, {
          method: 'post',
          headers: {
            'content-type': 'application/json'
          }
        }).then(function(res) {
          return res.json();
        }).then(function(data) {
          return data.token;
        });
      }
    }).render('#paypal-button-container');
    

    Notes:

    • The JavaScript SDK integration does not use return_url and cancel_url in the /v1/payments/payment endpoint.

      Pass https://www.paypal.com/checkoutnow/error as a placeholder value for these keys. To handle transaction success or failure, use onApprove, onCancel, and onError.

    • To customize the intent, currency, commit, vault, and locale values, see the JavaScript SDK reference.

Billing agreement integrations with /v1/billing-agreements/agreement-tokens

  1. Update your script tag to pass vault=true.

    <script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&vault=true"></script>
    
  2. Return the BA-XXXXX token to createBillingAgreement from the response of the /v1/billing-agreements/agreement-tokens call.

    API endpoint used: Create agreement

    paypal.Buttons({
      createBillingAgreement: function() {
        var CREATE_BILLING_AGREEMENT_URL = 'https://mystore.com/api/paypal/create-billing-agreement';
    
        return fetch(CREATE_BILLING_AGREEMENT_URL, {
          method: 'post',
          headers: {
            'content-type': 'application/json'
          }
        }).then(function(res) {
          return res.json();
        }).then(function(data) {
          return data.billingToken;
        });
      }
    }).render('#paypal-button-container');
    

    Notes:

    • The JavaScript SDK integration does not use the return_url and cancel_url values in the /v1/billing-agreements/agreement-tokens endpoint.

      To handle transaction success or failure, pass https://www.paypal.com/checkoutnow/error as a placeholder value for these keys, and use on onApprove, onCancel, and onError.

    • To customize the intent, currency, commit, vault and locale values, see the JavaScript SDK reference.

checkout.js integrations with actions.payment.create()

Migrate the actions.payment.create() call to actions.order.create().

See Add payment buttons.

paypal.Buttons({
  createOrder: function() {
    return actions.order.create({
      purchase_units: [{
        amount: {
          value: '220.00'
        }
      }]
    });
  }
}).render('#paypal-button-container');

4. Finalize payment

After your buyer logs in to PayPal and authorizes the transaction, the script calls the onApprove() function that you defined. This function finalizes the transaction.

Note: The onAuthorize() function from the checkout.js script is replaced by the onApprove() function in the JavaScript SDK integration.

NVP/SOAP integrations

  1. Call your server with the data.orderID and data.payerID values in a DoExpressCheckoutPayment NVP/SOAP API call:

    paypal.Buttons({
      onApprove: function(data) {
        var DOEC_URL = 'https://mystore.com/api/paypal/do-express-checkout';
    
        return fetch(DOEC_URL, {
          method: 'post',
          headers: {
            'content-type': 'application/json'
          },
          body: JSON.stringify({
            token:   data.orderID,
            payerID: data.payerID
          })
        });
      }
    }).render('#paypal-button-container');
    
  2. Invoke a DoExpressCheckoutPayment call on your server with the token and payerID.

Server-side REST integrations with /v1/payments

API endpoint used: Create payment

  1. If you have a call to the /v1/payments/payment/PAY-XXX/execute endpoint, call your server with the data.paymentID and data.payerID values:

    paypal.Buttons({
      onApprove: function(data) {
        var EXECUTE_URL = 'https://mystore.com/api/paypal/execute-payment';
    
        return fetch(EXECUTE_URL, {
          method: 'post',
          headers: {
            'content-type': 'application/json'
          },
          body: JSON.stringify({
            paymentID: data.paymentID,
            payerID:   data.payerID
          })
        });
      }
    }).render('#paypal-button-container');
    
  2. On your server, invoke a /v1/payments/payment/PAY-XXX/execute call with the paymentID and payerID.

Billing agreement integrations with /v1/billing-agreements/agreement-tokens

API endpoint used: Create agreement

  1. Call your server with the data.billingToken value in a REST API /v1/billing-agreements/agreements call.

    paypal.Buttons({
      onApprove: function(data) {
        var FINALIZE_BILLING_URL = 'https://mystore.com/api/paypal/finalize-billing-agreement';
    
        return fetch(FINALIZE_BILLING_URL, {
          method: 'post',
          headers: {
            'content-type': 'application/json'
          },
          body: JSON.stringify({
            billingToken: data.billingToken
          })
        });
      }
    }).render('#paypal-button-container');
    
  2. Invoke a /v1/billing-agreements/agreements call on your server with the billingToken.

Client-side REST integrations with actions.payment.create()

Migrate the actions.payment.execute() to actions.order.capture(). See Set up standard payments.

paypal.Buttons({
  onApprove: function(data, actions) {
    return actions.order.capture();
  }
}).render('#paypal-button-container');

5. Fix deprecations

For checkout.js integrations, upgrade the deprecated integration to the current integration. To debug issues, check your browser's JavaScript console for errors.

Deprecated integration Upgrade to integration

Add a script that points to paypalobjects.com/api/checkout.js.

Add a script that points to paypalobjects.com/sdk/js.

See Set up standard payments.

Add a client-side call to paypal.Button.render({}, '#el');.

Add a client-side call to paypal.Buttons({}).render('#el');.

See Set up standard payments.

Add the payment() { ... } callback.

Add the createOrder() { ... } callback.

See Set up standard payments.

Add the actions.payment.create() call.

Add the actions.order.create() call.

See Set up standard payments.

Add the onAuthorize() { ... } callback.

Add the onApprove() { ... } callback.

See Set up standard payments.

Add the actions.payment.execute() call.

Add the actions.order.capture() call.

See Set up standard payments.

Set style.size to small, medium, large, and responsive.

Set the container element to your preferred size.

See Customize the payment buttons.

Pass the client option in the paypal.Button.render() call.

Pass client-id=xyz to the /sdk/js script tag.

See Set up standard payments.

Pass the commit: true or commit: false option in the paypal.Button.render() call.

Pass commit=true or commit=false to the /sdk/js script tag.

See Commit.

Pass the env option in the paypal.Button.render() call.

Pass client-id=xyz to the /sdk/js script tag and auto-detect the environment.

See Client ID.

Pass the locale option in the paypal.Button.render() call.

Pass locale=xx_XX to the /sdk/js script tag.

See Locale.

Pass the style.fundingicons option in the paypal.Button.render() call.

The card buttons display automatically in the default integration.

See Set up standard payments.

Pass the funding.allowed option in the paypal.Button.render() call.

PayPal automatically decides on the optimal buttons to show to your buyers.

See Set up standard payments.

Pass the funding.disallowed option in the paypal.Button.render() call.

Pass disable-funding or disable-card to the /sdk/js script tag.

See Disable Funding and Disable card.

Use paypal.request, paypal.request.get, paypal.request.post.

Use the built-in browser fetch function, with a polyfill or your AJAX library of choice.

See Fetch.

Use paypal.Promise.

Use the built-in browser Promise, with a polyfill or your promise library of choice.

See Promise.

When you set up transaction, pass return and cancel URLs.

Call actions.redirect() in onAuthorize and onCancel.

When you set up transaction, do not pass return and cancel URLs.

Call actions.redirect('/done-page'); in onApprove.

Call actions.redirect('/cancel-page'); in onCancel.

See Redirect.

6. Test your integration

Test and go live with your upgraded integration.