Nico
Nico

Reputation: 167

PayPal Buttons don't close (Duplicates after re-rendering)

I'm implementing the PayPal Smart Payment Buttons with React, and every time my component re-renders I receive a duplicate of the buttons (with the one on the bottom holding the correct transaction information). enter image description here

Clearly I need to close the buttons, if I try so I receive the error that window.paypal.close()is not a function.

I tried to follow this example: Paypal React shows extra buttons after changing amount

Here is my code, I'm using Redux for state management and I need to rerender the component if items in the shopping cart are removed (to update the item information of the transaction):

  useEffect(() => {

  if (window.myButton) {
    window.myButton.close()
  }
  
  window.myButton = window.paypal
      .Buttons({
        createOrder: (data, actions) => {
          return actions.order.create({
            purchase_units: [
              {
                description: "test transaction",
                amount: {
                  currency_code: "USD",
                  value: document.getElementById("totalAmount").innerHTML,
                  breakdown: {
                    item_total: {
                      currency_code: "USD",
                      value: document.getElementById("totalAmount").innerHTML
                    }
                  }

                }
                ,
                items: itemsInCart.map(item => {
                  console.log(item.value)
                  return {
                    name: item.name,
                    unit_amount: {
                      currency_code: "USD",
                      value: String(item.price)
                    },
                    quantity: "1"
                  }
                })
              }
            ]
          });
        },
        onApprove: async (data, actions) => {
          const order = await actions.order.capture();
        }
            .catch(function(error) {
              console.error("Error writing document: ", error);
            });
        },
        onError: err => {
          // setError(err);
          console.error(err);
        }
      })

      .render(paypalRef.current)
  }, [itemsInCart]);

Upvotes: 1

Views: 1632

Answers (1)

Preston PHX
Preston PHX

Reputation: 30377

    })

    .render(paypalRef.current)

The problem is you are setting myButton to the .render() promise result, not the Button itself.

You need to store a reference to the actual Button (before rendereing it), and only then .render() it -- so that later you can call .close() on the reference. Basically:

    let myButton = paypal.Buttons(
        ....
    });

    myButton.render(paypalRef.current)

    // and at some later point in time...
    myButton.close();

Upvotes: 5

Related Questions