E-Commerce-Module/frontend/src/components/StripePaymentForm.jsx
2025-04-26 19:25:36 -05:00

98 lines
No EOL
2.6 KiB
JavaScript

import React, { useState } from 'react';
import {
PaymentElement,
useStripe as useStripeJs,
useElements
} from '@stripe/react-stripe-js';
import { Box, Button, CircularProgress, Alert, Typography } from '@mui/material';
import { useStripe } from '../context/StripeContext';
const StripePaymentForm = ({ orderId, onSuccess, onError }) => {
const stripe = useStripeJs();
const elements = useElements();
const { completeOrder } = useStripe();
const [isLoading, setIsLoading] = useState(false);
const [message, setMessage] = useState(null);
const handleSubmit = async (e) => {
e.preventDefault();
if (!stripe || !elements) {
// Stripe.js hasn't loaded yet
return;
}
setIsLoading(true);
setMessage(null);
try {
// Submit the form
const { error, paymentIntent } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: `${window.location.origin}/checkout/confirmation?order_id=${orderId}`,
},
redirect: 'if_required',
});
if (error) {
setMessage(error.message || 'An unexpected error occurred');
onError(error.message);
} else if (paymentIntent && paymentIntent.status === 'succeeded') {
// Call our backend to update the order status
await completeOrder(orderId, paymentIntent.id);
setMessage('Payment successful!');
onSuccess(paymentIntent);
} else {
setMessage('Payment processing. Please wait for confirmation.');
}
} catch (err) {
console.error('Payment error:', err);
setMessage(err.message || 'An error occurred during payment processing');
onError(err.message);
} finally {
setIsLoading(false);
}
};
return (
<Box component="form" onSubmit={handleSubmit} sx={{ width: '100%' }}>
{message && (
<Alert
severity={message.includes('successful') ? 'success' : 'error'}
sx={{ mb: 3 }}
>
{message}
</Alert>
)}
<Typography variant="h6" gutterBottom>
Enter your payment details
</Typography>
<Box sx={{ mb: 3 }}>
<PaymentElement />
</Box>
<Button
type="submit"
variant="contained"
color="primary"
fullWidth
size="large"
disabled={isLoading || !stripe || !elements}
>
{isLoading ? (
<>
<CircularProgress size={24} sx={{ mr: 1 }} />
Processing...
</>
) : (
'Pay Now'
)}
</Button>
</Box>
);
};
export default StripePaymentForm;