'use client'; import { Elements, PaymentElement, useElements, useStripe } from '@stripe/react-stripe-js'; import { loadStripe } from '@stripe/stripe-js'; import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { useCreatePaymentIntent } from '@/hooks/useStripeOneTime'; const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!); function PaymentForm({ onMessage }: { onMessage: (message: string) => void }) { const stripe = useStripe(); const elements = useElements(); const [loading, setLoading] = useState(false); return (
{ event.preventDefault(); if (!stripe || !elements) return; setLoading(true); const result = await stripe.confirmPayment({ elements, confirmParams: { return_url: `${window.location.origin}/payment/success` }, }); if (result.error) onMessage(result.error.message ?? 'Payment failed'); setLoading(false); }}> ); } export function StripeOneTimePayment({ onMessage }: { onMessage: (message: string) => void }) { const [payment, setPayment] = useState<{ clientSecret: string; amount: number; currency: string } | null>(null); const mutation = useCreatePaymentIntent(); if (!payment) { return ( ); } return ( {new Intl.NumberFormat('en', { style: 'currency', currency: payment.currency }).format(payment.amount / 100)} This amount comes from the server-configured Stripe Price. ); }