This commit is contained in:
Manav Rathi
2024-11-06 12:26:59 +05:30
parent 3a5189e715
commit 900ea0469f
4 changed files with 30 additions and 25 deletions

View File

@@ -63,7 +63,7 @@ import React, {
useState,
} from "react";
import { Trans } from "react-i18next";
import billingService from "services/billingService";
import { redirectToCustomerPortal } from "services/billingService";
import { getUncategorizedCollection } from "services/collectionService";
import exportService from "services/export";
import { getUserDetailsV2 } from "services/userService";
@@ -195,7 +195,7 @@ const UserDetailsSection: React.FC<UserDetailsSectionProps> = ({
hasStripeSubscription(userDetails.subscription) &&
isSubscriptionPastDue(userDetails.subscription)
) {
billingService.redirectToCustomerPortal();
redirectToCustomerPortal();
} else {
galleryContext.showPlanSelectorModal();
}
@@ -271,7 +271,7 @@ const SubscriptionStatus: React.FC<SubscriptionStatusProps> = ({
hasStripeSubscription(userDetails.subscription) &&
isSubscriptionPastDue(userDetails.subscription)
) {
billingService.redirectToCustomerPortal();
redirectToCustomerPortal();
} else {
showPlanSelectorModal();
}

View File

@@ -23,7 +23,7 @@ import { t } from "i18next";
import isElectron from "is-electron";
import { GalleryContext } from "pages/gallery";
import { useContext, useEffect, useRef, useState } from "react";
import billingService from "services/billingService";
import { redirectToCustomerPortal } from "services/billingService";
import { getLatestCollections } from "services/collectionService";
import {
getPublicCollectionUID,
@@ -659,7 +659,7 @@ export default function Uploader({
variant: "critical",
subtext: t("subscription_expired"),
message: t("renew_now"),
onClick: () => billingService.redirectToCustomerPortal(),
onClick: redirectToCustomerPortal,
};
break;
case CustomError.STORAGE_QUOTA_EXCEEDED:

View File

@@ -155,23 +155,6 @@ class billingService {
throw e;
}
}
public async redirectToCustomerPortal() {
try {
const redirectURL = completionRedirectURL();
const response = await HTTPService.get(
await apiURL("/billing/stripe/customer-portal"),
{ redirectURL },
{
"X-Auth-Token": getToken(),
},
);
window.location.href = response.data.url;
} catch (e) {
log.error("unable to get customer portal url", e);
throw e;
}
}
}
export default new billingService();
@@ -214,3 +197,21 @@ const getPaymentToken = async () => {
return z.object({ paymentToken: z.string() }).parse(await res.json())
.paymentToken;
};
/**
* Redirect to the Stripe customer portal / dashboard where the user can view
* details about their subscription and modify their payment method.
*/
export const redirectToCustomerPortal = async () => {
const redirectURL = completionRedirectURL();
const url = await apiURL("/billing/stripe/customer-portal");
const params = new URLSearchParams({ redirectURL });
const res = await fetch(`${url}?${params.toString()}`, {
headers: await authenticatedRequestHeaders(),
});
ensureOk(res);
const data = z
.object({ data: z.object({ url: z.string() }) })
.parse(await res.json()).data;
window.location.href = data.url;
};

View File

@@ -4,10 +4,14 @@ import {
isPartOfFamily,
} from "@/new/photos/services/user";
import { SetDialogBoxAttributes } from "@ente/shared/components/DialogBox/types";
import { LS_KEYS, getData } from "@ente/shared/storage/localStorage";
import { getData, LS_KEYS } from "@ente/shared/storage/localStorage";
import { t } from "i18next";
import type { NextRouter } from "next/router";
import billingService, { Plan, Subscription } from "services/billingService";
import billingService, {
Plan,
redirectToCustomerPortal,
Subscription,
} from "services/billingService";
import { SetLoading } from "types/gallery";
import { BonusData, UserDetails } from "types/user";
import { getSubscriptionPurchaseSuccessMessage } from "utils/ui";
@@ -215,7 +219,7 @@ export async function updatePaymentMethod(
) {
try {
setLoading(true);
await billingService.redirectToCustomerPortal();
await redirectToCustomerPortal();
} catch (error) {
setLoading(false);
setDialogMessage({