#wilem121982013
1 messages · Page 1 of 1 (latest)
Hello! We'll be with you shortly. 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.
- wilem121982013, 11 minutes ago, 4 messages
My apologies, let's start a new conversation here though. Here is the description of the issue from the last thread:
Hi i currently have an issue with my stripe form on my web application, i use PaymentElement, Elements, useStripe, useElements from react-stripe-js and i don't know why but when i focus then blur an input it refresh the elements and then it works fine do you have any idea why ?
here a video of what happens
it reload when i focus and blur my input only once every refresh and then work fine
here the code of my form
import { PaymentElement, Elements, useStripe, useElements } from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { ArrowRightIcon } from "@/assets/icons";
import { Button } from "@/components";
import { useUserSession } from "@/hooks/useUserSession";
import { STRIPE_PUBLIC_KEY } from "@/utils/env";
const CheckoutForm = () => {
const stripe = useStripe();
const elements = useElements();
const { user } = useUserSession();
const { t } = useTranslation();
const [errorMessage, setErrorMessage] = useState("");
const handleSubmit = async () => {
if (elements == null || stripe == null) {
return;
}
const { error: submitError } = await elements.submit();
if (submitError) {
setErrorMessage(submitError.message ?? "");
return;
}
const { error } = await stripe.confirmSetup({
elements,
clientSecret: client_secret,
confirmParams: {
return_url: return_url,
},
});
if (error) {
setErrorMessage(error.message ?? "");
} else {
// Your customer will be redirected to your `return_url`. For some payment
// methods like iDEAL, your customer will be redirected to an intermediate
// site first to authorize the payment, then redirected to the `return_url`.
}
};
if (elements == null || stripe == null) {
return;
}
return (
<form
onSubmit={(event) => {
event.preventDefault();
handleSubmit().catch(console.error);
}}
>
<PaymentElement onFocus={() => console.log("Input focus")} onBlur={() => console.log("input blurred")} />
<div className="items-center justify-start flex-col p-4 pb-6 pt-4">
<Button
text={t("navigation.validate")}
suffixIcon={<ArrowRightIcon />}
disabled={!stripe || !elements}
type="submit"
/>
</div>
{errorMessage && <div>{errorMessage}</div>}
</form>
);
};
const StripeForm = () => {
const { user } = useUserSession();
const stripePromise = loadStripe(STRIPE_PUBLIC_KEY);
const options = {
currency: "eur",
clientSecret: user?.checkout?.payment?.clientSecret ?? "",
};
return (
<Elements stripe={stripePromise} options={options}>
<CheckoutForm />
</Elements>
);
};
export default StripeForm;
thanks a lot
Hmm okay so yeah seems like there is a re-render happening
What do you see in your console?
Are you seeing the logs before the re-render?
here what i got before focus my input
What happens if you hard code a clientSecret here?
That makes it look like the issue is your Elements provider is getting updated which forces a re-render
Okay in that case I'd recommend starting to remove specific pieces from your code to narrow down exactly what is causing the re-render.
what can i remove ? i feel like everytime i remove something it breaks everything i cant try piece by piece
if you have any idea
Well to start with if you remove the onBlur={() => console.log("input blurred") then does it not re-render?
still doing it
Does anything wrap StripeForm?
{PaymentId && <StripeForm />}
its from the object user that is changing in a useEffect
useEffect(() => {
const validateCheckout = async () => {
const intent = await putCheckout(user?.checkout?.uuid);
setUser({
...user,
checkout: {
...user.checkout,
payment: intent,
},
});
};
if (user?.checkout?.uuid && !user?.checkout?.payment?.id) {
validateCheckout().catch(console.error);
}
}, [user]);
Yep so that is likely the culprit here
what can i use to i need that id to display the form
or i got a white screen
react-dom.development.js:12056 Uncaught IntegrationError: Invalid value for elements(): clientSecret should be a client secret of the form ${id}secret${secret}. You specified: .
Sounds like you want the deferred intent flow here: https://stripe.com/docs/payments/accept-a-payment-deferred
i dont really understand what it does sorry