Skip to content

Commit dd4dd5d

Browse files
committed
feat(payments): Add warning message when payment method is about to expire
1 parent 804f433 commit dd4dd5d

File tree

5 files changed

+195
-183
lines changed

5 files changed

+195
-183
lines changed

apps/payments/next/app/[locale]/subscriptions/manage/page.tsx

Lines changed: 109 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5+
import classNames from 'classnames';
56
import { headers } from 'next/headers';
67
import Image from 'next/image';
78
import Link from 'next/link';
@@ -57,17 +58,10 @@ export default async function Manage({
5758
appleIapSubscriptions,
5859
googleIapSubscriptions,
5960
} = await getSubManPageContentAction(session.user?.id);
60-
const {
61-
billingAgreementId,
62-
brand,
63-
expMonth,
64-
expYear,
65-
last4,
66-
type,
67-
walletType,
68-
} = defaultPaymentMethod || {};
61+
const { billingAgreementId, brand, expMonth, expYear, last4, type } =
62+
defaultPaymentMethod || {};
6963
const isPaypalBillingAgreementError =
70-
type === 'external_paypal' && brand === 'paypal' && !billingAgreementId;
64+
type === 'external_paypal' && !billingAgreementId;
7165
const expirationDate =
7266
expMonth && expYear
7367
? l10n.getLocalizedMonthYearString(expMonth, expYear, locale)
@@ -270,7 +264,9 @@ export default async function Manage({
270264
aria-hidden="true"
271265
></div>
272266
<div
273-
className={`w-full flex flex-col gap-2 tablet:flex-row ${(type === 'card' && brand && !walletType) || isPaypalBillingAgreementError ? 'tablet:items-start' : 'tablet:items-center'}`}
267+
className={classNames(
268+
`w-full flex flex-col gap-2 tablet:flex-row ${brand || isPaypalBillingAgreementError ? 'tablet:items-start' : 'tablet:items-center'}`
269+
)}
274270
>
275271
<h3 className="tablet:min-w-[160px]">
276272
{l10n.getString(
@@ -305,170 +301,125 @@ export default async function Manage({
305301
</div>
306302
)}
307303

308-
{type === 'card' && walletType && (
309-
<div className="w-full flex items-center justify-between">
310-
<Image
311-
src={
312-
getCardIcon(
313-
walletType === 'apple_pay'
314-
? 'apple_pay'
315-
: 'google_pay',
316-
l10n
317-
).img
318-
}
319-
alt={
320-
walletType === 'apple_pay'
321-
? l10n.getString(
322-
'apple-pay-logo-alt-text',
323-
'Apple Pay logo'
324-
)
325-
: l10n.getString(
326-
'google-pay-logo-alt-text',
327-
'Google Pay logo'
328-
)
304+
{type && (
305+
<div
306+
className={classNames(
307+
'w-full flex justify-between gap-3',
308+
{
309+
'flex-row':
310+
!brand && !isPaypalBillingAgreementError,
311+
'flex-row items-center':
312+
!isPaypalBillingAgreementError,
313+
'flex-col items-start tablet:flex-row':
314+
isPaypalBillingAgreementError,
315+
'leading-6 items-start tablet:flex-row tablet:justify-between':
316+
brand,
329317
}
330-
width={45}
331-
height={24}
332-
/>
333-
<Link
334-
className="bg-grey-10 border border-grey-200 box-border font-bold font-header inline-block rounded text-center py-2 px-5 w-auto"
335-
href={`${config.paymentsNextHostedUrl}/${locale}/subscriptions/payments/stripe`}
336-
aria-label={l10n.getString(
337-
'subscription-management-button-manage-payment-method-aria',
338-
'Manage payment method'
339-
)}
340-
>
341-
{l10n.getString(
342-
'subscription-management-button-manage-payment-method',
343-
'Manage'
344-
)}
345-
</Link>
346-
</div>
347-
)}
348-
349-
{type === 'card' && brand && !walletType && (
350-
<div className="w-full flex flex-col leading-6 tablet:flex-row tablet:items-center tablet:justify-between">
351-
<div>
352-
<div className="flex items-center gap-2">
353-
<Image
354-
src={getCardIcon(brand, l10n).img}
355-
alt={getCardIcon(brand, l10n).altText}
356-
width={32}
357-
height={20}
358-
/>
359-
{last4 && (
360-
<span className="font-bold">
361-
{l10n.getString(
362-
'subscription-management-card-ending-in',
363-
{ last4 },
364-
`Card ending in ${last4}`
318+
)}
319+
>
320+
<div className="flex flex-col">
321+
{brand ? (
322+
<div>
323+
<div className="flex items-center gap-2">
324+
<Image
325+
src={getCardIcon(brand, l10n).img}
326+
alt={getCardIcon(brand, l10n).altText}
327+
width={getCardIcon(brand, l10n).width}
328+
height={getCardIcon(brand, l10n).height}
329+
/>
330+
{last4 && (
331+
<span className="font-bold">
332+
{l10n.getString(
333+
'subscription-management-card-ending-in',
334+
{ last4 },
335+
`Card ending in ${last4}`
336+
)}
337+
</span>
365338
)}
366-
</span>
367-
)}
368-
</div>
369-
{expirationDate && (
370-
<p className="pt-1 pb-2 tablet:pb-0 text-sm">
371-
{l10n.getString(
372-
'subscription-management-card-expires-date',
373-
{ expirationDate },
374-
`Expires ${expirationDate}`
339+
</div>
340+
{expirationDate && (
341+
<p className="pt-1 tablet:pb-0 text-sm">
342+
{l10n.getString(
343+
'subscription-management-card-expires-date',
344+
{ expirationDate },
345+
`Expires ${expirationDate}`
346+
)}
347+
</p>
375348
)}
376-
</p>
377-
)}
378-
</div>
379-
<Link
380-
className="bg-grey-10 border border-grey-200 box-border font-bold font-header inline-block rounded text-center w-full py-2 px-5 tablet:w-auto"
381-
href={`${config.paymentsNextHostedUrl}/${locale}/subscriptions/payments/stripe`}
382-
aria-label={l10n.getString(
383-
'subscription-management-button-manage-payment-method-aria',
384-
'Manage payment method'
385-
)}
386-
>
387-
{l10n.getString(
388-
'subscription-management-button-manage-payment-method',
389-
'Manage'
390-
)}
391-
</Link>
392-
</div>
393-
)}
394-
395-
{type === 'link' && (
396-
<div className="w-full flex items-center justify-between">
397-
<Image
398-
src={getCardIcon('link', l10n).img}
399-
alt={l10n.getString(
400-
'link-logo-alt-text',
401-
'Link logo'
402-
)}
403-
width={72}
404-
height={24}
405-
/>
406-
<Link
407-
className="bg-grey-10 border border-grey-200 box-border font-bold font-header inline-block rounded text-center py-2 px-5 w-auto"
408-
href={`${config.paymentsNextHostedUrl}/${locale}/subscriptions/payments/stripe`}
409-
aria-label={l10n.getString(
410-
'subscription-management-button-manage-payment-method-aria',
411-
'Manage payment method'
412-
)}
413-
>
414-
{l10n.getString(
415-
'subscription-management-button-manage-payment-method',
416-
'Manage'
349+
</div>
350+
) : (
351+
<Image
352+
src={getCardIcon(type, l10n).img}
353+
alt={getCardIcon(type, l10n).altText}
354+
width={getCardIcon(type, l10n).width}
355+
height={getCardIcon(type, l10n).height}
356+
/>
417357
)}
418-
</Link>
419-
</div>
420-
)}
421-
422-
{type === 'external_paypal' && (
423-
<div
424-
className={`w-full flex ${isPaypalBillingAgreementError ? 'flex-col items-start tablet:flex-row' : 'items-center'} justify-between gap-4`}
425-
>
426-
<div className="leading-6">
427-
<Image
428-
src={getCardIcon('paypal', l10n).img}
429-
alt={l10n.getString(
430-
'paypal-logo-alt-text',
431-
'PayPal logo'
432-
)}
433-
width={91}
434-
height={24}
435-
/>
436358
{isPaypalBillingAgreementError && (
437-
<p className="pt-3 text-red-700">
359+
<p className="leading-6 pt-3 text-red-700">
438360
{l10n.getString(
439361
'subscription-management-error-paypal-billing-agreement',
440362
'There is an issue with your PayPal account. Please resolve the issue to maintain your active subscriptions.'
441363
)}
442364
</p>
443365
)}
444366
</div>
445-
<div
446-
className={`${isPaypalBillingAgreementError && 'flex tablet:justify-end w-full tablet:w-auto'}`}
447-
>
448-
<LinkExternal
449-
className={
450-
isPaypalBillingAgreementError
451-
? `flex items-center justify-center bg-blue-500 border border-blue-600 box-border font-bold font-header rounded text-center py-2 px-5 tablet:w-auto text-white w-full h-10`
452-
: 'bg-grey-10 border border-grey-200 box-border font-bold font-header inline-block rounded text-center py-2 px-5 w-auto'
453-
}
454-
href={
455-
isPaypalBillingAgreementError
456-
? `${config.paymentsNextHostedUrl}/${locale}/subscriptions/payments/paypal`
457-
: `${config.csp.paypalApi}/myaccount/autopay/connect/${billingAgreementId}`
458-
}
367+
368+
{type === 'external_paypal' ? (
369+
<div
370+
className={`${isPaypalBillingAgreementError && 'flex tablet:justify-end w-full tablet:w-auto'}`}
371+
>
372+
<LinkExternal
373+
className={classNames(
374+
'border box-border font-bold font-header rounded text-center py-2 px-5',
375+
{
376+
'flex items-center justify-center bg-blue-500 border-blue-600 tablet:w-auto text-white w-full h-10':
377+
isPaypalBillingAgreementError,
378+
'inline-block bg-grey-10 border-grey-200 w-auto':
379+
!isPaypalBillingAgreementError,
380+
}
381+
)}
382+
href={
383+
isPaypalBillingAgreementError
384+
? `${config.paymentsNextHostedUrl}/${locale}/subscriptions/payments/paypal`
385+
: `${config.csp.paypalApi}/myaccount/autopay/connect/${billingAgreementId}`
386+
}
387+
aria-label={l10n.getString(
388+
'subscription-management-button-manage-payment-method-aria',
389+
'Manage payment method'
390+
)}
391+
>
392+
<span>
393+
{l10n.getString(
394+
'subscription-management-button-manage-payment-method',
395+
'Manage'
396+
)}
397+
</span>
398+
</LinkExternal>
399+
</div>
400+
) : (
401+
<Link
402+
className={classNames(
403+
'border box-border font-bold font-header inline-block rounded text-center py-2 px-5 tablet:w-auto',
404+
{
405+
'bg-grey-10 border-grey-200 w-auto':
406+
!brand && !isPaypalBillingAgreementError,
407+
'bg-blue-500 border-blue-600 text-white w-full':
408+
isPaypalBillingAgreementError,
409+
}
410+
)}
411+
href={`${config.paymentsNextHostedUrl}/${locale}/subscriptions/payments/stripe`}
459412
aria-label={l10n.getString(
460413
'subscription-management-button-manage-payment-method-aria',
461414
'Manage payment method'
462415
)}
463416
>
464-
<span>
465-
{l10n.getString(
466-
'subscription-management-button-manage-payment-method',
467-
'Manage'
468-
)}
469-
</span>
470-
</LinkExternal>
471-
</div>
417+
{l10n.getString(
418+
'subscription-management-button-manage-payment-method',
419+
'Manage'
420+
)}
421+
</Link>
422+
)}
472423
</div>
473424
)}
474425
</div>

0 commit comments

Comments
 (0)