NiceToMytyuk
NiceToMytyuk

Reputation: 4277

How to re-render PayPal Smart Buttons with different values?

I'm using PayPal Smart button on my web site, and after each payment is made the user is able to make another new payment with PayPal smart button. The problem is that once I've created my PayPal button I'm unable to set the new createOrder in it with new orderID.

So in my website I have the following function which init the PayPal button if there is yet a pending order or it's called when a new order is made and I get a new orderID.

function initPayPal(orderID, publicKey) {
    var paymentID = $("#paypal-button-container").data("payment-id")
    var PAYPAL_SCRIPT =
        "https://www.paypal.com/sdk/js?client-id=" + publicKey + "&currency=EUR&intent=capture&commit=false&vault=true";
    var script = document.createElement("script");
    script.setAttribute("src", PAYPAL_SCRIPT);
    script.onload = function () {
        paypal
            .Buttons({
                style: {
                    shape: "rect",
                    color: "gold",
                    layout: "horizontal",
                    label: "paypal",
                    tagline: false,
                    height: 52,
                },
                createOrder: async function () {
                    $(".body-payments").hide();
                    $(".loader-payments").show();
                    const res = await fetch(
                        "/api/payment/paypal/" + paymentID + "/" + orderID,
                        {
                            method: "post",
                            headers: {
                                "content-type": "application/json",
                            },
                            credentials: "include",
                        }
                    );
                    const data = await res.json();
                    return data.id;
                },
                onApprove: async function (data) {
                    const res = await fetch(
                        "/api/payment/paypal/capture/" + paymentID + "/" + data.orderID,
                        {
                            method: "post",
                            headers: {
                                "content-type": "application/json",
                            },
                            credentials: "include",
                        }
                    );
                    if (localStorage.STBOrder) {
                        localStorage.removeItem("STBOrder");
                    }

                    $("#modalPayments").modal("hide");
                    $("#modalSuccess").modal("show");
                    $(".body-payments").show();
                    $(".loader-payments").hide();

                },
                onCancel: function (data) {
                    $(".body-payments").show();
                    $(".loader-payments").hide();
                },
            })
            .render("#paypal-button-container");
    };
    document.head.appendChild(script);
}

Client id is set dynamically as each user on its own page will get the payment on its own account. The issue here is that the button is initiated the first time all works fine, but if I dismiss the order and I call this function again it will create another button instead of setting new values to existing (already rendered) one.

Upvotes: 1

Views: 2491

Answers (1)

Preston PHX
Preston PHX

Reputation: 30379

There should be no need to init the button more than once.

Initialize the button one time (on page load).

Then, inside createOrder, ensure paymentID and orderID reference non-local variables or are replaced with function calls that will return the correct value at the time you want them to, e.g. some kind of getOrderID() of yours, and $("#paypal-button-container").data("payment-id") , in place of your existing local variables


In the unlikely event that you really did need to render the buttons more than once, you could save a reference to myButtons = paypal.Buttons({..}) before calling .render() --- and then, later myButtons.close() before saving a new reference to and rendering a new buttons object. But again, there should be no reason to do that here.

Upvotes: 2

Related Questions