Customize the Checkout Flow

For more complex integrations, you can add options to the checkout.js script to:

See checkout.js advanced documentation in the PayPal Checkout Github repo.

Implement the Pay Now checkout flow

In the Pay Now experience, the payment occurs immediately after the buyer clicks the Pay Now button on the checkout page.

To initialize the Pay Now checkout experience, set the commit parameter to true:

paypal.Button.render({
    commit: true
});

Show a confirmation page

In the onAuthorize call back, show a confirmation page. Use the payment and buyer details from actions.payment.get().

Note: You must show a confirmation without redirecting the page. Otherwise the actions.payment.execute() and actions.payment.get() functions become unavailable. Alternatively, you can use the server-side REST or Braintree server-side SDK to execute the payment on the server.

Try the full interactive demo.

<script>
    paypal.Button.render({

        env: 'production', // Optional: specify 'sandbox' environment

        client: {
            sandbox:    'xxxxxxxxx',
            production: 'xxxxxxxxx'
        },

        payment: function(data, actions) {
            return actions.payment.create({
                payment: {
                    transactions: [
                        {
                            amount: { total: '1.00', currency: 'USD' }
                        }
                    ]
                }
            });
        },

        commit: true, // Optional: show a 'Pay Now' button in the checkout flow

        onAuthorize: function(data, actions) {

            // Get the payment details

            return actions.payment.get().then(function(paymentDetails) {

                // Show a confirmation using the details from paymentDetails
                // Then listen for a click on your confirm button

                document.querySelector('#confirm-button')
                    .addEventListener('click', function() {

                    // Execute the payment

                    return actions.payment.execute().then(function() {
                        // Show a success page to the buyer
                    });
                });
            });
        }

    }, '#paypal-button');
</script>

Show a cancellation page

Normally when a buyer cancels a payment, the buyer is returned to the parent page. Instead, you can use the onCancel function to show a cancellation page or return to a shopping cart:

<script>
    paypal.Button.render({

        env: 'production', // Specify 'sandbox' for the test environment

        payment: function() {
            // Set up the payment here, when the buyer clicks on the button
        },

        onAuthorize: function(data, actions) {
            // Execute the payment here, when the buyer approves the transaction
        },

        onCancel: function(data, actions) {
            // Show a cancel page or return to cart
        }

    }, '#paypal-button');
</script>

Pass experience profile options

To customize the experience further using the Experience API, you can pass extra options in actions.payment.create().

In this example we pass the no_shipping flag to disable collection of shipping addresses:

<script>
    paypal.Button.render({

        env: 'production', // Optional: specify 'sandbox' environment

        client: {
            sandbox:    'xxxxxxxxx',
            production: 'xxxxxxxxx'
        },

        payment: function(data, actions) {
            return actions.payment.create({
                payment: {
                    transactions: [
                        {
                            amount: { total: '1.00', currency: 'USD' }
                        }
                    ]
                },

                experience: {
                    input_fields: {
                        no_shipping: 1
                    }
                }
            });
        },

        commit: true, // Optional: show a 'Pay Now' button in the checkout flow

        onAuthorize: function(data, actions) {

            // Optional: display a confirmation page here

            return actions.payment.execute().then(function() {
                // Show a success page to the buyer
            });
        }

    }, '#paypal-button');
</script>

Do a full-page redirect

Note: For a smooth buyer experience, PayPal recommends that rather than doing a full-page redirect, you show a success or failure message on the same page.

After a buyer authorizes or cancels a payment, you can redirect the buyer to your return or cancel URL. The page overlay and loading spinner remain active until the buyer is redirected to PayPal.

<script>
    paypal.Button.render({

        env: 'production', // Specify 'sandbox' for the test environment

        payment: function() {
            // Set up the payment here, when the buyer clicks on the button
        },

        onAuthorize: function(data, actions) {
            return actions.redirect();
        },

        onCancel: function(data, actions) {
            return actions.redirect();
        }

    }, '#paypal-button');
