#TheKents
1 messages ยท Page 1 of 1 (latest)
Hi! Let me help you with this.
hey, can i paste my current checkoutForm code?
Sure
if (!stripe) {
return;
}
const clientSecret = new URLSearchParams(window.location.search).get(
'payment_intent_client_secret'
);
if (!clientSecret) {
return;
}
stripe.retrievePaymentIntent(clientSecret).then(({ paymentIntent }) => {
if (paymentIntent) {
switch (paymentIntent.status) {
case 'succeeded':
setMessage('Payment succeeded!');
break;
case 'processing':
setMessage('Your payment is processing.');
break;
case 'requires_payment_method':
setMessage('Your payment was not successful, please try again.');
break;
default:
setMessage('Something went wrong.');
break;
}
}
});
}, [stripe]);
const handleSubmit = async (e: any) => {
e.preventDefault();
if (!stripe || !elements) {
// Stripe.js has not yet loaded.
// Make sure to disable form submission until Stripe.js has loaded.
return;
}
setIsLoading(true);
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
// Make sure to change this to your payment completion page
return_url: 'http://localhost:3000/order',
},
});```
so this is the useEffect, like in Stripe Docs
In return im using <LinkAuthenticationElement // onBlur={handleBlur} id='link-authentication-element' onChange={(e) => setEmail(e.value.email)} />
i dont understand where im supposed to get client secret to fetch payment intent id
or any other way to get payment intent id to update it
this is my paymentIntent create function
.region("europe-west1").https.onRequest(async (request, response) => {
cor(request, response, async () => {
const {items} = request.body;
functions.logger.log("items", items);
functions.logger.log("req body", request.body);
const paymentIntent = await stripe.paymentIntents.create({
amount: calculateOrderAmount(items),
currency: "eur",
automatic_payment_methods: {
enabled: true,
},
metadata: generateMetadata(items),
});
response.send({
clientSecret: paymentIntent.client_secret,
});
});
});```
The useEffect(() => { looks like it's from a page where you display the success message, and not the checkout page.
What docs are you following?
just a sec
CheckoutForm.jsx
this is what im using in the page where idisplay the success message
then also related to the checkout is this
i guess this in the docs is like app.jsx
You do it in App.jsx: https://stripe.com/docs/payments/quickstart#fetch-payment-intent
but then i dont have access to LinkAuthenticationElement email anymore
Not sure I'm following. What do you mean by "i dont have access to LinkAuthenticationElement email"? Where do you want to use it?
I want to update PaymentIntent once user has written their email, User writes their email to CheckoutForm.tsx, into LinkAuthenticationElement, the state of their email is kept in CheckoutForms const [email, setEmail] = useState('');, as you said that i should do it in App.jsx, for me its payment.tsx. And in there i cannot access the email user input to CheckoutForms LinkAuthenticationElement
You can store the email state in App.jsx as well
how do i store/fetch it there
Using React Component properties, export default function CheckoutForm({ email, setEmail }) {
And then <CheckoutForm email={email} setEmail={setEmail} />
and that should provide it back to payment.tsx?
Sorry, what's payment.tsx?
"as you said that i should do it in App.jsx, for me its payment.tsx"
App.jsx in docs is for me payment.tsx
How much are you familiar with React?
Main language, but the email is in useState in CheckoutForm, even if it is updated in CheckoutForm it doesnt provide updated values to parent
<CheckoutForm email={email} setEmail={setEmail} /> this is just inheriting email and setemail from parent
but to my knowledge they dont do this <-->, only this ->
If you use setEmail it sets the value in the parent component.
you are right
forgive me
// Create PaymentIntent as soon as the page loads
fetch('https://europe-west1-personal-jewelry.cloudfunctions.net/payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({items : [items]}),
})
.then((res) => res.json())
.then((data) => setClientSecret(data.clientSecret));
}, []);```
so in this is should call method to update receipt email?
inside App.jsx/payment.tsx
Hello, vanya had to step out but I can help. Updating the email there makes sense to me, have you tried it out?
hey, no i haven't yet, i had trouble with getting the correct paymentIntent and email into same function
should i instead update email onBlur? meaning when user has completed typing instead of when setEmail updates, that would result in many irrelevant calls, no?
Ah I see, apologies, I misread your code before. Yes you would only want to grab the payment intent once so yes it would be a good idea to avoid that call every time someone types a letter
could you advise me how would that work?
should there be a third parameter <CheckoutForm email={email} setEmail={setEmail} func={onBlurFunc} />
Unfortunately I am less familiar with the structure of react problems than vanya is. This is getting more out of the realm of this server's expertise which is calls directly to the Stripe API.
Yep sorry I can't help that far. There should be a decent amount of react and stack overflow docs for passing data from child to parent components like this though, those may help clarify your options here
it seems that theres another problem
my function works and calls this when user has clicked away
and i get the correct email from response
but when i test to pay the order the receipt_email is still null
i'll get some screenshots of logs
Can you make that update call again and print out the request ID from your update call? https://stripe.com/docs/api/request_ids
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
yeah, just a moment
"request id req_ZOBDlJC9KPPj6l"
also in response body there is receipt_email: "asdd@gmail.com"
oh
i get it
for some reason it created 2 paymentintents
Oh two separate intents?
it updates receipt email for the one that is never completed
and the one that succeeds is without email
so do i have to create only one paymentIntent somehow?
Yes that would be the preferred way to do this. When are each of these being created? You can probably remove that first creation if that intent isn't getting used at all
They are created almost at the same time because of the useEffect
Is that being called twice here or is some other piece of your code that is creating this intent?
it is created twice there
@opaque dune any solution for this?