我正在使用 PaymentElement 来接受付款。问题是生成 clientSecret 后,在我的网站上更新金额后,它没有反映更新金额。这是反映页面是否重新加载的唯一方法。
我可以在哪里更新金额吗?下面是我的代码。任何帮助将不胜感激。下面是我的代码
import React, { useState, useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import CheckoutForm from '../../components/CheckoutForm'; // Adjust the path as needed
import { loadStripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
import { useParams } from 'next/navigation';
import { useSelector } from 'react-redux';
export default function CheckoutPage() {
const storeInfo = useSelector((state) => state.storeInfo);
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
const [clientSecret, setClientSecret] = useState(null);
const params = useParams();
const storeId = params.store_id;
const grandTotal = useSelector((state) => state.cart.grandTotal); // Assuming it's in the cart slice
useEffect(() => {
const grandTotalInCents = Math.round(grandTotal * 100);
const fetchClientSecret = async () => {
try {
const response = await fetch('/api/checkout/create-payment-intent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: grandTotalInCents, // Dummy amount in cents
name: 'Dummy User', // Dummy name
email : "[email protected]"
}),
});
const data = await response.json();
if (data.clientSecret) {
setClientSecret(data.clientSecret);
} else {
console.error('Failed to retrieve client secret:', data);
}
} catch (error) {
console.error('Error fetching client secret:', error);
}
};
fetchClientSecret();
}, [grandTotal]); // Dependency array ensures this runs when grandTotal changes
return (
<div className="container mt-5">
<div className="d-flex justify-content-end mb-3"></div>
{stripePromise && clientSecret && (
<Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm clientSecrett={clientSecret} />
</Elements>
)}
</div>
);
}
当 clientSecret 更改时,Stripe 的 Elements 不会自动重新初始化。要处理这个问题:
Elements组件上的Key Prop:如果 key prop 发生变化,React 会将 Elements 视为新组件。通过使用 clientSecret 作为 key,只要 clientSecret 发生变化,React 就会重新渲染 Elements 组件。
像这样更新你的 Elements 包装器:
{stripePromise && clientSecret && (
<Elements stripe={stripePromise} options={{ clientSecret }} key={clientSecret}>
<CheckoutForm clientSecret={clientSecret} />
</Elements>
)}
这可确保在获取新的 clientSecret 时 Elements 组件重新初始化。
import React, { useState, useEffect } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import CheckoutForm from '../../components/CheckoutForm'; // Adjust the path as needed
import { loadStripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
import { useParams } from 'next/navigation';
import { useSelector } from 'react-redux';
export default function CheckoutPage() {
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
const [clientSecret, setClientSecret] = useState(null);
const params = useParams();
const storeId = params.store_id;
const grandTotal = useSelector((state) => state.cart.grandTotal); // Assuming it's in the cart slice
useEffect(() => {
const grandTotalInCents = Math.round(grandTotal * 100);
const fetchClientSecret = async () => {
try {
const response = await fetch('/api/checkout/create-payment-intent', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: grandTotalInCents,
name: 'Dummy User',
email: '[email protected]',
}),
});
const data = await response.json();
if (data.clientSecret) {
setClientSecret(data.clientSecret);
} else {
console.error('Failed to retrieve client secret:', data);
}
} catch (error) {
console.error('Error fetching client secret:', error);
}
};
fetchClientSecret();
}, [grandTotal]); // Dependency array ensures this runs when grandTotal changes
return (
<div className="container mt-5">
<div className="d-flex justify-content-end mb-3"></div>
{stripePromise && clientSecret && (
<Elements stripe={stripePromise} options={{ clientSecret }} key={clientSecret}>
<CheckoutForm clientSecret={clientSecret} />
</Elements>
)}
</div>
);
}
确保您的后端端点/api/checkout/create- payment-intent正确创建具有所提供金额的PaymentIntent。
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
app.post('/api/checkout/create-payment-intent', async (req, res) => {
const { amount, name, email } = req.body;
try {
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency: 'usd',
metadata: { name, email },
});
res.send({ clientSecret: paymentIntent.client_secret });
} catch (error) {
console.error('Error creating payment intent:', error);
res.status(500).send({ error: 'Failed to create payment intent' });
}
});