diff --git a/apps/payments/next/app/[locale]/subscriptions/manage/page.tsx b/apps/payments/next/app/[locale]/subscriptions/manage/page.tsx
index ce8085cf6ad..42ef4162095 100644
--- a/apps/payments/next/app/[locale]/subscriptions/manage/page.tsx
+++ b/apps/payments/next/app/[locale]/subscriptions/manage/page.tsx
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+import classNames from 'classnames';
import { headers } from 'next/headers';
import Image from 'next/image';
import Link from 'next/link';
@@ -57,17 +58,10 @@ export default async function Manage({
appleIapSubscriptions,
googleIapSubscriptions,
} = await getSubManPageContentAction(session.user?.id);
- const {
- billingAgreementId,
- brand,
- expMonth,
- expYear,
- last4,
- type,
- walletType,
- } = defaultPaymentMethod || {};
+ const { billingAgreementId, brand, expMonth, expYear, last4, type } =
+ defaultPaymentMethod || {};
const isPaypalBillingAgreementError =
- type === 'external_paypal' && brand === 'paypal' && !billingAgreementId;
+ type === 'external_paypal' && !billingAgreementId;
const expirationDate =
expMonth && expYear
? l10n.getLocalizedMonthYearString(expMonth, expYear, locale)
@@ -270,7 +264,9 @@ export default async function Manage({
aria-hidden="true"
>
{l10n.getString(
@@ -305,136 +301,62 @@ export default async function Manage({
)}
- {type === 'card' && walletType && (
-
-
-
- {l10n.getString(
- 'subscription-management-button-manage-payment-method',
- 'Manage'
- )}
-
-
- )}
-
- {type === 'card' && brand && !walletType && (
-
-
-
-
- {last4 && (
-
- {l10n.getString(
- 'subscription-management-card-ending-in',
- { last4 },
- `Card ending in ${last4}`
+ )}
+ >
+
+ {brand ? (
+
+
+
+ {last4 && (
+
+ {l10n.getString(
+ 'subscription-management-card-ending-in',
+ { last4 },
+ `Card ending in ${last4}`
+ )}
+
)}
-
- )}
-
- {expirationDate && (
-
- {l10n.getString(
- 'subscription-management-card-expires-date',
- { expirationDate },
- `Expires ${expirationDate}`
+
+ {expirationDate && (
+
+ {l10n.getString(
+ 'subscription-management-card-expires-date',
+ { expirationDate },
+ `Expires ${expirationDate}`
+ )}
+
)}
-
- )}
-
-
- {l10n.getString(
- 'subscription-management-button-manage-payment-method',
- 'Manage'
- )}
-
-
- )}
-
- {type === 'link' && (
-
-
-
- {l10n.getString(
- 'subscription-management-button-manage-payment-method',
- 'Manage'
+
+ ) : (
+
)}
-
-
- )}
-
- {type === 'external_paypal' && (
-
-
-
{isPaypalBillingAgreementError && (
-
+
{l10n.getString(
'subscription-management-error-paypal-billing-agreement',
'There is an issue with your PayPal account. Please resolve the issue to maintain your active subscriptions.'
@@ -442,33 +364,62 @@ export default async function Manage({
)}
-
-
+
+
+ {l10n.getString(
+ 'subscription-management-button-manage-payment-method',
+ 'Manage'
+ )}
+
+
+
+ ) : (
+
-
- {l10n.getString(
- 'subscription-management-button-manage-payment-method',
- 'Manage'
- )}
-
-
-
+ {l10n.getString(
+ 'subscription-management-button-manage-payment-method',
+ 'Manage'
+ )}
+
+ )}
)}
@@ -533,9 +484,9 @@ export default async function Manage({
aria-labelledby={`${sub.productName}-information`}
className="leading-6 pb-4"
>
-
-
-
+
+
+
-
-
-
+
+
+
@@ -747,9 +698,9 @@ export default async function Manage({
aria-labelledby={`${purchase.productName}-heading`}
className="leading-6 pb-4"
>
-
-
-
+
+
+
diff --git a/apps/payments/next/app/[locale]/subscriptions/payments/paypal/page.tsx b/apps/payments/next/app/[locale]/subscriptions/payments/paypal/page.tsx
index d357d55399c..e39f868c060 100644
--- a/apps/payments/next/app/[locale]/subscriptions/payments/paypal/page.tsx
+++ b/apps/payments/next/app/[locale]/subscriptions/payments/paypal/page.tsx
@@ -59,8 +59,8 @@ export default async function PaypalPaymentManagementPage({
'Manage payment methods'
)}
-
-
+
+
{
const mockUid = faker.string.uuid();
jest.spyOn(paymentMethodManager, 'determineType').mockResolvedValue({
- type: SubPlatPaymentMethodType.Stripe,
+ type: SubPlatPaymentMethodType.Card,
paymentMethodId: 'pm_id',
});
jest
@@ -114,7 +112,7 @@ describe('PaymentMethodManager', () => {
mockUid
);
expect(result).toEqual({
- type: mockPaymentMethod.type,
+ type: SubPlatPaymentMethodType.Card,
brand: mockPaymentMethod.card?.brand,
last4: mockPaymentMethod.card?.last4,
expMonth: mockPaymentMethod.card?.exp_month,
@@ -142,26 +140,61 @@ describe('PaymentMethodManager', () => {
mockUid
);
expect(result).toEqual({
- type: 'external_paypal',
+ type: SubPlatPaymentMethodType.PayPal,
brand: 'paypal',
billingAgreementId: mockPaypalBillingAgreementId,
});
});
+
+ it('returns payment method information - apple_pay', async () => {
+ const mockPaymentMethod = StripeResponseFactory(
+ StripePaymentMethodFactory({})
+ );
+ const mockStripeCustomer = StripeCustomerFactory();
+ const mockSubscriptions = [StripeSubscriptionFactory()];
+ const mockUid = faker.string.uuid();
+
+ jest.spyOn(paymentMethodManager, 'determineType').mockResolvedValue({
+ type: SubPlatPaymentMethodType.ApplePay,
+ paymentMethodId: 'pm_id',
+ });
+ jest
+ .spyOn(paymentMethodManager, 'retrieve')
+ .mockResolvedValue(mockPaymentMethod);
+
+ const result = await paymentMethodManager.getDefaultPaymentMethod(
+ mockStripeCustomer,
+ mockSubscriptions,
+ mockUid
+ );
+ expect(result).toEqual({
+ type: SubPlatPaymentMethodType.ApplePay,
+ brand: mockPaymentMethod.card?.brand,
+ last4: mockPaymentMethod.card?.last4,
+ expMonth: mockPaymentMethod.card?.exp_month,
+ expYear: mockPaymentMethod.card?.exp_year,
+ walletType: mockPaymentMethod.card?.wallet?.type,
+ });
+ });
});
describe('determineType', () => {
it('returns card', async () => {
const mockCustomer = StripeCustomerFactory({
invoice_settings: {
- custom_fields: null,
- default_payment_method: 'any',
- footer: null,
- rendering_options: null,
- },
+ custom_fields: null,
+ default_payment_method: 'any',
+ footer: null,
+ rendering_options: null,
+ },
});
- const mockPaymentMethod = StripeResponseFactory(StripeCardPaymentMethodFactory());
- jest.spyOn(paymentMethodManager, 'retrieve').mockResolvedValue(mockPaymentMethod);
+ const mockPaymentMethod = StripeResponseFactory(
+ StripeCardPaymentMethodFactory()
+ );
+ jest
+ .spyOn(paymentMethodManager, 'retrieve')
+ .mockResolvedValue(mockPaymentMethod);
await expect(
paymentMethodManager.determineType(mockCustomer)
@@ -198,7 +231,9 @@ describe('PaymentMethodManager', () => {
type: 'link',
})
);
- jest.spyOn(paymentMethodManager, 'retrieve').mockResolvedValue(mockPaymentMethod);
+ jest
+ .spyOn(paymentMethodManager, 'retrieve')
+ .mockResolvedValue(mockPaymentMethod);
await expect(
paymentMethodManager.determineType(mockCustomer)
@@ -220,10 +255,12 @@ describe('PaymentMethodManager', () => {
const mockPaymentMethod = StripeResponseFactory(
StripeCardPaymentMethodFactory({
- walletType: 'apple_pay'
+ walletType: 'apple_pay',
})
);
- jest.spyOn(paymentMethodManager, 'retrieve').mockResolvedValue(mockPaymentMethod);
+ jest
+ .spyOn(paymentMethodManager, 'retrieve')
+ .mockResolvedValue(mockPaymentMethod);
await expect(
paymentMethodManager.determineType(mockCustomer)
@@ -245,10 +282,12 @@ describe('PaymentMethodManager', () => {
const mockPaymentMethod = StripeResponseFactory(
StripeCardPaymentMethodFactory({
- walletType: 'google_pay'
+ walletType: 'google_pay',
})
);
- jest.spyOn(paymentMethodManager, 'retrieve').mockResolvedValue(mockPaymentMethod);
+ jest
+ .spyOn(paymentMethodManager, 'retrieve')
+ .mockResolvedValue(mockPaymentMethod);
await expect(
paymentMethodManager.determineType(mockCustomer)
diff --git a/libs/payments/customer/src/lib/paymentMethod.manager.ts b/libs/payments/customer/src/lib/paymentMethod.manager.ts
index c0eea5f0701..1cebd7afcf5 100644
--- a/libs/payments/customer/src/lib/paymentMethod.manager.ts
+++ b/libs/payments/customer/src/lib/paymentMethod.manager.ts
@@ -51,12 +51,11 @@ export class PaymentMethodManager {
paymentMethodType.paymentMethodId
);
defaultPaymentMethod = {
- type: paymentMethod.type,
+ type: paymentMethodType.type,
brand: paymentMethod.card?.brand,
last4: paymentMethod.card?.last4,
expMonth: paymentMethod.card?.exp_month,
expYear: paymentMethod.card?.exp_year,
- walletType: paymentMethod.card?.wallet?.type,
};
break;
}
@@ -64,8 +63,7 @@ export class PaymentMethodManager {
const billingAgreementId =
await this.paypalBillingAgreementManager.retrieveActiveId(uid);
defaultPaymentMethod = {
- type: 'external_paypal',
- brand: 'paypal',
+ type: SubPlatPaymentMethodType.PayPal,
billingAgreementId,
};
break;
diff --git a/libs/payments/customer/src/lib/types.ts b/libs/payments/customer/src/lib/types.ts
index 4575c1ba7ed..5d6f8dd3ca8 100644
--- a/libs/payments/customer/src/lib/types.ts
+++ b/libs/payments/customer/src/lib/types.ts
@@ -75,13 +75,12 @@ export type PaymentProvidersType =
| 'external_paypal';
export interface DefaultPaymentMethod {
- type: PaymentProvidersType;
+ type: SubPlatPaymentMethodType;
brand?: string;
last4?: string;
expMonth?: number;
expYear?: number;
billingAgreementId?: string;
- walletType?: string;
}
export interface PricingForCurrency {
diff --git a/libs/payments/ui/src/lib/client/components/PaymentMethodManagement/index.tsx b/libs/payments/ui/src/lib/client/components/PaymentMethodManagement/index.tsx
index 432fafff9d1..d428f3d4060 100644
--- a/libs/payments/ui/src/lib/client/components/PaymentMethodManagement/index.tsx
+++ b/libs/payments/ui/src/lib/client/components/PaymentMethodManagement/index.tsx
@@ -195,7 +195,7 @@ export function PaymentMethodManagement({
'Manage payment methods'
)}
-
+
{!isReady && (
@@ -204,7 +204,7 @@ export function PaymentMethodManagement({
{isInputNewCardDetails && (
<>
diff --git a/libs/payments/ui/src/lib/client/components/SubscriptionContent/index.tsx b/libs/payments/ui/src/lib/client/components/SubscriptionContent/index.tsx
index 27745e04b9e..47acf1cdcfe 100644
--- a/libs/payments/ui/src/lib/client/components/SubscriptionContent/index.tsx
+++ b/libs/payments/ui/src/lib/client/components/SubscriptionContent/index.tsx
@@ -531,7 +531,7 @@ export const SubscriptionContent = ({
{canResubscribe ? (
<>
@@ -562,7 +562,7 @@ export const SubscriptionContent = ({
{nextInvoiceTotal !== undefined && nextInvoiceTotal >= 0 ? (
<>
diff --git a/libs/payments/ui/src/lib/utils/getCardIcon.ts b/libs/payments/ui/src/lib/utils/getCardIcon.ts
index b394313754b..2eac254b8a7 100644
--- a/libs/payments/ui/src/lib/utils/getCardIcon.ts
+++ b/libs/payments/ui/src/lib/utils/getCardIcon.ts
@@ -22,61 +22,86 @@ export function getCardIcon(cardBrand: string, l10n: LocalizerRsc) {
return {
img: Amex,
altText: l10n.getString('amex-logo-alt-text', 'American Express logo'),
+ width: 32,
+ height: 20,
};
case 'apple_pay':
return {
img: ApplePay,
altText: l10n.getString('apple-pay-logo-alt-text', 'Apple Pay logo'),
+ width: 45,
+ height: 24,
};
case 'diners':
return {
img: Diners,
altText: l10n.getString('diners-logo-alt-text', 'Diners logo'),
+ width: 32,
+ height: 20,
};
case 'discover':
return {
img: Discover,
altText: l10n.getString('discover-logo-alt-text', 'Discover logo'),
+ width: 32,
+ height: 20,
};
case 'google_pay':
return {
img: GooglePay,
altText: l10n.getString('google-pay-logo-alt-text', 'Google Pay logo'),
+ width: 45,
+ height: 24,
};
case 'jcb':
return {
img: Jcb,
altText: l10n.getString('jcb-logo-alt-text', 'JCB logo'),
+ width: 32,
+ height: 20,
};
case 'link':
return {
img: Link,
altText: l10n.getString('link-logo-alt-text', 'Link logo'),
- }
+ width: 72,
+ height: 24,
+ };
case 'mastercard':
return {
img: Mastercard,
altText: l10n.getString('mastercard-logo-alt-text', 'Mastercard logo'),
+ width: 32,
+ height: 20,
};
+ case 'external_paypal':
case 'paypal':
return {
img: Paypal,
altText: l10n.getString('paypal-logo-alt-text', 'PayPal logo'),
+ width: 91,
+ height: 24,
};
case 'unionpay':
return {
img: UnionPay,
altText: l10n.getString('unionpay-logo-alt-text', 'Union Pay logo'),
+ width: 32,
+ height: 20,
};
case 'visa':
return {
img: Visa,
altText: l10n.getString('visa-logo-alt-text', 'Visa logo'),
+ width: 32,
+ height: 20,
};
default:
return {
img: Unbranded,
altText: l10n.getString('unbranded-logo-alt-text', 'Unbranded logo'),
+ width: 32,
+ height: 20,
};
}
}