javascriptpaypalscript-tag

Paypal not defined when customizing own src for script tag


In my project I use the PayPal implementation (https://developer.paypal.com/docs/checkout?keywords=checkout) to make payments possible.

In the first instance I ask the client which payment method he prefers and on that basis I generate the appropriate payment button (paypal, credit card or bancontact). When I use the code below I get the following error:

Uncaught ReferenceError: paypal is not defined.

As you can see below, I add the correct script tag to my HTML code before I the PayPal code is triggered, so this shouldn't be a problem.

HTML Code (paypal-div)

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

JavaScript Code

let radios = document.querySelectorAll('.pm');
const script = document.createElement("script");
let src = '';

radios.forEach(radio => {
    if (radio.checked) {
        supper_data.payment_method = (radio.value).charAt(0).toUpperCase() + (radio.value).slice(1);   

        if((radio.value).charAt(0).toUpperCase() + (radio.value).slice(1) === "Bancontact") { 
            src = 'https://www.paypal.com/sdk/js?client-id=ASuRqSAZYj9/*...*/-FEXCHWao5SA7-SADYX6werETXouaJDIBP1UeSAJpJbMbrtCOy59C7C-C&currency=EUR&disable-funding=card,sofort,credit';
        } else if (supper_data.payment_method === "Visa") {
            src = 'https://www.paypal.com/sdk/js?client-id=ASuRqSAZYj9/*...*/-FEXCHWao5SA7-SADYX6werETXouaJDIBP1UeSAJpJbMbrtCOy59C7C-C&currency=EUR&disable-funding=bancontact,sofort,credit';
        } else {
            src = 'https://www.paypal.com/sdk/js?client-id=ASuRqSAZYj9/*...*/-FEXCHWao5SA7-SADYX6werETXouaJDIBP1UeSAJpJbMbrtCOy59C7C-C&currency=EUR&disable-funding=bancontact,sofort,card';
        }

    }
});

script.type = "text/javascript";
script.src = src;
document.head.append(script);

document.querySelector('#paypal-button-container').style.display = "block";

paypal.Buttons({
    style: {
        shape: 'pill',
        color: 'blue'
    },
    createOrder: (data, actions) => {
        return actions.order.create({
            purchase_units: [{
                amount: {
                    currency_code: "EUR",
                    value: price
                }
            }]
        });
    },
    onApprove: (data, actions) => {
        return actions.order.capture().then((details) => {
            $.ajax({
                url: "./includes/delete-cart.php",
                method: "GET",
                success: function (data) {
                    Swal.fire({
                        icon: 'success',
                        title: 'Betaling Afgerond',
                        text: 'Uw bestelling is ontvangen.'
                    }).then(() => {
                        window.location.reload();
                    })
                    console.log(details);
                }
            });
        })
    }
}).render('#paypal-button-container');

Solution

  • Loading a script that way is asynchronous and takes time, so you should use an onload event callback.

    //Helper function
    
    function loadAsync(url, callback) {
      var s = document.createElement('script');
      s.setAttribute('src', url); s.onload = callback;
      document.head.insertBefore(s, document.head.firstElementChild);
    }
    
    // Usage -- callback is inlined here, but could be a named function
    
    loadAsync('https://www.paypal.com/sdk/js?client-id=test&currency=USD', function() {
      paypal.Buttons({
    
        // Set up the transaction
        createOrder: function(data, actions) {
            return actions.order.create({
                purchase_units: [{
                    amount: {
                        value: '0.01'
                    }
                }]
            });
        },
    
        // Finalize the transaction
        onApprove: function(data, actions) {
            return actions.order.capture().then(function(details) {
               //...
            });
        }
    
      }).render('#paypal-button-container');
    });
    

    There's also a node package to do much the same, @paypal/paypal-js