问题
My Payment.js :-
import React, { useState, useEffect } from 'react'
import "./Payment.css"
import { useStateValue } from './StateProvider'
import CheckoutProduct from './CheckoutProduct';
import { Link, useHistory } from 'react-router-dom';
import { CardElement,useElements, useStripe } from '@stripe/react-stripe-js';
import CurrencyFormat from 'react-currency-format';
import { getBasketTotal } from './reducer';
import axios from "./axios";
import {db} from "./firebase";
function Payment() {
const [{basket, user}, dispatch] = useStateValue();
const history = useHistory();
const stripe = useStripe();
const elements = useElements();
const [succeeded, setSucceeded]=useState(false);
const [processing,setProcessing] = useState("");
const [error, setError] = useState(null);
const [disabled, setDisabled] =useState(true);
const [clientSecret, setClientSecret] =useState(true);
useEffect(() =>{
//generate the special stripe secret which allows us to charge the customer
const getClientSecret = async () => {
const response = await axios({
method: 'Post',
// Stripe expects the total in a currencies submits
url: `/payments/create?total=${getBasketTotal(basket) * 100}`
});
setClientSecret(response.data.clientSecret)
}
getClientSecret();
},[basket])
console.log("THE SCRET KEY IS >>>>>", clientSecret)
console.log("Hey! I am the user: My props", user);
const handleSubmit = async (event) =>{
// do all the fancy stripe stuff
event.preventDefault();
setProcessing(true);
const payload = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement)
}
}).then(({paymentIntent})=>{
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')
})
}
const handleChange = event =>{
//handle for changes in tht CardElement
// and display any error as the customer types their card details
setDisabled(event.empty);
setError(event.error ? event.error.message : "")
}
return (
<div className="payment">
<div className="payment__container">
<h1>
Checkout Products(
{<Link to="/checkout">{basket?.length} items
</Link>})
</h1>
{/* payment section-delivery address */}
<div className="payment__section">
<div className="payment__title">
<h3>Delivery Address</h3>
</div>
<div className="payment__address" >
<p>{user?.email}</p>
<p>123 React Lane</p>
<p>Los Angeles, CA</p>
</div>
</div>
{/* payment section-delivery address */}
<div className="payment__section">
<div className="payment__title">
<h3>Review items and delivery</h3>
</div>
<div className="payment__items">
{basket.map( item =>
<CheckoutProduct
id={item.id}
title={item.title}
image={item.image}
price={item.price}
rating={item.rating} />
)}
</div>
</div>
{/* payment section-delivery address */}
<div className="payment__section paymentBox">
<div className="payment__title">
<h3>Payment Method</h3>
</div>
<div className="payment__details">
{/* stripe magic will goes here */}
<form onSubmit={handleSubmit} >
<CardElement onChange={handleChange}/>
<div className="payment__priceContainer">
<CurrencyFormat
renderText={(value)=>(
<h3>Order total {value}</h3>
)}
decimalScale={2}
value={getBasketTotal(basket)}
displayType={"text"}
thousandSeparator={true}
prefix={"₹"}
/>
<button disabled={processing || disabled || succeeded}>
<span>{processing?<p>processing</p>:"Buy Now"}</span>
</button>
</div>
{/* Error */}
{error && <div>{error}</div>}
</form>
</div>
</div>
</div>
</div>
)
}
export default Payment;
And the error is here :-
const handleSubmit = async (event) =>{
// do all the fancy stripe stuff
event.preventDefault();
setProcessing(true);
const payload = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement)
}
}).then(({paymentIntent})=>{
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')
})
}
Now, I can understand that it means to say that paymentIntent is undefined but why is it undefined? I tried doing console.log(paymentIntent) inside this function and it said that paymentIntent is undefined.
I have checked for all spelling errors and firebase config.js too.
My application doesn't make the collections in The Firebase neither does it replace the page from /payment to /orders.
I made this app again from scratch and yet the same error occurs. I tried to change my Firebase and Stripe accounts yet I get this error.
Please tell how to fix this error. If you need any other file, I will send you.
回答1:
According to stripe docs.
paymentIntent
is only present when the request is successful. Instead of destructuring directly, Could you also check the errors
object associated with it. And access paymentIntent
only if there are no errors
present.
I suggest you log the entire result object first and check what is happening.
回答2:
The confirmCardPayment method in Stripe.js does not return a Payment Intent, it returns a result
object. In your return handler you should first check for result.error
and, if that's present, handle it. Otherwise you can access result.paymentMethod
(or result.paymentMethod.id
).
Have a look at this sample code from the Stripe.js reference:
stripe.confirmCardPayment('{PAYMENT_INTENT_CLIENT_SECRET}', {
payment_method: {
card: cardElement,
billing_details: {
name: 'Jenny Rosen',
},
},
})
.then(function(result) {
// Handle result.error or result.paymentIntent
});
You don't have error handling and you're not looking for the Payment Intent ID in the right place, which is why you're getting the "Unhandled Rejection (TypeError): Cannot read property 'id' of undefined in React Application" error.
回答3:
The error is (message: "As per Indian regulations, export transactions require a description. More info here: https://stripe.com/docs/india-exports) in my case....
so the confirmCardPayment method does not return a Payment Intent../
And solution is change currency from 'USD' to other currency like 'INR' in (functions/index.js)
amount : total, currency : 'INR'
来源:https://stackoverflow.com/questions/65318451/i-get-the-error-unhandled-rejection-typeerror-cannot-read-property-id-o