diff --git a/static/gsAdmin/views/customerDetails.spec.tsx b/static/gsAdmin/views/customerDetails.spec.tsx index 0a14fe02ba5581..a10c06dc902871 100644 --- a/static/gsAdmin/views/customerDetails.spec.tsx +++ b/static/gsAdmin/views/customerDetails.spec.tsx @@ -2529,6 +2529,7 @@ describe('Customer Details', () => { countryCode: 'US', expMonth: 12, expYear: 2028, + brand: 'Visa', }, }); @@ -2564,6 +2565,7 @@ describe('Customer Details', () => { countryCode: 'US', expMonth: 12, expYear: 2028, + brand: 'Visa', }, }); @@ -2599,6 +2601,7 @@ describe('Customer Details', () => { countryCode: 'US', expMonth: 12, expYear: 2028, + brand: 'Visa', }, }); @@ -2633,6 +2636,7 @@ describe('Customer Details', () => { countryCode: 'US', expMonth: 12, expYear: 2028, + brand: 'Visa', }, }); @@ -2689,6 +2693,7 @@ describe('Customer Details', () => { countryCode: 'US', expMonth: 12, expYear: 2028, + brand: 'Visa', }, }); diff --git a/static/gsApp/components/creditCardEdit/panel.tsx b/static/gsApp/components/creditCardEdit/panel.tsx index 666ca7ced1f9f2..2a535c7f7e535a 100644 --- a/static/gsApp/components/creditCardEdit/panel.tsx +++ b/static/gsApp/components/creditCardEdit/panel.tsx @@ -11,6 +11,7 @@ import PanelHeader from 'sentry/components/panels/panelHeader'; import {t} from 'sentry/locale'; import type {Organization} from 'sentry/types/organization'; import {decodeScalar} from 'sentry/utils/queryString'; +import {toTitleCase} from 'sentry/utils/string/toTitleCase'; import {openEditCreditCard} from 'getsentry/actionCreators/modal'; import CreditCardSetup from 'getsentry/components/creditCardEdit/setup'; @@ -188,8 +189,8 @@ function CreditCardPanel({ /> ) : subscription.paymentSource ? ( - {`****${subscription.paymentSource.last4} ${String(subscription.paymentSource.expMonth).padStart(2, '0')}/${String(subscription.paymentSource.expYear).slice(-2)}`} - {`${countryName ? `${countryName} ` : ''} ${subscription.paymentSource.zipCode}`} + {`${toTitleCase(subscription.paymentSource.brand, {allowInnerUpperCase: true})} ****${subscription.paymentSource.last4} ${String(subscription.paymentSource.expMonth).padStart(2, '0')}/${String(subscription.paymentSource.expYear).slice(-2)}`} + {`${countryName ? `${countryName} ` : ''} ${subscription.paymentSource.zipCode ? subscription.paymentSource.zipCode : ''}`} ) : ( {t('No payment method on file')} diff --git a/static/gsApp/types/index.tsx b/static/gsApp/types/index.tsx index 03fca9888578b6..5a22e78ab6e53d 100644 --- a/static/gsApp/types/index.tsx +++ b/static/gsApp/types/index.tsx @@ -378,11 +378,12 @@ export type Subscription = { onDemandSpendUsed: number; partner: Partner | null; paymentSource: { - countryCode: string; + brand: string; + countryCode: string | null; expMonth: number; expYear: number; last4: string; - zipCode: string; + zipCode: string | null; } | null; pendingChanges: PendingChanges | null; // Subscription details diff --git a/static/gsApp/views/amCheckout/steps/addPaymentMethod.spec.tsx b/static/gsApp/views/amCheckout/steps/addPaymentMethod.spec.tsx index 1b1ea187e53293..aef270958bfb47 100644 --- a/static/gsApp/views/amCheckout/steps/addPaymentMethod.spec.tsx +++ b/static/gsApp/views/amCheckout/steps/addPaymentMethod.spec.tsx @@ -109,6 +109,7 @@ describe('AddPaymentMethod', () => { countryCode: 'US', expMonth: 12, expYear: 2028, + brand: 'Visa', }, }; @@ -141,6 +142,7 @@ describe('AddPaymentMethod', () => { countryCode: 'US', expMonth: 12, expYear: 2028, + brand: 'Visa', }, }; diff --git a/static/gsApp/views/subscriptionPage/billingInformation.spec.tsx b/static/gsApp/views/subscriptionPage/billingInformation.spec.tsx index 236227e5217293..1f993ca666c8e5 100644 --- a/static/gsApp/views/subscriptionPage/billingInformation.spec.tsx +++ b/static/gsApp/views/subscriptionPage/billingInformation.spec.tsx @@ -627,6 +627,7 @@ describe('Billing details form', () => { zipCode: '94242', expMonth: 8, expYear: 2030, + brand: 'Visa', }, }); diff --git a/static/gsApp/views/subscriptionPage/headerCards/billingInfoCard.spec.tsx b/static/gsApp/views/subscriptionPage/headerCards/billingInfoCard.spec.tsx index 17592c93e43b68..98bdf46a30c968 100644 --- a/static/gsApp/views/subscriptionPage/headerCards/billingInfoCard.spec.tsx +++ b/static/gsApp/views/subscriptionPage/headerCards/billingInfoCard.spec.tsx @@ -23,13 +23,14 @@ describe('BillingInfoCard', () => { method: 'GET', body: BillingDetailsFixture(), }); - const subscription = SubscriptionFixture({organization}); + const subscription = SubscriptionFixture({organization, accountBalance: 10_00}); render(); expect(screen.getByText('Billing information')).toBeInTheDocument(); await screen.findByText('Test company, Display Address'); expect(screen.getByText('Billing email: test@gmail.com')).toBeInTheDocument(); - expect(screen.getByText('Card ending in 4242')).toBeInTheDocument(); + expect(screen.getByText('Visa ending in 4242')).toBeInTheDocument(); + expect(screen.getByText('Account balance: $10')).toBeInTheDocument(); }); it('renders with some pre-existing info', async () => { @@ -38,7 +39,7 @@ describe('BillingInfoCard', () => { method: 'GET', body: BillingDetailsFixture({billingEmail: null, companyName: null}), }); - const subscription = SubscriptionFixture({organization}); + const subscription = SubscriptionFixture({organization, accountBalance: -10_00}); render(); expect(screen.getByText('Billing information')).toBeInTheDocument(); @@ -48,7 +49,8 @@ describe('BillingInfoCard', () => { expect( screen.getByText('No billing email or tax number on file') ).toBeInTheDocument(); - expect(screen.getByText('Card ending in 4242')).toBeInTheDocument(); + expect(screen.getByText('Visa ending in 4242')).toBeInTheDocument(); + expect(screen.getByText('Account balance: $10 credit')).toBeInTheDocument(); }); it('renders without pre-existing info', async () => { diff --git a/static/gsApp/views/subscriptionPage/headerCards/billingInfoCard.tsx b/static/gsApp/views/subscriptionPage/headerCards/billingInfoCard.tsx index 5b69b833d99ed3..6307c996a2c0b6 100644 --- a/static/gsApp/views/subscriptionPage/headerCards/billingInfoCard.tsx +++ b/static/gsApp/views/subscriptionPage/headerCards/billingInfoCard.tsx @@ -4,12 +4,14 @@ import {Text} from 'sentry/components/core/text'; import Placeholder from 'sentry/components/placeholder'; import {t, tct} from 'sentry/locale'; import type {Organization} from 'sentry/types/organization'; +import {toTitleCase} from 'sentry/utils/string/toTitleCase'; import {useNavContext} from 'sentry/views/nav/context'; import {NavLayout} from 'sentry/views/nav/types'; import {useBillingDetails} from 'getsentry/hooks/useBillingDetails'; import type {Subscription} from 'getsentry/types'; import {hasSomeBillingDetails} from 'getsentry/utils/billing'; +import formatCurrency from 'getsentry/utils/formatCurrency'; import {countryHasSalesTax, getTaxFieldInfo} from 'getsentry/utils/salesTax'; import SubscriptionHeaderCard from 'getsentry/views/subscriptionPage/headerCards/subscriptionHeaderCard'; @@ -33,7 +35,7 @@ function BillingInfoCard({ align="start" maxWidth="100%" > - + , + {!!subscription.accountBalance && ( + + {tct('Account balance: [balance]', { + balance, + })} + + )} {primaryDetails.length > 0 ? primaryDetails.join(', ') @@ -129,7 +145,8 @@ function PaymentSourceInfo({subscription}: {subscription: Subscription}) { return ( - {tct('Card ending in [last4]', { + {tct('[cardBrand] ending in [last4]', { + cardBrand: toTitleCase(paymentSource.brand, {allowInnerUpperCase: true}), last4: paymentSource.last4, })} diff --git a/tests/js/getsentry-test/fixtures/subscription.ts b/tests/js/getsentry-test/fixtures/subscription.ts index cbf630ec141e24..9d3584bf245f3a 100644 --- a/tests/js/getsentry-test/fixtures/subscription.ts +++ b/tests/js/getsentry-test/fixtures/subscription.ts @@ -97,6 +97,7 @@ export function SubscriptionFixture(props: Props): TSubscription { zipCode: '94242', expMonth: 12, expYear: 2077, + brand: 'Visa', }, billingPeriodEnd: '2018-10-24', onDemandSpendUsed: 0,