</script>

Redirect for an alternate funding source

If a buyer's funding source has insufficient funds, one of these errors might occur:

  • REST Payments API — INSTRUMENT_DECLINED
  • NVP/SOAP APIs — 10486

If the error occurs, restart the payment and enable the buyer to select a different payment option:

<script>
    paypal.Button.render({

        env: 'production', // Specify 'sandbox' for the test environment

        payment: function() {
            // Set up the payment here, when the buyer clicks on the button
        },

        onAuthorize: function(data, actions) {
            // Call your server to execute the payment

            if (error === 'INSTRUMENT_DECLINED') {
                actions.restart();
            }
        }

    }, '#paypal-button');
</script>

The buyer can then choose a different funding source.

Handle checkout flow errors

If an error prevents buyer checkout, define an error page using the onError call back:

<script>
    paypal.Button.render({

        env: 'production', // Specify 'sandbox' for the test environment

        payment: function() {
            // Set up the payment here, when the buyer clicks on the button
        },

        onAuthorize: function(data, actions) {
            // Execute the payment here, when the buyer approves the transaction
        },

        onError: function(err) {
            // Show an error page here, when an error occurs
        }

    }, '#paypal-button');
</script>

Use Express Checkout with acceptance marks

To use Express Checkout with acceptance marks, PayPal recommends that you render radio buttons on your page. These buttons enable the buyer to choose their payment method, which determines the user's checkout experience.

If the user selects PayPal, show the PayPal button. Otherwise, hide the PayPal button.

Try the full interactive demo

<!-- Render the radio fields and button containers -->

<label>
    <input type="radio" name="payment-option" value="paypal" checked>
    <img src="/demo/checkout/static/img/paypal-mark.jpg" alt="Pay with Paypal">
</label>

<label>
    <input type="radio" name="payment-option" value="card">
    <img src="/demo/checkout/static/img/card-mark.png"
         alt="Accepting Visa, Mastercard, Discover and American Express">
</label>

<div id="paypal-button-container"></div>
<div id="card-button-container" class="hidden"><button>Continue</button></div>

<script>

    // Helper functions

    function getElements(el) {
        return Array.prototype.slice.call(document.querySelectorAll(el));
    }

    function hideElement(el) {
        document.body.querySelector(el).style.display = 'none';
    }

    function showElement(el) {
        document.body.querySelector(el).style.display = 'block';
    }

    // Listen for changes to the radio fields

    getElements('input[name=payment-option]').forEach(function(el) {
        el.addEventListener('change', function(event) {

            // If PayPal is selected, show the PayPal button

            if (event.target.value === 'paypal') {
                hideElement('#card-button-container');
                showElement('#paypal-button-container');
            }

            // If Card is selected, show the standard continue button

            if (event.target.value === 'card') {
                showElement('#card-button-container');
                hideElement('#paypal-button-container');
            }
        });
    });

    // Hide non-PayPal button by default

    hideElement('#card-button-container');

    // Render the PayPal button

    paypal.Button.render({

        env: 'production', // Optional: specify 'sandbox' environment

        client: {
            sandbox:    'xxxxxxxxx',
            production: 'xxxxxxxxx'
        },

        payment: function(data, actions) {
            return actions.payment.create({
                payment: {
                    transactions: [
                        {
                            amount: { total: '1.00', currency: 'USD' }
                        }
                    ]
                }
            });
        },

        onAuthorize: function(data, actions) {
            return actions.payment.execute().then(function() {
                document.querySelector('#paypal-button-container')
                    .innerText = 'Payment Complete!';
            });
        }

    }, '#paypal-button-container');

</script>

Interactive demo

PayPal Express Checkout Integration Demo

Try an interactive demo of the different Express Checkout flows. You can edit the code in the demo to view different integrations or button styles and optional features.

Additional information