PayPal Checkout

Upgrade your Existing Checkout Integration

Upgrade your existing PayPal Checkout integration to the latest PayPal Checkout JavaScript SDK integration. The new code keeps you current with button styles and payment features.

1. Understand the PayPal Checkout JavaScript SDK checkout flow

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

  • Rather than using a static image, you are now required to use the PayPal JavaScript SDK to render the PayPal button.
  • The PayPal Checkout flow now launches in a popup window, rather than as a full-page redirect.
  • After the buyer authorizes the transaction, the PayPal button calls your JavaScript callback, rather than redirecting the buyer to a return URL.

Buyer's checkout flow

  1. Your buyer clicks the PayPal Smart Buttons
  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

2. Add the Smart Payment Buttons

Follow these steps to add the Smart Buttons to your page:

  1. Add the script to your page.
  2. Render the buttons to your page.

3. Update the 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://paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&currency=EUR&intent=order&commit=false&vault=true"></script>

4. Set up the 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 PayPal JavaScript SDK integration replaces the payment() function in the checkout.js script.

NVP integrations

If you have an existing SetExpressCheckout NVP API call, return the token value from the API 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).then(function(res) {
      return res.json();
    }).then(function(data) {
      return data.token;
    });
  }
}).render('#paypal-button-container');

Note: RETURNURL and CANCELURL in the NVP API are not used by the PayPal JavaScript SDK integration.

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

Note: Read Customize PayPal JavaScript SDK script to learn how to customize the intent, currency, commit, vault and locale values.

Server-side REST integrations with /v1/payments

If you have an existing call to the /v1/payments/payment REST API, return the EC-XXXXX token from the response of that API call.

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

  "links": [
    {
      "href": "https://api.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.sandbox.paypal.com/v1/payments/payment/PAY-1B56960729604235TKQQIYVY/execute",
      "rel": "execute",
      "method": "POST"
    }
  ]

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

Return the token to createOrder on the client side. In this example, the required token is EC-60385559L1062554J:

paypal.Buttons({
  createOrder: function() {
    var CREATE_PAYMENT_URL = 'https://mystore.com/api/paypal/create-payment';

    return fetch(CREATE_PAYMENT_URL).then(function(res) {
      return res.json();
    }).then(function(data) {
      return data.token;
    });
  }
}).render('#paypal-button-container');

Note: return_url and cancel_url in the /v1/payments/payment API are not used by the PayPal JavaScript SDK integration.

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

Note: See Customize PayPal JavaScript SDK script for instructions on how to customize the intent, currency, commit, vault and locale values.

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

First, update your script tag to pass vault=true.

<script src="https://paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&vault=true"></script>

Then, return the BA-XXXXX token to createBillingAgreement from the response of the /v1/billing-agreements/agreement-tokens call:

paypal.Buttons({
  createBillingAgreement: function() {
    var CREATE_BILLING_AGREEMENT_URL = 'https://mystore.com/api/paypal/create-billing-agreement';

    return fetch(CREATE_BILLING_AGREEMENT_URL).then(function(res) {
      return res.json();
    }).then(function(data) {
      return data.billingToken;
    });
  }
}).render('#paypal-button-container');

Note: return_url and cancel_url in the /v1/billing-agreements/agreement-tokens API are not used by the PayPal JavaScript SDK integration.

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

Note: See Customize SDK for instructions on how to customize the intent, currency, commit, vault and locale values.

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

If you have an existing call to actions.payment.create(), migrate to actions.order.create(). Refer to Set up the transaction in the basic integration.

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

5. Finalize the 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 new JavaScript integration.

NVP integrations

If you have an existing DoExpressCheckoutPayment NVP API call, call your server with the data.orderID and data.payerID values:

paypal.Buttons({
  onApprove: function(data) {
    var DOEC_URL = 'https://mystore.com/api/paypal/do-express-checkout';

    return fetch(DOEC_URL, {
      method: 'post',
      body: JSON.stringify({
        token:   data.orderID,
        payerID: data.payerID
      })
    });
  }
}).render('#paypal-button-container');

Then on your server, invoke your existing DoExpressCheckoutPayment call with the token and payerID.

Server-side REST integrations with /v1/payments

