import { useState, useEffect } from 'react';
import { loadStripe } from '@stripe/stripe-js';
import { Elements, PaymentElement, useStripe, useElements } from '@stripe/react-stripe-js';
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
export default function Checkout({ cartItems, locationId, onSuccess }) {
const [clientSecret, setClientSecret] = useState('');
const [error, setError] = useState(null);
useEffect(() => {
if (cartItems.length === 0) return;
// Create payment intent
fetch('/api/create-payment-intent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ cartItems, locationId })
})
.then(res => res.json())
.then(data => {
if (data.clientSecret) {
setClientSecret(data.clientSecret);
} else {
setError('Failed to setup payment');
}
})
.catch(err => setError(err.message));
}, [cartItems, locationId]);
const options = {
clientSecret,
appearance: {
theme: 'stripe',
variables: {
colorPrimary: '#007bff',
colorBackground: '#ffffff',
colorText: '#30313d',
fontFamily: 'system-ui, sans-serif'
}
}
};
if (error) {
return <div className="error">Error: {error}</div>;
}
if (!clientSecret) {
return <div>Loading payment...</div>;
}
return (
<Elements options={options} stripe={stripePromise}>
<CheckoutForm onSuccess={onSuccess} />
</Elements>
);
}
function CheckoutForm({ onSuccess }) {
const stripe = useStripe();
const elements = useElements();
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const handleSubmit = async (event) => {
event.preventDefault();
if (!stripe || !elements) return;
setLoading(true);
setError(null);
const result = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: `${window.location.origin}/order-success`
},
redirect: 'if_required'
});
if (result.error) {
setError(result.error.message);
} else {
// Payment succeeded
onSuccess(result.paymentIntent);
}
setLoading(false);
};
return (
<form onSubmit={handleSubmit} className="checkout-form">
<PaymentElement />
{error && <div className="error">{error}</div>}
<button type="submit" disabled={!stripe || loading} className="pay-button">
{loading ? 'Processing...' : 'Pay Now'}
</button>
</form>
);
}