Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add ACH payment method #3616

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
10 changes: 10 additions & 0 deletions src/assets/billing/bank.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion src/pages/PlanPage/PlanPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import config from 'config'

import { SentryRoute } from 'sentry'

import { Theme, useThemeContext } from 'shared/ThemeContext'
import LoadingLogo from 'ui/LoadingLogo'

import { PlanProvider } from './context'
import PlanBreadcrumb from './PlanBreadcrumb'
import { PlanPageDataQueryOpts } from './queries/PlanPageDataQueryOpts'
import Tabs from './Tabs'

import { StripeAppearance } from '../../stripe'

const CancelPlanPage = lazy(() => import('./subRoutes/CancelPlanPage'))
const CurrentOrgPlan = lazy(() => import('./subRoutes/CurrentOrgPlan'))
const InvoicesPage = lazy(() => import('./subRoutes/InvoicesPage'))
Expand All @@ -37,6 +40,8 @@ function PlanPage() {
const { data: ownerData } = useSuspenseQueryV5(
PlanPageDataQueryOpts({ owner, provider })
)
const { theme } = useThemeContext()
const isDarkMode = theme !== Theme.LIGHT

if (config.IS_SELF_HOSTED || !ownerData?.isCurrentUserPartOfOrg) {
return <Redirect to={`/${provider}/${owner}`} />
Expand All @@ -45,7 +50,7 @@ function PlanPage() {
return (
<div className="flex flex-col gap-4">
<Tabs />
<Elements stripe={stripePromise}>
<Elements stripe={stripePromise} options={StripeAppearance(isDarkMode)}>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the Theme was getting duped and passed in both the AddressForm and CreditCardForm before, so I consolidated them in file stripe.ts

<PlanProvider>
<PlanBreadcrumb />
<Suspense fallback={<Loader />}>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { useState } from 'react'
import { useParams } from 'react-router-dom'

import { useAccountDetails } from 'services/account'
import A from 'ui/A'
import Button from 'ui/Button'

import AddressCard from './Address/AddressCard'
import EditPaymentMethods from './EditPaymentMethods'
import EmailAddress from './EmailAddress'
import PaymentCard from './PaymentCard'
import { ViewPaymentMethod } from './ViewPaymentMethod'

// Remove this when we build Secondary Payment Method feature
export const SECONDARY_PAYMENT_FEATURE_ENABLED = false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flag can get removed when we build out the rest of the secondary payment method feature (next quarter)


interface URLParams {
provider: string
Expand All @@ -18,34 +24,86 @@ function BillingDetails() {
owner,
})
const subscriptionDetail = accountDetails?.subscriptionDetail
const [isEditMode, setEditMode] = useState(false)

const secondaryPaymentFeatureEnabled = SECONDARY_PAYMENT_FEATURE_ENABLED

if (!subscriptionDetail) {
return null
}

return (
<div className="flex flex-col border">
<h3 className="p-4 font-semibold">Billing details</h3>
<EmailAddress />
<PaymentCard
// @ts-expect-error - TODO fix this once we update PaymentCard to TS
subscriptionDetail={subscriptionDetail}
provider={provider}
owner={owner}
/>
<AddressCard
subscriptionDetail={subscriptionDetail}
provider={provider}
owner={owner}
/>
{subscriptionDetail.taxIds.length > 0 ? (
<div className="flex flex-col gap-2 p-4">
<h4 className="font-semibold">Tax ID</h4>
{subscriptionDetail.taxIds.map((val, index) => (
<p key={index}>{val?.value}</p>
))}
<div className="flex flex-col divide-y border">
{/* Billing Details Section */}
<div className="flex items-center justify-between gap-4 p-4">
<div>
<h3 className="font-semibold">Billing details</h3>
<p className="pt-1 text-xs text-ds-gray-octonary">
You can modify your billing details. To update your tax IDs, please{' '}
{/* @ts-expect-error ignore until we can convert A component to ts */}
<A to={{ pageName: 'support' }} variant="link">
contact support
</A>
</p>
</div>
) : null}
{!isEditMode ? (
<Button
hook="button"
onClick={() => setEditMode(true)}
variant="default"
className="flex-none"
>
Edit payment
</Button>
) : (
<Button
hook="button"
onClick={() => setEditMode(false)}
variant="default"
className="flex-none"
>
Back
</Button>
)}
</div>
{isEditMode ? (
<EditPaymentMethods
setEditMode={setEditMode}
provider={provider}
owner={owner}
existingSubscriptionDetail={subscriptionDetail}
/>
) : (
<>
<EmailAddress />
<ViewPaymentMethod
heading="Primary Payment Method"
isPrimaryPaymentMethod={true}
setEditMode={setEditMode}
subscriptionDetail={subscriptionDetail}
provider={provider}
owner={owner}
/>
{secondaryPaymentFeatureEnabled && (
<ViewPaymentMethod
heading="Secondary Payment Method"
isPrimaryPaymentMethod={false}
setEditMode={setEditMode}
subscriptionDetail={subscriptionDetail}
provider={provider}
owner={owner}
/>
)}
{subscriptionDetail?.taxIds?.length ? (
<div className="flex flex-col gap-2 p-4">
<h4 className="font-semibold">Tax ID</h4>
{subscriptionDetail?.taxIds?.map((val, index) => (
<p key={index}>{val?.value}</p>
))}
</div>
) : null}
</>
)}
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import { z } from 'zod'

import { AddressSchema } from 'services/account'
import { useUpdateBillingAddress } from 'services/account/useUpdateBillingAddress'
import { Theme, useThemeContext } from 'shared/ThemeContext'
import Button from 'ui/Button'

interface AddressFormProps {
address?: z.infer<typeof AddressSchema>
name?: string
name?: string | null | undefined
closeForm: () => void
provider: string
owner: string
Expand All @@ -23,28 +22,6 @@ function AddressForm({
owner,
}: AddressFormProps) {
const elements = useElements()
const { theme } = useThemeContext()
const isDarkMode = theme === Theme.DARK

// Note: unfortunately seems Stripe doesn't let us reference like `var(--<var name>)` so rgbs are hardcoded in below
elements?.update({
appearance: {
variables: {
fontFamily: 'Poppins, ui-sans-serif, system-ui, sans-serif',
},
rules: {
'.Label': {
fontWeight: '600',
color: isDarkMode ? 'rgb(210,212,215)' : 'rgb(14,27,41)', // Same values as --color-app-text-primary.
},
'.Input': {
backgroundColor: isDarkMode ? 'rgb(22,24,29)' : 'rgb(255,255,255)', // Same values as --color-app-container.
borderColor: isDarkMode ? 'rgb(47,51,60)' : 'rgb(216,220,226)', // Same values as --color-ds-gray-tertiary.
color: isDarkMode ? 'rgb(210,212,215)' : 'rgb(14,27,41)', // Same values as --color-app-text-primary.
},
},
},
})

const {
mutate: updateAddress,
Expand Down Expand Up @@ -105,7 +82,7 @@ function AddressForm({
disabled={isLoading}
to={undefined}
>
Update
Save
</Button>
<Button
type="button"
Expand Down
Loading
Loading