'Fill PayPal order script using onOpen() function

I'm trying to implement the PayPal SDK on my site, and thought this should work:

<body onload="writeOrderCode()">

The JS file with this function was loaded in the <head> section. The function writes the code to a var, which is then inserted as $("paypalscript").innerHTML. The <script id="paypalscript"> tag is at the place in the HTML where the button should be drawn. Here's an example of what I had in mind:

<head>
  <-- Load PayPal SDK -->
    <script src="https://www.paypal.com/sdk/js?client-id=[CLIENT_ID]"></script>
    <-- Load JS file with the function -->
      <script src="/myJSfile.js"></script>
</head>

<body onload="writeOrderCode(5)">
  <div id="paypal-button-container">
    <script id="paybtn">
      <-- JS function should write order code here -->
    </script>
  </div>
</body>

function writeOrderCode(x) {
  var ps = '    paypal.Buttons({\n';
    ps += ' style: {\n';
    ps += '     layout:  "vertical",\n';
    // Calc choices about values or which properties to include //
    ps += '     color:   ' + (x > 2 ? "gold" : "black") + ',\n';
    ps += '     shape:   "pill",\n';
    ps += '     label:   "pay"\n';
    ps += '   },\n';
    ps += '}).render("#paypal-button-container")\n';
  // insert into script tag in HTML //
  document.getElementById("paybtn").innerHTML = ps;
}

The problem is the entire page gets drawn before the new code is inserted, so it has no effect, except that it triggers an error:

Failed to load resource: A server with the specified hostname could not be found.

It references a mile-long URL at "https://tracking.qa.paypal.com". Obviously this is coming from the PayPal file that was also loaded in the <head> section, but I don't understand why this error happens when I write the code from JS, but not if the same code is in the script tag to start with. Is PayPal trying to write code to the same tag?

I suspect this might be done with a callback, to make sure the code was written before the rest of the page was rendered, but I'm afraid I'm sadly incompetent and confused by callbacks. Any help on how this might be done would be greatly appreciated.



Solution 1:[1]

You don't show us your function, or what it wrote to your page DOM, so it's hard to offer any specific guidance.

But here is a working example:

function loadAsync(url, callback) {
  var s = document.createElement('script');
  s.setAttribute('src', url); s.onload = callback;
  document.head.insertBefore(s, document.head.firstElementChild);
}

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) {
            // Show a success message to the buyer
            alert('Transaction completed by ' + details.payer.name.given_name);
        });
    }

  }).render('body');
});

If you want a full package dedicated to this loading, you can use paypal-js.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1