diff --git a/src/pages/PlanPage/PlanPage.jsx b/src/pages/PlanPage/PlanPage.jsx index 2608b9efb9..97ce11ffae 100644 --- a/src/pages/PlanPage/PlanPage.jsx +++ b/src/pages/PlanPage/PlanPage.jsx @@ -54,6 +54,7 @@ function PlanPage() { stripe={stripePromise} options={{ ...StripeAppearance(isDarkMode), + // mode and currency are required for the PaymentElement mode: 'setup', currency: 'usd', }} diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressCard.test.tsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressCard.test.tsx index 5142eafd5c..14372d9175 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressCard.test.tsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressCard.test.tsx @@ -224,7 +224,7 @@ describe('AddressCard', () => { { wrapper } ) - expect(screen.getByText('Cardholder name')).toBeInTheDocument() + expect(screen.getByText('Full name')).toBeInTheDocument() expect(screen.getByText('N/A')).toBeInTheDocument() expect(screen.getByText('Billing address')).toBeInTheDocument() expect(screen.queryByText(/null/)).not.toBeInTheDocument() @@ -241,7 +241,7 @@ describe('AddressCard', () => { { wrapper } ) - expect(screen.getByText(/Cardholder name/)).toBeInTheDocument() + expect(screen.getByText(/Full name/)).toBeInTheDocument() expect(screen.getByText(/Bob Smith/)).toBeInTheDocument() }) }) diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressCard.tsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressCard.tsx index 377a7a3c9e..6280b6dbe5 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressCard.tsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/Address/AddressCard.tsx @@ -40,7 +40,7 @@ function AddressCard({ {!isFormOpen && ( <>
-

Cardholder name

+

Full name

setIsFormOpen(true)} diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/BankInformation.tsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/BankInformation.tsx new file mode 100644 index 0000000000..f73afae9f8 --- /dev/null +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/BankInformation.tsx @@ -0,0 +1,26 @@ +import { z } from 'zod' + +import bankLogo from 'assets/billing/bank.svg' +import { SubscriptionDetailSchema } from 'services/account' + +interface BankInformationProps { + subscriptionDetail: z.infer +} +function BankInformation({ subscriptionDetail }: BankInformationProps) { + return ( +
+
+ bank logo +
+ + {subscriptionDetail?.defaultPaymentMethod?.usBankAccount?.bankName} +  ••••  + {subscriptionDetail?.defaultPaymentMethod?.usBankAccount?.last4} + +
+
+
+ ) +} + +export default BankInformation diff --git a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.jsx b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.jsx index 83c001d8a1..a011671d16 100644 --- a/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.jsx +++ b/src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/PaymentCard/PaymentCard.jsx @@ -6,11 +6,13 @@ import A from 'ui/A' import Button from 'ui/Button' import Icon from 'ui/Icon' +import BankInformation from './BankInformation' import CardInformation from './CardInformation' import PaymentMethodForm from './PaymentMethodForm' function PaymentCard({ subscriptionDetail, provider, owner }) { const [isFormOpen, setIsFormOpen] = useState(false) const card = subscriptionDetail?.defaultPaymentMethod?.card + const usBankAccount = subscriptionDetail?.defaultPaymentMethod?.usBankAccount return (
@@ -20,7 +22,7 @@ function PaymentCard({ subscriptionDetail, provider, owner }) { setIsFormOpen(true)} - hook="edit-card" + hook="edit-payment-method" > Edit @@ -31,14 +33,17 @@ function PaymentCard({ subscriptionDetail, provider, owner }) { provider={provider} owner={owner} closeForm={() => setIsFormOpen(false)} + subscriptionDetail={subscriptionDetail} /> ) : card ? ( + ) : usBankAccount ? ( + ) : (

- No credit card set. Please contact support if you think it’s an - error or set it yourself. + No payment method set. Please contact support if you think it's + an error or set it yourself.

@@ -94,7 +100,6 @@ const PaymentMethodForm = ({ variant="plain" disabled={isLoading} onClick={closeForm} - to={undefined} > Cancel diff --git a/src/services/account/index.ts b/src/services/account/index.ts index 4780cda4a0..71d1d41ddd 100644 --- a/src/services/account/index.ts +++ b/src/services/account/index.ts @@ -3,6 +3,7 @@ export * from './propTypes' export * from './useAccountDetails' export * from './useAutoActivate' export * from './useCancelPlan' +export * from './useCreateStripeSetupIntent' export * from './useEraseAccount' export * from './useInvoice' export * from './usePlanData' diff --git a/src/services/account/useAccountDetails.ts b/src/services/account/useAccountDetails.ts index d3fb95b85b..a9632d1fa9 100644 --- a/src/services/account/useAccountDetails.ts +++ b/src/services/account/useAccountDetails.ts @@ -213,3 +213,20 @@ export function useAccountDetails({ ...opts, }) } + +export const stripeAddress = ( + billingDetails: z.infer | null | undefined +) => { + const address = billingDetails?.address + if (!address) return undefined + + return { + line1: address.line1 || null, + line2: address.line2 || null, + city: address.city || null, + state: address.state || null, + // eslint-disable-next-line camelcase + postal_code: address.postalCode || null, + country: address.country || null, + } +} diff --git a/src/services/account/useUpdatePaymentMethod.ts b/src/services/account/useUpdatePaymentMethod.ts index 8cdb844901..abef288be6 100644 --- a/src/services/account/useUpdatePaymentMethod.ts +++ b/src/services/account/useUpdatePaymentMethod.ts @@ -1,4 +1,5 @@ -import { PaymentElement, useElements, useStripe } from '@stripe/react-stripe-js' +import { useElements, useStripe } from '@stripe/react-stripe-js' +import { Address, StripePaymentElement } from '@stripe/stripe-js' import { useMutation, useQueryClient } from '@tanstack/react-query' import config from 'config' @@ -11,7 +12,9 @@ import { useCreateStripeSetupIntent } from './useCreateStripeSetupIntent' interface useUpdatePaymentMethodProps { provider: Provider owner: string + name?: string email?: string + address?: Address } interface useUpdatePaymentMethodReturn { @@ -19,7 +22,7 @@ interface useUpdatePaymentMethodReturn { error: null | Error isLoading: boolean mutate: ( - variables: typeof PaymentElement, + variables: StripePaymentElement | null, data?: { onSuccess?: () => void } ) => void data: undefined | unknown @@ -38,7 +41,9 @@ function getPathAccountDetails({ export function useUpdatePaymentMethod({ provider, owner, + name, email, + address, }: useUpdatePaymentMethodProps): useUpdatePaymentMethodReturn { const stripe = useStripe() const elements = useElements() @@ -62,7 +67,9 @@ export function useUpdatePaymentMethod({ payment_method_data: { // eslint-disable-next-line camelcase billing_details: { + name: name, email: email, + address: address, }, }, // eslint-disable-next-line camelcase