import React, { useState } from 'react'; import { Box, Button, Typography, Alert, CircularProgress } from '@mui/material'; import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js'; import type { StripeCardElementChangeEvent } from '@stripe/stripe-js'; interface PaymentMethodFormProps { onSubmit: (paymentMethodId: string) => void; isLoading?: boolean; } const CARD_ELEMENT_OPTIONS = { style: { base: { fontSize: '16px', color: '#424770', '::placeholder': { color: '#aab7c4', }, }, invalid: { color: '#9e2146', }, }, }; export const PaymentMethodForm: React.FC = ({ onSubmit, isLoading = false, }) => { const stripe = useStripe(); const elements = useElements(); const [error, setError] = useState(null); const [processing, setProcessing] = useState(false); const [cardComplete, setCardComplete] = useState(false); const handleCardChange = (event: StripeCardElementChangeEvent) => { setError(event.error?.message || null); setCardComplete(event.complete); }; const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); if (!stripe || !elements) { return; } const cardElement = elements.getElement(CardElement); if (!cardElement) { return; } setProcessing(true); setError(null); try { const { error: createError, paymentMethod } = await stripe.createPaymentMethod({ type: 'card', card: cardElement, }); if (createError) { setError(createError.message || 'Failed to create payment method'); setProcessing(false); return; } if (paymentMethod) { onSubmit(paymentMethod.id); } } catch { setError('An unexpected error occurred'); setProcessing(false); } }; return (
Card Details {error && ( {error} )}
); };