Skip to content

Commit e8358ee

Browse files
Merge pull request #20177 from mozilla/PAY-3566-location-cant-be-set
fix(payments-next): Location can't be set to Denmark, Poland and Czech Republic on the "Set up your subscription" page for Mozilla VPN monthly subscription (Stage only)
2 parents 74aa759 + c6a88c8 commit e8358ee

10 files changed

Lines changed: 71 additions & 28 deletions

File tree

apps/payments/next/app/[locale]/[offeringId]/[interval]/checkout/[cartId]/layout.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ export default async function CheckoutLayout({
130130
countryCode,
131131
postalCode,
132132
},
133-
session?.user?.id
133+
session?.user?.id,
134+
params.interval
134135
);
135136

136137
if (result.ok) {

apps/payments/next/app/[locale]/[offeringId]/[interval]/location/page.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export default async function Location({
5757
try {
5858
const [cmsData, validateLocationResults] = await Promise.all([
5959
fetchCMSData(params.offeringId, acceptLanguage, params.locale),
60-
validateLocationAction(params.offeringId, taxAddress, fxaUid),
60+
validateLocationAction(params.offeringId, taxAddress, fxaUid, params.interval),
6161
]);
6262
cms = cmsData;
6363
locationStatus = validateLocationResults.status;
@@ -117,7 +117,8 @@ export default async function Location({
117117
)}
118118
</Banner>
119119
) : locationStatus === LocationStatus.ProductNotAvailable ||
120-
locationStatus === TaxChangeAllowedStatus.CurrencyNotFound ? (
120+
locationStatus === TaxChangeAllowedStatus.CurrencyNotFound ||
121+
locationStatus === TaxChangeAllowedStatus.PriceCurrencyNotAvailable ? (
121122
<Banner variant={BannerVariant.Error} showCloseButton={true}>
122123
{l10n.getString(
123124
'select-tax-location-product-not-available',
@@ -160,20 +161,18 @@ export default async function Location({
160161
saveAction={async (countryCode: string, postalCode: string) => {
161162
'use server';
162163

163-
if (fxaUid) {
164-
// call server Action here to validate if tax location change is allowed
165-
const result = await validateLocationAction(
166-
params.offeringId,
167-
{ countryCode, postalCode },
168-
fxaUid
169-
);
164+
const result = await validateLocationAction(
165+
params.offeringId,
166+
{ countryCode, postalCode },
167+
fxaUid,
168+
params.interval
169+
);
170170

171-
if (!result.isValid) {
172-
return {
173-
ok: false,
174-
error: result.status,
175-
};
176-
}
171+
if (!result.isValid) {
172+
return {
173+
ok: false,
174+
error: result.status,
175+
};
177176
}
178177

179178
searchParams['countryCode'] = countryCode;

apps/payments/next/app/[locale]/[offeringId]/[interval]/new/page.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ export default async function New({
7979
const { isValid: locationIsValid } = await validateLocationAction(
8080
offeringId,
8181
taxAddress,
82-
fxaUid
82+
fxaUid,
83+
interval
8384
);
8485

8586
if (!taxAddress || !locationIsValid) {

libs/payments/cart/src/lib/tax.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
export enum TaxChangeAllowedStatus {
66
CurrencyNotFound = 'currency_not_found',
77
CurrencyChange = 'currency_change',
8+
PriceCurrencyNotAvailable = 'price_currency_not_available',
89
Allowed = 'allowed',
910
}

libs/payments/ui/src/lib/actions/updateTaxAddress.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export const updateTaxAddressAction = async (
1414
version: number,
1515
offeringId: string,
1616
taxAddress: TaxAddress,
17-
uid?: string
17+
uid?: string,
18+
interval?: string
1819
) => {
1920
const actionsService = getApp().getActionsService();
2021

@@ -24,6 +25,7 @@ export const updateTaxAddressAction = async (
2425
offeringId,
2526
taxAddress,
2627
uid,
28+
interval,
2729
});
2830

2931
revalidatePath(

libs/payments/ui/src/lib/actions/validateLocation.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import { getApp } from '../nestapp/app';
99
export const validateLocationAction = async (
1010
offeringId: string,
1111
taxAddress?: TaxAddress,
12-
uid?: string
12+
uid?: string,
13+
interval?: string
1314
) => {
1415
return await getApp()
1516
.getActionsService()
16-
.validateLocation({ offeringId, taxAddress, uid });
17+
.validateLocation({ offeringId, taxAddress, uid, interval });
1718
};

libs/payments/ui/src/lib/client/components/SelectTaxLocation/index.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import spinnerWhiteImage from '@fxa/shared/assets/images/spinnerwhite.svg';
1818

1919
enum SaveActionErrors {
2020
CURRENCY_CHANGE_NOT_ALLOWED = 'currency_change', //TaxChangeAllowedStatus.CurrencyChange
21+
PRICE_CURRENCY_NOT_AVAILABLE = 'price_currency_not_available', //TaxChangeAllowedStatus.PriceCurrencyNotAvailable
2122
}
2223

2324
type SaveActionSignature = (
@@ -220,6 +221,13 @@ const Expanded = ({
220221
...prev,
221222
invalidCurrencyChange: true,
222223
}));
224+
} else if (
225+
result.error === SaveActionErrors.PRICE_CURRENCY_NOT_AVAILABLE
226+
) {
227+
setServerErrors((prev) => ({
228+
...prev,
229+
productNotAvailable: true,
230+
}));
223231
} else {
224232
setServerErrors((prev) => ({
225233
...prev,

libs/payments/ui/src/lib/nestapp/nextjs-actions.service.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,7 @@ export class NextJSActionsService {
941941
offeringId: string;
942942
taxAddress: TaxAddress;
943943
uid?: string;
944+
interval?: string;
944945
}): Promise<
945946
| {
946947
ok: true;
@@ -951,13 +952,14 @@ export class NextJSActionsService {
951952
error: string;
952953
}
953954
> {
954-
const { cartId, version, offeringId, taxAddress, uid } = args;
955+
const { cartId, version, offeringId, taxAddress, uid, interval } = args;
955956

956957
// Validate Tax Address before updating
957958
const { isValid, status } = await this.validateLocation({
958959
offeringId,
959960
taxAddress,
960961
uid,
962+
interval,
961963
});
962964
if (!isValid) {
963965
return {
@@ -1009,6 +1011,7 @@ export class NextJSActionsService {
10091011
offeringId: string;
10101012
taxAddress?: TaxAddress;
10111013
uid?: string;
1014+
interval?: string;
10121015
}) {
10131016
const { status: locationStatus } =
10141017
await this.eligibilityService.getProductAvailabilityForLocation(
@@ -1020,17 +1023,36 @@ export class NextJSActionsService {
10201023
if (args.uid && args.taxAddress) {
10211024
const { status: taxChangeStatus, currentCurrency } =
10221025
await this.taxService.getTaxChangeStatus(args.uid, args.taxAddress);
1023-
return {
1024-
isValid: taxChangeStatus === TaxChangeAllowedStatus.Allowed,
1025-
status: taxChangeStatus,
1026-
currentCurrency,
1027-
};
1028-
} else {
1026+
if (taxChangeStatus !== TaxChangeAllowedStatus.Allowed) {
1027+
return {
1028+
isValid: false,
1029+
status: taxChangeStatus,
1030+
currentCurrency,
1031+
};
1032+
}
1033+
}
1034+
if (args.interval && args.taxAddress?.countryCode) {
1035+
const currency = this.currencyManager.getCurrencyForCountry(
1036+
args.taxAddress.countryCode
1037+
);
1038+
if (currency) {
1039+
const price =
1040+
await this.productConfigurationManager.retrieveStripePrice(
1041+
args.offeringId,
1042+
args.interval as SubplatInterval
1043+
);
1044+
if (price && !price.currency_options?.[currency]) {
1045+
return {
1046+
isValid: false,
1047+
status: TaxChangeAllowedStatus.PriceCurrencyNotAvailable,
1048+
};
1049+
}
1050+
}
1051+
}
10291052
return {
10301053
isValid: true,
10311054
status: locationStatus,
10321055
};
1033-
}
10341056
} else {
10351057
return {
10361058
isValid: false,

libs/payments/ui/src/lib/nestapp/validators/UpdateTaxAddressActionArgs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@ export class UpdateTaxAddressActionArgs {
2828
@IsOptional()
2929
@IsString()
3030
uid?: string;
31+
32+
@IsOptional()
33+
@IsString()
34+
interval?: string;
3135
}

libs/payments/ui/src/lib/nestapp/validators/ValidateLocationActionArgs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@ export class ValidateLocationActionArgs {
1515
@IsString()
1616
@IsOptional()
1717
uid?: string;
18+
19+
@IsString()
20+
@IsOptional()
21+
interval?: string;
1822
}

0 commit comments

Comments
 (0)