Returning buyer integration (SDK)

DOCS

Last updated: Sept 23rd, 9:45pm

Enhance your existing PayPal billing agreement SDK integration for returning buyers.

On this page

Know before you code

Make sure you complete or have the following before you begin:

  • Complete the steps in Get started to get the following sandbox account information from the Developer Dashboard:
    • Get API Credentials (Client ID and Secret)
    • Exchange your API credentials for an access token
  • Make sure you have the ability to identify the buyers who come to your website.
  • Make sure you are enabled to create and process payments using billing agreements.

1. Generate ID token

Generate an ID token for your buyer.

Pass the billing agreement ID to PayPal to generate an ID token. The ID token is a unique ID for each billing agreement ID that's created.

Sample client token request

    1curl -v POST https://api-m.sandbox.paypal.com/v1/identity/generate-token \
    2 -H 'Accept: application/json' \
    3 -H 'Accept-Language: en_US' \
    4 -H 'Authorization: Bearer <ACCESS-TOKEN>' \
    5 -H 'Content-Type: application/json' \
    6 -d '{
    7 "billing_agreement_id": "B-XXXXXXXXXXXX"
    8 }'

    Modify the code

    1. Copy the sample request code.
    2. Change the access token to your sandbox access token.
    3. Replace B-XXXXXXXXXXXX with the billing agreement ID created for that particular buyer.

    Sample client token response

      1{
      2 "client_token": "eyJicmFpbnRyZWUiOnsiYXV0aG9yaXphdGlvbkZpbmdlcnByaW50IjoiYTI1ZjhmYTUwYjc2NmY1YTg2ZjUwOGY1NDgxNWIxNGIyYjNkYjk1MzQ0ZjMyNjAwOWI5NmQ3YjFlOTAzZGNiNHxtZXJjaGFudF9pZD1yd3dua3FnMnhnNTZobTJuJnB1YmxpY19rZXk9NjNrdm4zN3Z0MjlxYjRkZiZjcmVhdGVkX2F0PTIwMjEtMDgtMjVUMDg6MzQ6MzAuMzg2WiZjdXN0b21lcl9pZD1jdXN0b21lcl81NzgwNDI1MjkiLCJ2ZXJzaW9uIjoiMy1wYXlwYWwifSwicGF5cGFsIjp7ImlkVG9rZW4iOiJleUpyYVdRaU9pSmxOREEyTmpBNFlqVTBZVGswTkRneFlqazFZemMxTkRJME9HTmpNVEl6WmlJc0luUjVjQ0k2SWtwWFZDSXNJbUZzWnlJNklsSlRNalUySW4wLmV5SnBjM01pT2lKb2RIUndjem92TDJGd2FTNXpZVzVrWW05NExuQmhlWEJoYkM1amIyMGlMQ0p5YjJ4bElqb2lUVVZTUTBoQlRsUWlMQ0psZUhSbGNtNWhiRjlwWkNJNld5SlFZWGxRWVd3Nk9FZEhPVXRWVWtRMVFVTlpNaUpkTENKelpYTnphVzl1WDJsdVpHVjRJam9pVTJwNGFYZ3hTMDloVW1SNGNtbFhNWGgwV0RWamRWZHhUalZwSWl3aVkyeHBaVzUwWDJsa0lqb2lRV1F3YlZFeGNFSm1kbkEwYlc5Q01qQlNaMFJrTlZadVZtVktWR2h6YVdSbFMwNVNWemQ0TmtJM1oxY3hNMlk0U0docFUyNXlOSEJIYVVSek4wOVhjakJIU1VwYVgwOVFRVW90VTJNeVNVZ2lMQ0poWTNJaU9sc2lZMnhwWlc1MElsMHNJbUYxWkNJNklrRmtNRzFSTVhCQ1puWndORzF2UWpJd1VtZEVaRFZXYmxabFNsUm9jMmxrWlV0T1VsYzNlRFpDTjJkWE1UTm1PRWhvYVZOdWNqUndSMmxFY3pkUFYzSXdSMGxLV2w5UFVFRktMVk5qTWtsSUlpd2lZWFYwYUY5MGFXMWxJam94TmpJNU9EZ3dORGN3TENKdmNIUnBiMjV6SWpwN0ltTjFjM1J2YldWeVgybGtJam9pWTNWemRHOXRaWEpmTlRjNE1EUXlOVEk1SW4wc0ltRjZJam9pWjJOd0xuTnNZeUlzSW5OamIzQmxjeUk2V3lKQ2NtRnBiblJ5WldVNlZtRjFiSFFpTENKUVlYbHdZV3c2YjI1bFgzUnBiV1ZmY0dGNWJXVnVkQ0pkTENKbGVIQWlPakUyTWprNE9ERXpOekFzSW1saGRDSTZNVFl5T1RnNE1EUTNNQ3dpYW5ScElqb2lWVEpCUVVwM1dYYzVSV2t5YWkwME1qUmZOakl6ZGtsTVpEVlZNMWRLVFcxcFVucHVUMXB0UmsxNGVEaHBZak4xY3pkWFVEa3hXVVpTZW1KUFFqRk9hVUpMYkhrdFRHMXJOemRzWDJaNGJXRmhOV0ZsUnpoU2NHeHlUMVYwWW0xclUwWjBMVWhVYmtKT1IzWnVUWFJQUTBkNFVHSkpXRFJVY0hkbGJFaHhWbEVpZlEuSXlrTktCZ2c5RWtGaFJ5TC0yT3hnTUswb0p6Y09XazYwaEpORS03Qm5vdkI3RURTS18tNkM1RmtDZUpqamk1YjB5TjM1S3RaeHNnWFZlT2VVSkozd240THI0UTZ1LWIxRV9kOFpjb04tZDRZa2FXd0tKVnhYWFR5NVI1NGJLRXdWWjBLZXI0WGdXM3NFWnhGNnFiaktrbmQtNnJWVjNkTFZDU1ZtUEk1a29TMFRQTXp1OGI4QjBTX2JfUldCbXhSRUNJV0lEVGZGdGxqZnA0SWp0czhJeDFBa1dxMXRsR21qcUtDdmpMTTBnakszeExndjBfUlNzRkcxX3BxNEhzUWRKc1JmeDg2TUw5R3h1ZlZFSk1NV0FoZDhfbDlGSmUtQ3N0TU4weVR5RUZaeEljWUIwSk53d1lWbWowSGtKdGR2bHJPdDhuX3N6RmdBNVByYm1YZW93IiwiYWNjZXNzVG9rZW4iOiJBMjFBQUpDY2NvNmhMRzBIQi1SeHh4Zy1Tb3F2Qjg4RUFPQjVJZGFjX05VQlZac0VrVGhOZ0dUSzc2RDlrRHZhZVE3bzNRbFY3OWJYS0M5VUVMTDk0eVhwV19KUXgyQ3BBIn19",
      3 "id_token": "eyJraWQiOiJlNDA2NjA4YjU0YTk0NDgxYjk1Yzc1NDI0OGNjMTIzZiIsInR5cCI6IkpXVCIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJodHRwczovL2FwaS5zYW5kYm94LnBheXBhbC5jb20iLCJyb2xlIjoiTUVSQ0hBTlQiLCJleHRlcm5hbF9pZCI6WyJQYXlQYWw6OEdHOUtVUkQ1QUNZMiJdLCJzZXNzaW9uX2luZGV4IjoiU2p4aXgxS09hUmR4cmlXMXh0WDVjdVdxTjVpIiwiY2xpZW50X2lkIjoiQWQwbVExcEJmdnA0bW9CMjBSZ0RkNVZuVmVKVGhzaWRlS05SVzd4NkI3Z1cxM2Y4SGhpU25yNHBHaURzN09XcjBHSUpaX09QQUotU2MySUgiLCJhY3IiOlsiY2xpZW50Il0sImF1ZCI6IkFkMG1RMXBCZnZwNG1vQjIwUmdEZDVWblZlSlRoc2lkZUtOUlc3eDZCN2dXMTNmOEhoaVNucjRwR2lEczdPV3IwR0lKWl9PUEFKLVNjMklIIiwiYXV0aF90aW1lIjoxNjI5ODgwNDcwLCJvcHRpb25zIjp7ImN1c3RvbWVyX2lkIjoiY3VzdG9tZXJfNTc4MDQyNTI5In0sImF6IjoiZ2NwLnNsYyIsInNjb3BlcyI6WyJCcmFpbnRyZWU6VmF1bHQiLCJQYXlwYWw6b25lX3RpbWVfcGF5bWVudCJdLCJleHAiOjE2Mjk4ODEzNzAsImlhdCI6MTYyOTg4MDQ3MCwianRpIjoiVTJBQUp3WXc5RWkyai00MjRfNjIzdklMZDVVM1dKTW1pUnpuT1ptRk14eDhpYjN1czdXUDkxWUZSemJPQjFOaUJLbHktTG1rNzdsX2Z4bWFhNWFlRzhScGxyT1V0Ym1rU0Z0LUhUbkJOR3ZuTXRPQ0d4UGJJWDRUcHdlbEhxVlEifQ.IykNKBgg9EkFhRyL-2OxgMK0oJzcOWk60hJNE-7BnovB7EDSK_-6C5FkCeJjji5b0yN35KtZxsgXVeOeUJJ3wn4Lr4Q6u-b1E_d8ZcoN-d4YkaWwKJVxXXTy5R54bKEwVZ0Ker4XgW3sEZxF6qbjKknd-6rVV3dLVCSVmPI5koS0TPMzu8b8B0S_b_RWBmxRECIWIDTfFtljfp4Ijts8Ix1AkWq1tlGmjqKCvjLM0gjK3xLgv0_RSsFG1_pq4HsQdJsRfx86ML9GxufVEJMMWAhd8_l9FJe-CstMN0yTyEFZxIcYB0JNwwYVmj0HkJtdvlrOt8n_szFgA5PrbmXeow",
      4 "expires_in": 3600
      5}

      2. Add the SDK and buttons

      Add the JavaScript SDK and payment buttons to your page.

      Copy the sample JavaScript SDK code and paste it into the code of your checkout page or any other page where you want to render the buttons.

        1<!DOCTYPE html>
        2<html>
        3 <head>
        4 <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Ensures optimal rendering on mobile devices. -->
        5 <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <!-- Optimal Internet Explorer compatibility -->
        6 </head>
        7 <body>
        8 <script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID¤cy=CURRENCY&intent=capture&commit=false" data-user-id-token=YOUR_ID_TOKEN> // Replace YOUR_CLIENT_ID with your sandbox client ID
        9 </script>
        10 <div id="paypal-button-container"></div>
        11 </body>
        12</html>

        Modify the code

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

        • In the SDK code, replace YOUR_CLIENT_ID with your client ID.
        • In the SDK code, replace YOUR_ID_TOKEN with your ID token.

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

        3. Render the button

        Tell the SDK how to render button and what action to take.

        Sample code

          1paypal.Buttons({
          2// More code to be added here
          3}).render('#paypal-button-container');

          4. Set up a transaction or create an order

          Tell the SDK how to setup a transaction or create an order.

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

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

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

            1paypal.Buttons({
            2 createOrder: function() {
            3 var SETEC_URL = 'https://mystore.com/api/set-express-checkout';
            4
            5 return fetch(SETEC_URL, {
            6 method: 'post',
            7 headers: {
            8 'content-type': 'application/json'
            9 }
            10 }).then(function(res) {
            11 return res.json();
            12 }).then(function(data) {
            13 return data.token;
            14 });
            15 }
            16}).render('#paypal-button-container');
            • Make sure the amount is greater than zero.
            • The SetExpressCheckout call should not contain any references to billing agreement parameter such as L_BILLINGTYPEn.
            • Add NOSHIPPING=1 if no shipping address is required to be passed during a transaction, or add NOSHIPPING=0 and ADDROVERRIDE=1 if the shipping address must be passed along with the shipping address (using the shipping address fields in SetExpressCheckout).
            • Because the JavaScript SDK 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 by using actions.redirect(‘/desired-page').
            • For a returning buyer, you don't need to get the buyer approval because you already have consent from them for future purchases.

            5. Buyer approval

            Tell the SDK what to do on getting buyer approval.

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

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

              1paypal.Buttons({
              2 onApprove: function(data) {
              3 var DOEC_URL = 'https://mystore.com/api/do-express-checkout';
              4
              5 return fetch(DOEC_URL, {
              6 method: 'post',
              7 headers: {
              8 'content-type': 'application/json'
              9 },
              10 body: JSON.stringify({
              11 token: data.orderID,
              12 payerID: data.payerID
              13 })
              14 });
              15 }
              16}).render('#paypal-button-container');

              Invoke a DoExpressCheckoutPayment call on your server with the token and payerID. This, in turn, calls the DoReferenceTransaction functionality API that's called during a direct API integration.