#Laëti
1 messages · Page 1 of 1 (latest)
Hi there. Just to confirm, are you following this guide (and this specific linked step)? https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements#fetch-updates
Yes I am
Hm ok. Can you share your code for this part so I can see what's happening?
Yes
We have a provider where we have this function to call an aws lambda to update the PaymentIntent :
`async ({
intentID,
amount,
application_fee_amount,
metadata = {},
countryCode
}) => {
const newIntentData = { ...this.state.intentData, ...metadata };
const userToken = await firebase.auth().currentUser.getIdToken();
const response = await invokeLambda('onlinePayment', {
firebaseToken: userToken,
actions: {
type: 'customer.updateIntentData',
paymentIntentId: intentID,
amount,
application_fee_amount,
metadata: newIntentData,
countryCode
}
});
if (!response.errorMessage) {
this.setState({
isPaymentIntentUpdating: false
});
}
}`
In the lambda, the method called is this one :
`const updateIntentData = async action => {
const stripe = getStripe();
const { paymentIntentId, amount, application_fee_amount, metadata, countryCode } = action;
const paymentMethodTypes = getPaymentMethodTypes({ countryCode, amount });
return await stripe.paymentIntents.update(paymentIntentId, {
amount,
application_fee_amount,
metadata: formatIntentMetadata(metadata),
payment_method_types: paymentMethodTypes
});
};`
The PaymentIntent is updated.
The CheckoutForm looks like this :
`const CheckoutForm = ({
isAccount,
isPaymentIntent,
isLoading,
setIsLoading,
setDisplayAddCard,
hasPaymentMethods,
tokenData,
getRedirectUrl,
getSpecificPaymentMethod,
stripe,
setError,
countryCode,
amount
}) => {
const elements = useElements();
const { t } = useTranslation();
useStyles(styles);
useEffect(() => {
!isLoading && elements?.fetchUpdates();
}, [isLoading]);
const handleSubmit = async event => {
event.preventDefault();
setIsLoading(true);
if (!stripe || !elements) {
setError('defaultError');
setIsLoading(false);
return;
}
let result, redirectResult;
if (isPaymentIntent && !isAccount) {
result = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: redirectResult.redirectUrl
},
redirect: 'if_required'
});
} else {
result = await stripe.confirmSetup({
elements,
redirect: 'if_required'
});
}
};
return (
<form onSubmit={handleSubmit}>
<PaymentElement />
{hasPaymentMethods && (
<Button
label={t('stripePayment.returnToPaymentMethods')}
type={'linked'}
onClick={() => {
setDisplayAddCard(false);
}}
/>
)}
<Button
isLoading={isLoading}
label={t(
isAccount ? 'bookAppointment.addCard' : 'stripePayment.submit',
{ price: formatPrice(amount) }
)}
/>
</form>
);
};`
Hm ok. Can you explain more about the 1 second timeout issue? What is the exact behavior you're seeing unless you do setTimeout of 1 second. And can you elaborate on what's not working when you update the paymentintent multiple times?
Sorry, I just remember when I read my message again that we rolled back the setTimeout solution so the useEffect should look like this (with the setTimeout) :
useEffect(() => { const timeout = setTimeout(() => {!isLoading && elements?.fetchUpdates()}, 1000) () => clearTimeout(timeout) }, [isLoading]);
The problem without the second is that the PaymentIntent is updated, but after this update we use elements.fetchUpdates to update the PaymentElement and it doesn't update.
Writing you made me think about one thing I didn't tell you : the CheckoutForm is in a component that unmount or stay mount depending on when we update the PaymentIntent.
The update of PaymentElement doesn't work after 2 things :
- first, we update the PaymentIntent when the PaymentElement
- after that, we update the PaymentIntent when the PaymentElement is unmount
👋 stepping in as codename_duchess needs to step away
So sounds like you are having an issue with fetchUpdates?
Can you explain what you mean exactly when you say "it doesn't update"?
What do you see happen?
When I have amount between 35 and 1500 €, I must have the Klarna tab, and for other amounts I must not have the Klarna tab.
In my case I have for example a 50€ payment (I see the Klarna tab) and I change it for a 15€ payment and the Klarna tab stays in the PaymentElement.
(and hello 😄 )
Yes
Is there somewhere I can reproduce the behavior here?
I don't know how
Okay no worries
Can you clarify something else... you said this does work if you use a setTimeout?
Can you tell me more about that?
It does work if I use a setTimeout of 1 second, it seems like elements takes time to get the PaymentIntent's update.
But when I double update elements.fetchUpdates doesn't work anymore even with the setTimeout
Yes it should take time for the fetchUpdates promise to resolve, that is true
I did notice you aren't awaiting fetchUpdates which is what I think is likely the cause here and where useEffect is making it a bit whacky
But also what is a "double update"?
Ok ! I will try with await
A double update is when I update the PaymentIntent twice
The await doesn't change anything :/
Well it won't change anything because it is in your useEffect I think
Let's do a test and can you pull fetchUpdates outside of useEffect?
Sorry I tested it wrong, it does change !!
Yes sorry for the delay I was testing all the cases hahaha
Thank you soooooo much !!!!!! You are a genius thank you thank you thank you