w-aura/src/components/PaymentPage/methods/CheckoutForm/index.tsx

109 lines
2.8 KiB
TypeScript

import MainButton from "@/components/MainButton";
import Title from "@/components/Title";
import routes from "@/routes";
import { actions } from "@/store";
import {
PaymentElement,
useElements,
useStripe,
} from "@stripe/react-stripe-js";
import { useState } from "react";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import styles from "./styles.module.css";
export type TConfirmType = "payment" | "setup";
interface ICheckoutFormProps {
children?: JSX.Element | null;
subscriptionReceiptId?: string;
returnUrl?: string;
confirmType?: TConfirmType;
isHide?: boolean;
}
export default function CheckoutForm({
children,
subscriptionReceiptId,
returnUrl,
confirmType = "payment",
isHide = false,
}: ICheckoutFormProps) {
const stripe = useStripe();
const elements = useElements();
const dispatch = useDispatch();
const navigate = useNavigate();
const [message, setMessage] = useState("");
const [isProcessing, setIsProcessing] = useState(false);
const [formReady, setFormReady] = useState(false);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!stripe || !elements) {
return;
}
setIsProcessing(true);
try {
const { error } = await stripe[
confirmType === "payment" ? "confirmPayment" : "confirmSetup"
]({
elements,
confirmParams: {
return_url: returnUrl
? returnUrl
: `https://${window.location.host}/payment/result/${subscriptionReceiptId}/`,
},
});
if (error) {
setMessage(error?.message || "Oops! Something went wrong.");
} else {
dispatch(actions.status.update("subscribed"));
navigate(routes.client.paymentSuccess());
}
} catch (error) {
console.log("error -> ", error);
setMessage("Oops! Something went wrong.");
} finally {
setIsProcessing(false);
}
};
return (
<form
className={`payment-form-stripe ${isHide ? styles.hide : ""}`}
id="payment-form"
onSubmit={handleSubmit}
>
{children ? children : null}
<PaymentElement
options={{
terms: { card: "never" },
wallets: {
googlePay: "never",
applePay: "never",
},
}}
onReady={() => setFormReady(true)}
/>
<MainButton
color="blue"
disabled={isProcessing || !formReady}
id="submit"
className={styles.button}
>
<img src="/lock.svg" alt="Secure" />
<span id="button-text">{isProcessing ? "Processing..." : "Start"}</span>
</MainButton>
{!!message.length && (
<Title variant="h5" style={{ color: "red" }}>
{message}
</Title>
)}
</form>
);
}