All I’m trying to do here is to be able fetch paypal_api_key from backend api something like:
app.get("/api/keys/paypal", (req, res) => {
res.send(process.env.PAYPAL_CLIENT_ID || "sb");
});
frontend side:
const loadPaypalScript = async () => {
const { data: clientId } = await axios.get("/api/keys/paypal", {
headers: { authorization: `Bearer ${userInfo.token}` },
});
paypalDispatch({
type: "resetOptions",
value: {
"client-id": clientId,
currency: "GBP",
},
});
paypalDispatch({ type: "setLoadingStatus", value: "pending" });
};
loadPaypalScript();
ERROR:
Uncaught Error: Attempted to load sdk version 5.0.343 on page, but window.paypal at version undefined already loaded.
To load this sdk alongside the existing version, please specify a different namespace in the script tag, e.g. <script src="https://www.paypal.com/sdk/js?client-id=CLIENT_ID" data-namespace="paypal_sdk"></script>, then use the paypal_sdk namespace in place of paypal in your code.
at VM827 js:2
at Module.<anonymous> (VM827 js:2)
at t (VM827 js:2)
at VM827 js:2
at VM827 js:2
I’ve tried this
<script src="https://www.paypal.com/sdk/js?client-id=***"></script>
it works but I’m not interested in passing my api key in plain sight like that
2
Answers
The Client ID is and must be public information, it’s required for the script to load. Fetching it asynchronously after page load and using it to load the script dynamically does not in any way hide it; it will be in "plain sight" the moment the browser makes its request and also the moment the resource is loaded. So if that’s the reason you’re loading the script asynchronously, it does not make any sense; you are accomplishing nothing and should just do what works, ether putting the script tag in your page as HTML or using the official react-paypal-js.
In any case, the cause of your error is you are doing something that loads the SDK more than once. You need to ensure it’s only loaded once. (for the rare use case that requires multiple SDKs concurrently,
data-namespace
is available but this is not your case)For me, it was happening because I had an HTML element with
id="paypal"
on the page (due to an SVG icons sprite).Renaming the element to something else solved the problem.
Reference: https://www.paypal-community.com/t5/Merchant-Products-and-Services/Smart-Payment-Buttons-Problem/m-p/1892006