import { useMemo, useState } from "react"; import styles from "./styles.module.css"; import { useStripe, useElements, ExpressCheckoutElement, } from "@stripe/react-stripe-js"; import { AvailablePaymentMethods, StripeExpressCheckoutElementReadyEvent, } from "@stripe/stripe-js"; interface IExpressCheckoutStripeProps { clientSecret: string; returnUrl?: string; isHide?: boolean; onAvailable?: ( isAvailable: boolean, availableMethods: AvailablePaymentMethods | undefined ) => void; onChangeLoading?: (isLoading: boolean) => void; } const checkFormAvailable = ( availablePaymentMethods: undefined | AvailablePaymentMethods ) => { if (!availablePaymentMethods) return false; let result = false; for (const key in availablePaymentMethods) { if (availablePaymentMethods[key as keyof AvailablePaymentMethods]) { result = true; break; } } return result; }; function ExpressCheckoutStripe({ clientSecret, returnUrl = "https://${window.location.host}/payment/result/", isHide = false, onAvailable, onChangeLoading, }: IExpressCheckoutStripeProps) { const stripe = useStripe(); const elements = useElements(); const [errorMessage, setErrorMessage] = useState(); const [isAvailable, setIsAvailable] = useState(false); const isHideForm = useMemo( () => isHide || !isAvailable, [isAvailable, isHide] ); const onConfirm = async () => // event: StripeExpressCheckoutElementConfirmEvent { if (!stripe || !elements) { // Stripe.js hasn't loaded yet. // Make sure to disable form submission until Stripe.js has loaded. return; } const { error: submitError } = await elements.submit(); if (submitError) { setErrorMessage(submitError.message); return; } // // Create the PaymentIntent and obtain clientSecret // const res = await fetch("/create-intent", { // method: "POST", // }); // const { client_secret: clientSecret } = await res.json(); // Confirm the PaymentIntent using the details collected by the Express Checkout Element const { error } = await stripe.confirmPayment({ // `elements` instance used to create the Express Checkout Element elements, // `clientSecret` from the created PaymentIntent clientSecret, confirmParams: { return_url: returnUrl, }, }); if (error) { // This point is only reached if there's an immediate error when // confirming the payment. Show the error to your customer (for example, payment details incomplete) setErrorMessage(error.message); } else { // The payment UI automatically closes with a success animation. // Your customer is redirected to your `return_url`. } }; const onReady = (event: StripeExpressCheckoutElementReadyEvent) => { const _isAvailable = checkFormAvailable(event.availablePaymentMethods); setIsAvailable(_isAvailable); onAvailable && onAvailable(_isAvailable, event.availablePaymentMethods); onChangeLoading && onChangeLoading(false); }; return (
onChangeLoading && onChangeLoading(false)} onConfirm={onConfirm} /> {errorMessage &&

{errorMessage}

}
); } export default ExpressCheckoutStripe;