#day0_code
1 messages ยท Page 1 of 1 (latest)
๐ Welcome to your new thread!
โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
๐ This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1463190704791486620
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- day0_code, 2 hours ago, 39 messages
hi there, can you say more about how you're loading the customer's shipping address? does updating the elements afterwards not work for your use case? https://docs.stripe.com/js/elements_object/update#elements_update-options-currency
We load the customer's shipping address when the ApplePay dialog opens
So we detect the address in the onShippingAddressChange function, which prompts our app to update load the shipping methods for that country and in turn if the address is tied to a currency that wasnt was set initially, we try to update the currency which obviously isn't possible
So wondering, the best way to handle this sort of scenario where we update the currency after opening the ApplePay/GooglePay dialog ]
I'm not sure there's a way to do this, one sec while I investigate
Thank you
I don't think this is possible, you would want to collect the customer's shipping address first before instantiating the Express Checkout Element with the proper currency
How would we detect the customer's shipping address without the dialog being open?
you would collect their shipping address in a separate form beforehand
That would defeat the purpose of express checkout. What would happen if they then change the address while the dialog is open to a different country for example
one moment while I reach out to my colleagues
Thank you!
Another question I have, our Google Pay doesn't work on safari. Says payment method not supported and I'm pretty sure it should prompt a log in
ok my colleagues agree there's unfortunately no real way to do this, updating the currency on the Elements session wouldn't affect the dialog since it's already open at the time the user is changing the address
you likely need to set paymentMethods.googlePay to always https://docs.stripe.com/elements/express-checkout-element#:~:text=Google Pay on Safari-based browsers
Ah I see, is there a way to close the dialog when we detect the currency needs to change? This way we can show some of prompt and retrigger the dialog
It is set to always
<ExpressCheckoutElement
onConfirm={async (event) => this.handlePayment(event)}
options={{
emailRequired: true,
phoneNumberRequired: true,
shippingAddressRequired: true,
// shippingRates: [],
paymentMethods: {
link: "never",
applePay: "always",
googlePay: "always",
paypal: "never",
// @ts-expect-error klarna not in typescript def
klarna: "never",
},
paymentMethodTypes: ['card'],
paymentMethodOrder: ['apple_pay', 'google_pay'],
layout: {maxColumns: 2, maxRows: 2},
}}
onShippingAddressChange={(event) => this.handleShippingAddressChange(event)}
onShippingRateChange={(event) => this.handleShippingRateChange(event)}
onClick={event => this.handleOnClick(event)}
/>
I'm not seeing a way to do this programmatically. if you call elements.update() with the new currency, what happens?
do you have a public page I can access with your express checkout element so I can test google pay not appearing in Safari?
The dialog is tuck spinning and you get the can't update currency error
Not at the moment
if you go to this page in Safari, do you see Google Pay https://docs.stripe.com/testing/wallets?ui=express-checkout-element
Hi there. I'll be taking over for denton here
Let me get caught up. We have a lot of people asking questions right now so it may be a few minutes
No worries...the main thing I would like answered is around currency changing. The other issue, I can figure that one out myself
sure thing.
The dialog is tuck spinning and you get the can't update currency error
Can you give me the exact error you get? And just to make sure I understand correctly you're trying to change the currency in response to shipping address change, right?
Yes, exactly
ok - can you copy/paste the exact error for me, please?
"IntegrationError: You cannot update the currency if the payment interface is already open."
that certainly makes it seem like we don't support doing this. Let me test this
there might be a workaround
Thank you!
I think probably the best solution would be using the Checkout Sessions x Elements integration so you can leverage adaptive pricing:
I think this is all before the dialog is shown but our situation is when the express checkout dialog has been opened
The only other option I think is trying to use Elements.destroy() to unmount the ECE and then update the currency and remount the element
(I'm trying that now)
If I may, here is how we are set up currently. We can detect the currency changing just before, but wouldn't the destroy ruin the other payment methods?
I'm not sure what you mean by "ruin" - the Google Pay / Apple Pay interface will disappear visually and the Express Checkout Element will be in the original state and they'll have to start again. It does work - I was able to do it just now, but that is the only way to change the currency after someone has clicked the apple pay/google pay button
Another approach you could use is to use Confirmation Tokens instead and then decide what the currency is after you get shipping info
Sorry, just to be clear what am I calling destroy on in our use case?
I will look into this to see if we could potentially use this
So here's what I did to achieve the effect.
In the shipping address change handler, I added logic to detect if the selected shipping address was not US. If it is, I call elements.destroy() on the Express Checkout Element, which unmounts it, and then create a new ECE and update currency to, for example, CAD
My implementation seems to be timing out
So my ExpressCheckout component returns this
<ExpressCheckoutElement
onConfirm={async (event) => this.handlePayment(event)}
options={{
emailRequired: true,
phoneNumberRequired: true,
shippingAddressRequired: true,
// shippingRates: [],
paymentMethods: {
link: "never",
applePay: "always",
googlePay: "always",
paypal: "never",
// @ts-expect-error klarna not in typescript def
klarna: "never",
},
paymentMethodTypes: ['card'],
paymentMethodOrder: ['apple_pay', 'google_pay'],
layout: {maxColumns: 2, maxRows: 2},
}}
onShippingAddressChange={(event) => this.handleShippingAddressChange(event)}
onShippingRateChange={(event) => this.handleShippingRateChange(event)}
onClick={event => this.handleOnClick(event)}
/>
And here is my handleShippingAddressChange method, if the if statment before getting the shipping mehtods is the addition to what we currently have
async handleShippingAddressChange(event: StripeExpressCheckoutElementShippingAddressChangeEvent){
const shippingAddress = this.parseShippingAddress(event.name, event.address)
if(shippingAddress?.country?.iso2 !== this.props.order?.shipping_address?.country?.iso2){
this.props.elements.destroy()
}
const methods = await this.props.getShippingMethods(shippingAddress)
this.setState({
shippingAddress,
shippingMethods: methods,
})
const shippingMethods = methods.map((method: any) => {
return {
id: method.code,
displayName: method.title,
description: method.description,
amount: parseFloat(method.estimatedCost.amount) * 100
}
})
if(shippingMethods.length == 0){
event.reject()
return
}
const lineItems = this.updateElementDetails(
this.props.checkout,
shippingMethods[0].amount,
this.state.paymentMethod
)
event.resolve({
shippingRates: shippingMethods,
lineItems
});
}
replacing this.props.elements.destroy() with event.reject(); return; doesnt seem to work either
what's the value of this.props.elements?
I think you need something closer to this:
const eceElement = elements?.getElement("expressCheckout");
if (eceElement) {
eceElement.destroy();
}
it should be the stripe elements
You're not destroying the elements provider, you're destroying the ECE
what dialogue? Google Pay/Apple Pay?
well darn. I tested using Google Pay and it worked fine - let me see if I get the same behavior
Yeah, Apple Pay's dialogue is persistent I suppose
That is kind of back to square one. I think your only options here are either collecting desired currency beforehand or using Confirmation Tokens
Thank you, I will need to look into the Confirmation Tokens