Reputation: 166
Making an eCommerce app with React. This is a "handleSubmit" function that is returning an error every time I'm trying to checkout.
I have imported "db" and declared "paymentIntent". It is still coming up with this error in the browser.
const handleSubmit = async (event) => {
//do fancy stripe stuff
event.preventDefault()
setProcessing(true)
// const payload = await stripe
const payload = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement)
}
}).then(({ paymentIntent }) => {
//paymetnIntent = payment Confirmation
db
.collection('users')
.doc(user?.uid)
.collection('orders')
.doc(paymentIntent?.id)
.set({
basket: basket,
amount: paymentIntent.amount,
created: paymentIntent.created,
})
setSucceeded(true);
setError(null)
setProcessing(false)
dispatch({
type: 'EMPTY_BASKET'
})
history.replace('/orders')
})
}
Upvotes: 1
Views: 1237
Reputation: 11
import { db } from './firebase';
import { collection, addDoc } from "firebase/firestore";
const handleSubmit = async (event) => {
event.preventDefault();
setProcessing(true);
const payload = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement)
}
}).then( async ({ paymentIntent }) => {
try{
const docRef = await addDoc(collection(db, "users", user.uid, "orders"), {
basket: basket,
amount: paymentIntent.amount,
created: paymentIntent.created
});
console.log("Document written with orderID: ", docRef.id);
}catch(e){
console.log("Error adding document: ", e);
}
setSucceeded(true);
setError(null);
setProcessing(false);
dispatch({
type: 'EMPTY_BASKET'
})
navigate('/orders', { replace : true }); // don't come back to the payment page
})
}
Upvotes: 1
Reputation: 144
I faced the same problem some time ago and we have to notice that in the stipe documentation for confirmCardPayment, it says the returning result object is either the payment intent or the error.
So if the request is successful you'll receive a payment intent object for the response as,
{
"id": "xxx",
"amount": 30,
"created": 123213,
...
}
or if the request fails the response would be an error as,
{
"error": {
"code": "parameter_unknown",
"message": "Error message",
"payment_intent": {
"id": "xxx",
"amount": 30,
...
}
}
}
Note that in the success response you'll get the payment intent object itself so there will be no property as paymentIntent
in the response object and that's why you get it as undefined
. So in your code you'll have to do as,
.then(({ id, amount, created, error }) => {
if(error) {
// error handling
// dispatch error action
} else {
db.collection('users')
.doc(user?.uid)
.collection('orders')
.doc(id) // destructured id from paymentIntent object
.set({
basket: basket,
amount, // destructured amount from paymentIntent object
created, // destructured created from paymentIntent object
})
setSucceeded(true);
setError(null)
setProcessing(false)
dispatch({
type: 'EMPTY_BASKET'
})
history.replace('/orders')
}
})
Upvotes: 2
Reputation: 23189
You will need to check if there are any error
s. .confirmPayment()
returns a promise and when it's resolved a result object. It has two keys, paymentIntent
(the one you already use), and error
(the one you need to check):
.then(({ error, paymentIntent }) => {
// check if there is any error
if (error || !paymentIntent) {
// handle error, tell the user
// ...
// return to exit code
return;
}
db.collection('users')
.doc(user?.uid)
.collection('orders')
.doc(paymentIntent.id)
.set({
basket: basket,
amount: paymentIntent.amount,
created: paymentIntent.created,
});
setSucceeded(true);
setError(null);
setProcessing(false);
dispatch({
type: 'EMPTY_BASKET',
});
history.replace('/orders');
});
Upvotes: 2
Reputation: 484
Try to add console.log(paymentIntent) after line in the beginning of the then body and check the format it has. If it contains the amount property in paymentIntent then Add the checks before extracting the amount property as it might be taking sometime to load that. So,
.set({
basket: basket,
amount: paymentIntent?.amount, //Add check here
created: paymentIntent?.created, //Also check here
})
Upvotes: 1