If you have an existing call to /v1/payments/payment/PAY-XXX/execute REST API, 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',
      body: JSON.stringify({
        paymentID: data.paymentID,
        payerID:   data.payerID
      })
    });
  }
}).render('#paypal-button-container');

Then on your server, invoke your existing /v1/payments/payment/PAY-XXX/execute call with the paymentID and payerID.

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

If you have an existing call to /v1/billing-agreements/agreements REST API, call your server with the data.billingToken value.

paypal.Buttons({
  onApprove: function(data) {
    var FINALIZE_BILLING_URL = 'https://mystore.com/api/paypal/finalize-billing-agreement';

    return fetch(FINALIZE_BILLING_URL, {
      method: 'post',
      body: JSON.stringify({
        billingToken: data.billingToken
      })
    });
  }
}).render('#paypal-button-container');

Then on your server, invoke your existing /v1/billing-agreements/agreements call with the billingToken.

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

If you have an existing call to actions.payment.execute(), migrate to actions.order.capture(). Refer to Finalize the payment in the basic integration.

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

6. Fix deprecations

For checkout.js integrations, see the following list of deprecations and upgrade each item to the new integration standard. To debug issues, check your browser's JavaScript console for errors.

Task Deprecated integration New integration Reference
Add the script Add a script pointing to paypalobjects.com/api/checkout.js Add a script pointing to paypalobjects.com/sdk/js Add the script
Render the Smart Payment Buttons Add a client-side call to paypal.Button.render({}, '#el'); Add a client-side call to paypal.Buttons({}).render('#el'); Render the Buttons
Handle a click from the Smart Payment Buttons to set up a transaction Add the payment() { ... } callback Add the createOrder() { ... } callback Set up the transaction
Set up a transaction from the client Add a call to actions.payment.create() Add a call to actions.order.create() Set up the transaction
Handle a successful buyer approval for a transaction Add the onAuthorize() { ... } callback Add the onApprove() { ... } callback Capture the transaction
Capture a transaction from the client Add a call to actions.payment.execute() Add a call to actions.order.capture() Capture the transaction
Get transaction details from the client Add a call to actions.payment.get() Add a call to actions.order.get() Get the transaction details
Render buttons of different sizes Set style.size to small, medium, large, and responsive Set the size of the container element to your preferred size Style the Buttons
Pass your PayPal client-id to the Smart Payment Buttons Pass the client option when calling paypal.Button.render() Pass client-id=xyz to the /sdk/js script tag Add the PayPal script
Show a Pay Now or Continue button in the checkout experience Pass the commit: true or commit: false option when calling paypal.Button.render() Pass commit=true or commit=false to the /sdk/js script tag Commit
Switch between sandbox and production PayPal environments Pass the env option when calling paypal.Button.render() Pass client-id=xyz to the /sdk/js script tag and the environment will be autodetected Client ID
Change the language of the buttons Pass the locale option when calling paypal.Button.render() Pass locale=xx_XX to the /sdk/js script tag Locale
Show card logos below the buttons Pass the style.fundingicons option when calling paypal.Button.render() The card buttons display automatically in the default integration Smart Payment Buttons integration
Opt-in to enable a button for a specific funding source Pass the funding.allowed option when calling paypal.Button.render() PayPal automatically decides on the optimal buttons to show to your buyers Smart Payment Buttons Integration
Opt out to disable a button for a specific funding source Pass the funding.disallowed option when calling paypal.Button.render() Pass disable-funding or disable-card to the /sdk/js script tag Disable Funding and Disable card
Make a call to your server from the buttons Use paypal.request, paypal.request.get, paypal.request.post Use the built-in browser fetch function, with a polyfill if needed, or your AJAX library of choice. Fetch
Use promises for asynchronous tasks Use paypal.Promise Use the built-in browser Promise, with a polyfill if needed, or your promise library of choice. Promise
Redirect to success and cancel urls Pass a return and cancel URL when setting up the transaction, then use actions.redirect() in onAuthorize and onCancel Do not pass a return or cancel URL when setting up the transaction. Call actions.redirect('/done-page'); in onApprove and actions.redirect('/cancel-page'); in onCancel Redirect

7. Test your integration

Test your upgraded integration and launch it into production:

Feedback