My website has products in several currencies up for sale on the same page, so a person can click the product that sold in EUR and pay in euros, or they can click the product that is sold in USD and pay in usd and so on...
The problem is that once you initialise the new PayPal SDK, you cannot change the currency that it accepts without:
- destroying the element
- changing the link to the SDK, so that it would accept a different currency
- manually injecting it into the page
- reinitialising it
As you can probably understand it is not very fast, stable or safe at the same time. Am I missing something? I know that you could send the currency as a parameter in the old Express Checkout version.
The PayPal documentation is infuriating, it is missing a lot of information and doesn't have a big munity around it, so I could not find the answer to my question anywhere.
I have tried sending the currency in the payment parameters, but if it is different from the initialised currency, it throws a currency mismatch error once you try to confirm the payment.
Right now I am manually reinjecting and reinitialising the paypal SDK with the correct currency if the user clicks on the option of paying with PayPal, but it is slow and requires hardcoding sleep (although it is probably due to my lack of knowledge, there are probably better ways).
Here's the pseudocode of my current setup that is not acceptable:
initialisePaypalSDK(currency) {
destroy old initialisation
change link to paypal with new currency
inject new link to page
initialise the new sdk
sleep until the paypal variable is defined
showPayPalButton()
}
I expect that there is an easier and a safer way of changing the currency than this. Thanks.
My website has products in several currencies up for sale on the same page, so a person can click the product that sold in EUR and pay in euros, or they can click the product that is sold in USD and pay in usd and so on...
The problem is that once you initialise the new PayPal SDK, you cannot change the currency that it accepts without:
- destroying the element
- changing the link to the SDK, so that it would accept a different currency
- manually injecting it into the page
- reinitialising it
As you can probably understand it is not very fast, stable or safe at the same time. Am I missing something? I know that you could send the currency as a parameter in the old Express Checkout version.
The PayPal documentation is infuriating, it is missing a lot of information and doesn't have a big munity around it, so I could not find the answer to my question anywhere.
I have tried sending the currency in the payment parameters, but if it is different from the initialised currency, it throws a currency mismatch error once you try to confirm the payment.
Right now I am manually reinjecting and reinitialising the paypal SDK with the correct currency if the user clicks on the option of paying with PayPal, but it is slow and requires hardcoding sleep (although it is probably due to my lack of knowledge, there are probably better ways).
Here's the pseudocode of my current setup that is not acceptable:
initialisePaypalSDK(currency) {
destroy old initialisation
change link to paypal with new currency
inject new link to page
initialise the new sdk
sleep until the paypal variable is defined
showPayPalButton()
}
I expect that there is an easier and a safer way of changing the currency than this. Thanks.
Share Improve this question asked May 15, 2019 at 6:22 Артём ЮрковАртём Юрков 1211 silver badge7 bronze badges 6- can you please provide the link to visualize the changes? – Senthil Commented May 15, 2019 at 6:37
-
Sure, so for example if I use this link to initialise the SDK:
https://www.paypal./sdk/js?client-id=${credentials}¤cy=USD
, it will only accept payments in USD, I have to reinject and reinitialise it with¤cy=EUR
for it to work with EUR. If I don't set the parameter, it defaults to USD, also you cannot send an array as the parameter. – Артём Юрков Commented May 15, 2019 at 6:43 - 2 @terales I did not, it is very unfortunate but we have to make do with suboptimal solutions like I described in the original post. I wish PayPal cared more about developers :( – Артём Юрков Commented Jun 26, 2019 at 13:31
- 1 Thanks, we've ended up in reloading a page (even if it's a SPA) after currency change — this makes it much simpler from the code perspective and has almost no hurt in UX – terales Commented Jun 26, 2019 at 18:35
- 3 I've submitted an issue: github./paypal/paypal-checkout-ponents/issues/1180 – jaynetics Commented Aug 9, 2019 at 9:07
3 Answers
Reset to default 1You can use a backend to solve this issue. First, define createOrder function like this:
const createOrder = async (data, actions) => {
return await axios.get('/yourbackend/api/get_order_id')
}
const onApprove = (data, actions) => {
// ... code to handle the payment status
}
paypal.Buttons({createOrder, onApprove}).render('#paypal-button-container')
Then just implement REST Api for order creation (/v2/checkout/orders) on your backend. Then return id of the created payment.
For those using React, this is now possible with the new library @paypal/react-paypal-js
. From the README:
The usePayPalScriptReducer hook can be used to reload the JS SDK script when parameters like currency change. It provides the action resetOptions for reloading with new parameters. For example, here's how you can use it to change currency.
// get the state for the sdk script and the dispatch method
const [{ options }, dispatch] = usePayPalScriptReducer();
const [currency, setCurrency] = useState(options.currency);
function onCurrencyChange({ target: { value } }) {
setCurrency(value);
dispatch({
type: "resetOptions",
value: {
...scriptProviderOptions,
currency: value,
},
});
}
return (
<>
<select value={currency} onChange={onCurrencyChange}>
<option value="USD">United States dollar</option>
<option value="EUR">Euro</option>
</select>
<PayPalButtons />
</>
);
You can add the script once the currency has been selected.
let myScript = document.createElement("script");
myScript.setAttribute(
"src",
"https://www.paypal./sdk/js?client-id="your cliend id"&ponents=buttons¤cy=" + currencyVariable
);
let head = document.head;
head.insertBefore(myScript, head.firstElementChild);
myScript.addEventListener("load", scriptLoaded, false);
function scriptLoaded() {
console.log("Script is ready to rock and roll!");
paypal
.Buttons({
style: {
layout: "vertical",
color: "blue",
shape: "rect",
label: "paypal",
},
createOrder: function (data, actions) {
// Set up the transaction
return actions.order.create({
purchase_units: [
{
amount: {
value: traspasoCantidad,
},
payee: {
},
description: "",
},
],
application_context: {
},
});
},
onApprove: function (data, actions) {
return actions.order.capture().then(function (details) {
/* window.location.href = "approve.html"; */
});
},
onError: function (err) {
myApp.alert("Ha ocurrido un error al hacer el traspaso", "ERROR");
},
})
.render("#paypal-button-container");
}