diff --git a/src/locales/en.json b/src/locales/en.json index 2eb78e2..d98e720 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -320,6 +320,10 @@ "title": "Choose a plan to continue", "description": "Your trial period is ending soon. Select a plan to continue using VPN without restrictions." }, + "expired": { + "title": "Subscription expired", + "selectTariff": "Your subscription has expired. Choose a plan below to restore access to VPN." + }, "connection": { "title": "Connect VPN", "selectDevice": "Select your device", diff --git a/src/locales/ru.json b/src/locales/ru.json index 22beb2b..d0acebb 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -342,6 +342,10 @@ "title": "Выберите тариф для продолжения", "description": "Ваш пробный период скоро закончится. Выберите подходящий тариф, чтобы продолжить пользоваться VPN без ограничений." }, + "expired": { + "title": "Подписка истекла", + "selectTariff": "Ваша подписка истекла. Выберите тариф ниже, чтобы возобновить доступ к VPN." + }, "connection": { "title": "Подключить VPN", "selectDevice": "Выберите устройство", diff --git a/src/pages/Subscription.tsx b/src/pages/Subscription.tsx index 402de39..e5b1891 100644 --- a/src/pages/Subscription.tsx +++ b/src/pages/Subscription.tsx @@ -312,6 +312,28 @@ export default function Subscription() { queryClient.invalidateQueries({ queryKey: ['purchase-options'] }); setSwitchTariffId(null); }, + onError: (error: unknown) => { + // Handle subscription_expired error - redirect to purchase flow + if (error instanceof AxiosError) { + const detail = error.response?.data?.detail; + if ( + typeof detail === 'object' && + detail?.error_code === 'subscription_expired' && + detail?.use_purchase_flow === true + ) { + // Find the tariff user was trying to switch to and open purchase form + const targetTariff = tariffs.find((t) => t.id === switchTariffId); + if (targetTariff) { + setSwitchTariffId(null); + setSelectedTariff(targetTariff); + setSelectedTariffPeriod(targetTariff.periods[0] || null); + setShowTariffPurchase(true); + // Refetch purchase-options to get updated expired status + queryClient.invalidateQueries({ queryKey: ['purchase-options'] }); + } + } + } + }, }); // Tariff purchase mutation @@ -1955,6 +1977,40 @@ export default function Subscription() { )} + {/* Expired subscription notice - prompt to purchase new tariff */} + {isTariffsMode && + purchaseOptions && + 'subscription_is_expired' in purchaseOptions && + purchaseOptions.subscription_is_expired && ( +