AW-104-express-checkout
This commit is contained in:
parent
fb00697993
commit
d8da6d9de6
BIN
public/amazon-pay-mark.png
Normal file
BIN
public/amazon-pay-mark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,116 @@
|
||||
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<string>();
|
||||
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 (
|
||||
<div className={`${styles.container} ${isHideForm ? styles.hide : ""}`}>
|
||||
<ExpressCheckoutElement
|
||||
onReady={onReady}
|
||||
onLoadError={() => onChangeLoading && onChangeLoading(false)}
|
||||
onConfirm={onConfirm}
|
||||
/>
|
||||
{errorMessage && <p className={styles.error}>{errorMessage}</p>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ExpressCheckoutStripe;
|
||||
@ -0,0 +1,16 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.hide {
|
||||
height: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.error {
|
||||
width: 100%;
|
||||
color: #FF5758;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
@ -5,7 +5,7 @@ import { useEffect, useMemo, useState } from "react";
|
||||
import { EPaymentMethod, paymentMethods } from "@/data/paymentMethods";
|
||||
import { Elements } from "@stripe/react-stripe-js";
|
||||
import CheckoutForm from "@/components/PaymentPage/methods/CheckoutForm";
|
||||
import { Stripe, loadStripe } from "@stripe/stripe-js";
|
||||
import { AvailablePaymentMethods, Stripe, loadStripe } from "@stripe/stripe-js";
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectors } from "@/store";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@ -15,8 +15,7 @@ import SecurityPayments from "../SecurityPayments";
|
||||
import { EPlacementKeys, IPaywallProduct } from "@/api/resources/Paywall";
|
||||
import { usePaywall } from "@/hooks/paywall/usePaywall";
|
||||
import { useMakePayment } from "@/hooks/payment/useMakePayment";
|
||||
import StripeButton from "@/components/PaymentPage/methods/StripeButton";
|
||||
import CheckAvailableStripeButton from "@/components/PaymentPage/methods/StripeButton/CheckAvailableStripeButton";
|
||||
import ExpressCheckoutStripe from "@/components/PaymentPage/methods/ExpressCheckoutStripe";
|
||||
|
||||
interface IPaymentModalProps {
|
||||
activeProduct?: IPaywallProduct;
|
||||
@ -49,7 +48,7 @@ function PaymentModal({
|
||||
returnUrl: checkoutUrl,
|
||||
paymentType,
|
||||
publicKey,
|
||||
isLoading,
|
||||
isLoading: isLoadingPayment,
|
||||
error,
|
||||
} = useMakePayment({
|
||||
productId: _activeProduct?._id || "",
|
||||
@ -58,17 +57,23 @@ function PaymentModal({
|
||||
returnPaidUrl: returnUrl,
|
||||
});
|
||||
|
||||
const stripeButton = useSelector(selectors.selectStripeButton);
|
||||
const [availableMethods, setAvailableMethods] = useState<
|
||||
AvailablePaymentMethods | undefined
|
||||
>();
|
||||
|
||||
const paymentRequest = stripeButton?.paymentRequest;
|
||||
const availableMethods = stripeButton?.availableMethods;
|
||||
const [isLoadingExpressCheckout, setIsLoadingExpressCheckout] =
|
||||
useState(true);
|
||||
|
||||
const isLoading = useMemo(() => {
|
||||
return isLoadingPayment || isLoadingExpressCheckout;
|
||||
}, [isLoadingPayment, isLoadingExpressCheckout]);
|
||||
|
||||
if (checkoutUrl?.length) {
|
||||
window.location.href = checkoutUrl;
|
||||
}
|
||||
|
||||
const paymentMethodsButtons = useMemo(() => {
|
||||
return paymentMethods(availableMethods);
|
||||
return paymentMethods(availableMethods || null);
|
||||
}, [availableMethods]);
|
||||
|
||||
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(
|
||||
@ -92,15 +97,16 @@ function PaymentModal({
|
||||
})();
|
||||
}, [_activeProduct, navigate, products, publicKey]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className={styles["payment-modal"]}>
|
||||
<div className={styles["payment-loader"]}>
|
||||
<Loader />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const onAvailableExpressCheckout = (
|
||||
isAvailable: boolean,
|
||||
availableMethods: AvailablePaymentMethods | undefined
|
||||
) => {
|
||||
if (isAvailable && availableMethods) {
|
||||
setAvailableMethods(availableMethods);
|
||||
return setSelectedPaymentMethod(EPaymentMethod.PAYMENT_BUTTONS);
|
||||
}
|
||||
return setAvailableMethods(undefined);
|
||||
};
|
||||
|
||||
if (error?.length) {
|
||||
return (
|
||||
@ -113,62 +119,75 @@ function PaymentModal({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles["payment-modal"]}>
|
||||
<Title variant="h3" className={styles.title}>
|
||||
Choose payment method
|
||||
</Title>
|
||||
<PaymentMethodsChoice
|
||||
paymentMethods={paymentMethodsButtons}
|
||||
selectedPaymentMethod={selectedPaymentMethod}
|
||||
onSelectPaymentMethod={onSelectPaymentMethod}
|
||||
/>
|
||||
{_activeProduct && (
|
||||
<div>
|
||||
{!noTrial && (
|
||||
<>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
You will be charged only{" "}
|
||||
<b>${getPrice(_activeProduct)} for your 3-day trial.</b>
|
||||
</p>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
We`ll <b>email you a reminder</b> before your trial period ends.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
Cancel anytime. The charge will appear on your bill as witapps.
|
||||
</p>
|
||||
<>
|
||||
{isLoading && (
|
||||
<div className={styles["payment-modal"]}>
|
||||
<div className={styles["payment-loader"]}>
|
||||
<Loader />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={styles["payment-method-container"]}>
|
||||
{stripePromise && clientSecret && (
|
||||
<Elements stripe={stripePromise} options={{ clientSecret }}>
|
||||
<CheckAvailableStripeButton
|
||||
activeProduct={_activeProduct}
|
||||
clientSecret={clientSecret}
|
||||
/>
|
||||
{selectedPaymentMethod === EPaymentMethod.PAYMENT_BUTTONS && (
|
||||
<div className={styles["payment-method"]}>
|
||||
{paymentRequest && (
|
||||
<StripeButton paymentRequest={paymentRequest} />
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={`${styles["payment-modal"]} ${isLoading ? styles.hide : ""}`}
|
||||
>
|
||||
<Title variant="h3" className={styles.title}>
|
||||
Choose payment method
|
||||
</Title>
|
||||
<PaymentMethodsChoice
|
||||
paymentMethods={paymentMethodsButtons}
|
||||
selectedPaymentMethod={selectedPaymentMethod}
|
||||
onSelectPaymentMethod={onSelectPaymentMethod}
|
||||
/>
|
||||
{_activeProduct && (
|
||||
<div>
|
||||
{!noTrial && (
|
||||
<>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
You will be charged only{" "}
|
||||
<b>${getPrice(_activeProduct)} for your 3-day trial.</b>
|
||||
</p>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
We`ll <b>email you a reminder</b> before your trial period
|
||||
ends.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedPaymentMethod === EPaymentMethod.CREDIT_CARD && (
|
||||
<CheckoutForm
|
||||
confirmType={paymentType}
|
||||
subscriptionReceiptId={paymentIntentId}
|
||||
returnUrl={returnUrl}
|
||||
/>
|
||||
)}
|
||||
</Elements>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
Cancel anytime. The charge will appear on your bill as witapps.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className={styles["payment-method-container"]}>
|
||||
{stripePromise && clientSecret && (
|
||||
<Elements stripe={stripePromise} options={{ clientSecret }}>
|
||||
<ExpressCheckoutStripe
|
||||
clientSecret={clientSecret}
|
||||
returnUrl={returnUrl}
|
||||
isHide={
|
||||
selectedPaymentMethod !== EPaymentMethod.PAYMENT_BUTTONS
|
||||
}
|
||||
onAvailable={(_isAvailable, _availableMethods) =>
|
||||
onAvailableExpressCheckout(_isAvailable, _availableMethods)
|
||||
}
|
||||
onChangeLoading={(isLoading) =>
|
||||
setIsLoadingExpressCheckout(isLoading)
|
||||
}
|
||||
/>
|
||||
{selectedPaymentMethod === EPaymentMethod.CREDIT_CARD && (
|
||||
<CheckoutForm
|
||||
confirmType={paymentType}
|
||||
subscriptionReceiptId={paymentIntentId}
|
||||
returnUrl={returnUrl}
|
||||
/>
|
||||
)}
|
||||
</Elements>
|
||||
)}
|
||||
</div>
|
||||
<SecurityPayments />
|
||||
<p className={styles.address}>500 N RAINBOW BLVD LAS VEGAS, NV 89107</p>
|
||||
</div>
|
||||
<SecurityPayments />
|
||||
<p className={styles.address}>500 N RAINBOW BLVD LAS VEGAS, NV 89107</p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,12 @@
|
||||
color: #2f2e37;
|
||||
}
|
||||
|
||||
.payment-modal.hide {
|
||||
min-height: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
|
||||
@ -5,7 +5,7 @@ import { useEffect, useMemo, useState } from "react";
|
||||
import { EPaymentMethod, paymentMethods } from "@/data/paymentMethods";
|
||||
import { Elements } from "@stripe/react-stripe-js";
|
||||
import CheckoutForm from "@/components/PaymentPage/methods/CheckoutForm";
|
||||
import { Stripe, loadStripe } from "@stripe/stripe-js";
|
||||
import { AvailablePaymentMethods, Stripe, loadStripe } from "@stripe/stripe-js";
|
||||
import { useSelector } from "react-redux";
|
||||
import { selectors } from "@/store";
|
||||
import Loader from "@/components/Loader";
|
||||
@ -13,8 +13,9 @@ import SecurityPayments from "../SecurityPayments";
|
||||
import { EPlacementKeys, IPaywallProduct } from "@/api/resources/Paywall";
|
||||
import { usePaywall } from "@/hooks/paywall/usePaywall";
|
||||
import { useMakePayment } from "@/hooks/payment/useMakePayment";
|
||||
import StripeButton from "@/components/PaymentPage/methods/StripeButton";
|
||||
import CheckAvailableStripeButton from "@/components/PaymentPage/methods/StripeButton/CheckAvailableStripeButton";
|
||||
import ExpressCheckoutStripe from "@/components/PaymentPage/methods/ExpressCheckoutStripe";
|
||||
import routes from "@/routes";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
interface IPaymentModalProps {
|
||||
activeProduct?: IPaywallProduct;
|
||||
@ -36,6 +37,7 @@ function PaymentModal({
|
||||
returnUrl,
|
||||
placementKey = EPlacementKeys["aura.placement.main"],
|
||||
}: IPaymentModalProps) {
|
||||
const navigate = useNavigate();
|
||||
const [stripePromise, setStripePromise] =
|
||||
useState<Promise<Stripe | null> | null>(null);
|
||||
|
||||
@ -51,7 +53,7 @@ function PaymentModal({
|
||||
returnUrl: checkoutUrl,
|
||||
paymentType,
|
||||
publicKey,
|
||||
isLoading,
|
||||
isLoading: isLoadingPayment,
|
||||
error,
|
||||
} = useMakePayment({
|
||||
productId: _activeProduct?._id || "",
|
||||
@ -60,20 +62,27 @@ function PaymentModal({
|
||||
returnPaidUrl: returnUrl,
|
||||
});
|
||||
|
||||
const { paymentRequest, availableMethods } = useSelector(
|
||||
selectors.selectStripeButton
|
||||
);
|
||||
const [availableMethods, setAvailableMethods] = useState<
|
||||
AvailablePaymentMethods | undefined
|
||||
>();
|
||||
|
||||
const [isLoadingExpressCheckout, setIsLoadingExpressCheckout] =
|
||||
useState(true);
|
||||
|
||||
const isLoading = useMemo(() => {
|
||||
return isLoadingPayment || isLoadingExpressCheckout;
|
||||
}, [isLoadingPayment, isLoadingExpressCheckout]);
|
||||
|
||||
if (checkoutUrl?.length) {
|
||||
window.location.href = checkoutUrl;
|
||||
}
|
||||
|
||||
const paymentMethodsButtons = useMemo(() => {
|
||||
return paymentMethods(availableMethods);
|
||||
return paymentMethods(availableMethods || null);
|
||||
}, [availableMethods]);
|
||||
|
||||
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(
|
||||
EPaymentMethod.PAYMENT_BUTTONS
|
||||
paymentMethodsButtons[0].id
|
||||
);
|
||||
|
||||
const onSelectPaymentMethod = (method: EPaymentMethod) => {
|
||||
@ -84,18 +93,25 @@ function PaymentModal({
|
||||
(async () => {
|
||||
if (!products?.length || !publicKey) return;
|
||||
setStripePromise(loadStripe(publicKey));
|
||||
const isActiveProduct = products.find(
|
||||
(product) => product._id === _activeProduct?._id
|
||||
);
|
||||
if (!_activeProduct || !isActiveProduct) {
|
||||
navigate(routes.client.trialChoice());
|
||||
}
|
||||
})();
|
||||
}, [products, publicKey]);
|
||||
}, [_activeProduct, navigate, products, publicKey]);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className={styles["payment-modal"]}>
|
||||
<div className={styles["payment-loader"]}>
|
||||
<Loader />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const onAvailableExpressCheckout = (
|
||||
isAvailable: boolean,
|
||||
availableMethods: AvailablePaymentMethods | undefined
|
||||
) => {
|
||||
if (isAvailable && availableMethods) {
|
||||
setAvailableMethods(availableMethods);
|
||||
return setSelectedPaymentMethod(EPaymentMethod.PAYMENT_BUTTONS);
|
||||
}
|
||||
return setAvailableMethods(undefined);
|
||||
};
|
||||
|
||||
if (error?.length) {
|
||||
return (
|
||||
@ -108,62 +124,75 @@ function PaymentModal({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles["payment-modal"]}>
|
||||
<Title variant="h3" className={styles.title}>
|
||||
Choose payment method
|
||||
</Title>
|
||||
<PaymentMethodsChoice
|
||||
paymentMethods={paymentMethodsButtons}
|
||||
selectedPaymentMethod={selectedPaymentMethod}
|
||||
onSelectPaymentMethod={onSelectPaymentMethod}
|
||||
/>
|
||||
{_activeProduct && (
|
||||
<div>
|
||||
{!noTrial && (
|
||||
<>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
You will be charged only{" "}
|
||||
<b>${getPrice(_activeProduct)} for your 3-day trial.</b>
|
||||
</p>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
We`ll <b>email you a reminder</b> before your trial period ends.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
Cancel anytime. The charge will appear on your bill as witapps.
|
||||
</p>
|
||||
<>
|
||||
{isLoading && (
|
||||
<div className={styles["payment-modal"]}>
|
||||
<div className={styles["payment-loader"]}>
|
||||
<Loader />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className={styles["payment-method-container"]}>
|
||||
{stripePromise && clientSecret && (
|
||||
<Elements stripe={stripePromise} options={{ clientSecret }}>
|
||||
<CheckAvailableStripeButton
|
||||
activeProduct={_activeProduct}
|
||||
clientSecret={clientSecret}
|
||||
/>
|
||||
{selectedPaymentMethod === EPaymentMethod.PAYMENT_BUTTONS && (
|
||||
<div className={styles["payment-method"]}>
|
||||
{paymentRequest && (
|
||||
<StripeButton paymentRequest={paymentRequest} />
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className={`${styles["payment-modal"]} ${isLoading ? styles.hide : ""}`}
|
||||
>
|
||||
<Title variant="h3" className={styles.title}>
|
||||
Choose payment method
|
||||
</Title>
|
||||
<PaymentMethodsChoice
|
||||
paymentMethods={paymentMethodsButtons}
|
||||
selectedPaymentMethod={selectedPaymentMethod}
|
||||
onSelectPaymentMethod={onSelectPaymentMethod}
|
||||
/>
|
||||
{_activeProduct && (
|
||||
<div>
|
||||
{!noTrial && (
|
||||
<>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
You will be charged only{" "}
|
||||
<b>${getPrice(_activeProduct)} for your 3-day trial.</b>
|
||||
</p>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
We`ll <b>email you a reminder</b> before your trial period
|
||||
ends.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
{selectedPaymentMethod === EPaymentMethod.CREDIT_CARD && (
|
||||
<CheckoutForm
|
||||
confirmType={paymentType}
|
||||
subscriptionReceiptId={paymentIntentId}
|
||||
returnUrl={returnUrl}
|
||||
/>
|
||||
)}
|
||||
</Elements>
|
||||
<p className={styles["sub-plan-description"]}>
|
||||
Cancel anytime. The charge will appear on your bill as witapps.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className={styles["payment-method-container"]}>
|
||||
{stripePromise && clientSecret && (
|
||||
<Elements stripe={stripePromise} options={{ clientSecret }}>
|
||||
<ExpressCheckoutStripe
|
||||
clientSecret={clientSecret}
|
||||
returnUrl={returnUrl}
|
||||
isHide={
|
||||
selectedPaymentMethod !== EPaymentMethod.PAYMENT_BUTTONS
|
||||
}
|
||||
onAvailable={(_isAvailable, _availableMethods) =>
|
||||
onAvailableExpressCheckout(_isAvailable, _availableMethods)
|
||||
}
|
||||
onChangeLoading={(isLoading) =>
|
||||
setIsLoadingExpressCheckout(isLoading)
|
||||
}
|
||||
/>
|
||||
{selectedPaymentMethod === EPaymentMethod.CREDIT_CARD && (
|
||||
<CheckoutForm
|
||||
confirmType={paymentType}
|
||||
subscriptionReceiptId={paymentIntentId}
|
||||
returnUrl={returnUrl}
|
||||
/>
|
||||
)}
|
||||
</Elements>
|
||||
)}
|
||||
</div>
|
||||
<SecurityPayments />
|
||||
<p className={styles.address}>500 N RAINBOW BLVD LAS VEGAS, NV 89107</p>
|
||||
</div>
|
||||
<SecurityPayments />
|
||||
<p className={styles.address}>500 N RAINBOW BLVD LAS VEGAS, NV 89107</p>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,12 @@
|
||||
color: #2f2e37;
|
||||
}
|
||||
|
||||
.payment-modal.hide {
|
||||
min-height: 0;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
|
||||
@ -4,26 +4,28 @@ import { TCanMakePaymentResult } from "@/components/PaymentPage/methods/StripeBu
|
||||
interface IPaymentButtonsProps {
|
||||
availableMethods: TCanMakePaymentResult;
|
||||
}
|
||||
const Image = ({ availableMethods }: IPaymentButtonsProps) => {
|
||||
if (!availableMethods) return <></>;
|
||||
if (availableMethods["applePay"]) {
|
||||
return <img src="/applepay.webp" alt="ApplePay" />;
|
||||
}
|
||||
if (availableMethods["googlePay"]) {
|
||||
return <img src="/google-pay-mark.png" alt="google" />;
|
||||
}
|
||||
if (availableMethods["amazon"]) {
|
||||
return <img src="/amazon-pay-mark.png" alt="AmazonPay" />;
|
||||
}
|
||||
if (availableMethods["link"]) {
|
||||
return <img src="/link-pay-mark.png" alt="LinkPay" />;
|
||||
}
|
||||
return <></>;
|
||||
};
|
||||
|
||||
function PaymentButtons({ availableMethods }: IPaymentButtonsProps) {
|
||||
if (!availableMethods) return <></>;
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
{availableMethods["applePay"] && (
|
||||
<img src="/applepay.webp" alt="ApplePay" />
|
||||
)}
|
||||
{availableMethods["googlePay"] && (
|
||||
<img
|
||||
src="/google-pay-mark.png"
|
||||
alt="google"
|
||||
style={{
|
||||
height: "36px",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{availableMethods["link"] && (
|
||||
<img src="/link-pay-mark.png" alt="LinkPay" />
|
||||
)}
|
||||
<Image availableMethods={availableMethods} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user