1 import { c } from 'ttag';
3 import { usePaymentMethods } from '@proton/account/paymentMethods/hooks';
4 import { useSubscription } from '@proton/account/subscription/hooks';
5 import { useUser } from '@proton/account/user/hooks';
6 import type { ButtonProps } from '@proton/atoms';
7 import { Button } from '@proton/atoms';
8 import Icon from '@proton/components/components/icon/Icon';
9 import Loader from '@proton/components/components/loader/Loader';
10 import useModalState from '@proton/components/components/modalTwo/useModalState';
11 import MozillaInfoPanel from '@proton/components/containers/account/MozillaInfoPanel';
12 import SettingsParagraph from '@proton/components/containers/account/SettingsParagraph';
13 import SettingsSection from '@proton/components/containers/account/SettingsSection';
14 import useConfig from '@proton/components/hooks/useConfig';
15 import useMozillaCheck from '@proton/components/hooks/useMozillaCheck';
16 import { useChargebeeEnabledCache } from '@proton/components/payments/client-extensions/useChargebeeContext';
17 import { usePollEvents } from '@proton/components/payments/client-extensions/usePollEvents';
18 import useLoading from '@proton/hooks/useLoading';
22 type SavedPaymentMethod,
25 } from '@proton/payments';
26 import { APPS, EVENT_ACTIONS } from '@proton/shared/lib/constants';
27 import { getKnowledgeBaseUrl } from '@proton/shared/lib/helpers/url';
28 import { ChargebeeEnabled } from '@proton/shared/lib/interfaces';
30 import { useRedirectToAccountApp } from '../../desktop/useRedirectToAccountApp';
31 import EditCardModal from '../EditCardModal';
32 import { default as PayPalV4Modal, PayPalV5Modal } from '../PayPalModal';
33 import PaymentMethodsTable from './PaymentMethodsTable';
35 const AddPaypalButton = ({ onClick, ...rest }: ButtonProps) => {
37 <Button shape="outline" onClick={onClick} {...rest}>
38 <Icon name="brand-paypal" className="mr-2" />
39 <span>{c('Action').t`Add PayPal`}</span>
44 const PaymentMethodsSection = () => {
45 const { APP_NAME } = useConfig();
46 const [paymentMethods = [], loadingPaymentMethods] = usePaymentMethods();
47 const [isManagedByMozilla, loadingCheck] = useMozillaCheck();
48 const [creditCardModalProps, setCreditCardModalOpen, renderCreditCardModal] = useModalState();
49 const [paypalV4ModalProps, setPaypalV4ModalOpen, renderPaypalV4Modal] = useModalState();
50 const [paypalV5ModalProps, setPaypalV5ModalOpen, renderPaypalV5Modal] = useModalState();
51 const isChargebeeEnabled = useChargebeeEnabledCache();
52 const [subscription] = useSubscription();
53 const [user] = useUser();
54 const pollPaymentMethodsCreate = usePollEvents({
55 subscribeToProperty: 'PaymentMethods',
56 action: EVENT_ACTIONS.CREATE,
58 const [pollingEvents, withPollingEvents] = useLoading();
59 const redirectToAccountApp = useRedirectToAccountApp();
61 if (loadingPaymentMethods || loadingCheck) {
65 if (isManagedByMozilla) {
66 return <MozillaInfoPanel />;
70 APP_NAME === APPS.PROTONVPN_SETTINGS
71 ? 'https://protonvpn.com/support/payment-options/'
72 : getKnowledgeBaseUrl('/payment-options');
75 isChargebeeEnabled() !== ChargebeeEnabled.CHARGEBEE_FORCED ||
76 (isOnSessionMigration(user.ChargebeeUser, subscription?.BillingPlatform) &&
77 !isSplittedUser(user.ChargebeeUser, user.ChargebeeUserExists, subscription?.BillingPlatform));
79 const paypalPredicate = (method: SavedPaymentMethod) =>
80 method.Type === PAYMENT_METHOD_TYPES.PAYPAL &&
81 (method.External === MethodStorage.INTERNAL || method.External === MethodStorage.EXTERNAL);
83 const canAddPaypalV4 = !paymentMethods.some(paypalPredicate) && canAddV4;
84 const canAddPaypalV5 = !paymentMethods.some(paypalPredicate) && !canAddV4;
86 const loadAddedMethod = () => {
87 void withPollingEvents(pollPaymentMethodsCreate());
92 <SettingsParagraph learnMoreUrl={learnMoreUrl}>
93 {c('Info for payment methods')
94 .t`You can add a payment method to have your subscription renewed automatically. Other payment methods are also available.`}
96 <div className="mb-4">
100 disabled={pollingEvents}
102 if (redirectToAccountApp()) {
106 setCreditCardModalOpen(true);
109 <Icon name="credit-card" className="mr-2" />
110 <span>{c('Action').t`Add credit / debit card`}</span>
114 disabled={pollingEvents}
116 if (redirectToAccountApp()) {
120 setPaypalV4ModalOpen(true);
126 disabled={pollingEvents}
128 if (redirectToAccountApp()) {
132 setPaypalV5ModalOpen(true);
137 <PaymentMethodsTable loading={pollingEvents} methods={paymentMethods} />
138 {renderCreditCardModal && <EditCardModal onMethodAdded={loadAddedMethod} {...creditCardModalProps} />}
139 {renderPaypalV4Modal && <PayPalV4Modal {...paypalV4ModalProps} />}
140 {renderPaypalV5Modal && <PayPalV5Modal onMethodAdded={loadAddedMethod} {...paypalV5ModalProps} />}
145 export default PaymentMethodsSection;