-
-
-
-
- No active plan
- π
- No subscription yet
-
- Choose a plan and activate your subscription to unlock all features.
-
-
-
-
-
-
+
U
@@ -5091,14 +4972,6 @@
'app.loading': 'Loading your subscription...',
'error.default.title': 'Subscription Not Found',
'error.default.message': 'Please contact support to activate your subscription.',
- 'state.registration.title': 'Register in the bot',
- 'state.registration.text': 'Start the bot in Telegram to create an account and access the mini app.',
- 'state.registration.button': 'Open bot',
- 'state.no_subscription.badge': 'No active plan',
- 'state.no_subscription.title': 'No subscription yet',
- 'state.no_subscription.text': 'Choose a plan and activate your subscription to unlock all features.',
- 'state.no_subscription.action.purchase': 'Choose a plan',
- 'state.no_subscription.action.topup': 'Top up balance',
'stats.days_left': 'Days left',
'stats.servers': 'Servers',
'stats.devices': 'Devices',
@@ -5454,14 +5327,6 @@
'app.loading': 'ΠΠ°Π³ΡΡΠΆΠ°Π΅ΠΌ Π²Π°ΡΡ ΠΏΠΎΠ΄ΠΏΠΈΡΠΊΡ...',
'error.default.title': 'ΠΠΎΠ΄ΠΏΠΈΡΠΊΠ° Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½Π°',
'error.default.message': 'Π‘Π²ΡΠΆΠΈΡΠ΅ΡΡ Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ, ΡΡΠΎΠ±Ρ Π°ΠΊΡΠΈΠ²ΠΈΡΠΎΠ²Π°ΡΡ ΠΏΠΎΠ΄ΠΏΠΈΡΠΊΡ.',
- 'state.registration.title': 'ΠΠ°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠΉΡΠ΅ΡΡ Π² Π±ΠΎΡΠ΅',
- 'state.registration.text': 'ΠΠ°ΠΏΡΡΡΠΈΡΠ΅ Π±ΠΎΡΠ° Π² Telegram, ΡΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π°ΠΊΠΊΠ°ΡΠ½Ρ ΠΈ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΠΌΠΈΠ½ΠΈ-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.',
- 'state.registration.button': 'ΠΡΠΊΡΡΡΡ Π±ΠΎΡΠ°',
- 'state.no_subscription.badge': 'ΠΠ΅Ρ ΠΏΠΎΠ΄ΠΏΠΈΡΠΊΠΈ',
- 'state.no_subscription.title': 'ΠΠΎΠ΄ΠΏΠΈΡΠΊΠ° Π½Π΅ Π°ΠΊΡΠΈΠ²Π½Π°',
- 'state.no_subscription.text': 'ΠΡΠ±Π΅ΡΠΈΡΠ΅ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡΠΈΠΉ ΡΠ°ΡΠΈΡ ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΠ΅ ΠΏΠΎΠ΄ΠΏΠΈΡΠΊΡ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠ΅ΡΠ²ΠΈΡΠΎΠΌ.',
- 'state.no_subscription.action.purchase': 'ΠΡΠ±ΡΠ°ΡΡ ΡΠ°ΡΠΈΡ',
- 'state.no_subscription.action.topup': 'ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΡ Π±Π°Π»Π°Π½Ρ',
'stats.days_left': 'ΠΡΡΠ°Π»ΠΎΡΡ Π΄Π½Π΅ΠΉ',
'stats.servers': 'Π‘Π΅ΡΠ²Π΅ΡΡ',
'stats.devices': 'Π£ΡΡΡΠΎΠΉΡΡΠ²Π°',
@@ -5915,58 +5780,6 @@
applyKey('app.subtitle', rawServiceDescription);
}
- function buildFallbackUserData(purchaseData) {
- const currency = (purchaseData?.currency || 'RUB').toString().toUpperCase();
- const balanceKopeks = coercePositiveInt(
- purchaseData?.balanceKopeks
- ?? purchaseData?.balance_kopeks
- ?? null,
- 0
- ) || 0;
-
- const telegramUser = tg?.initDataUnsafe?.user || {};
- const username = telegramUser.username ? `@${telegramUser.username}` : null;
- const nameCandidates = [
- [telegramUser.first_name, telegramUser.last_name].filter(Boolean).join(' ').trim() || null,
- telegramUser.first_name || null,
- telegramUser.last_name || null,
- username,
- ].filter(Boolean);
- const fallbackName = nameCandidates[0] || 'User';
-
- return {
- user: {
- display_name: fallbackName,
- username,
- first_name: telegramUser.first_name || null,
- last_name: telegramUser.last_name || null,
- telegram_id: telegramUser.id || null,
- subscription_status: 'disabled',
- subscription_actual_status: 'disabled',
- has_active_subscription: false,
- expires_at: null,
- traffic_used_label: t('values.not_available'),
- traffic_limit_label: t('values.not_available'),
- device_limit: null,
- },
- balance_kopeks: balanceKopeks,
- balance_currency: currency,
- balance_rubles: balanceKopeks / 100,
- subscription_type: 'trial',
- autopay_enabled: false,
- connected_servers: [],
- connected_devices: [],
- connected_devices_count: 0,
- transactions: [],
- promo_offers: [],
- referral: null,
- faq: null,
- legal_documents: null,
- subscription_url: null,
- subscriptionPurchaseUrl: null,
- };
- }
-
let userData = null;
let appsConfig = {};
let currentPlatform = 'android';
@@ -5975,7 +5788,6 @@
let preferredLanguage = 'en';
let languageLockedByUser = false;
let currentErrorState = null;
- let subscriptionViewState = 'loading';
let paymentMethodsCache = null;
let paymentMethodsPromise = null;
let activePaymentMethod = null;
@@ -6022,10 +5834,6 @@
periodId: null,
};
- const urlParams = new URLSearchParams(window.location.search || '');
- const botUsernameRaw = urlParams.get('tgWebAppBotName') || urlParams.get('bot') || '';
- const botUsername = botUsernameRaw ? botUsernameRaw.trim().replace(/^@/, '') : null;
-
const PAYMENT_STATUS_INITIAL_DELAY_MS = 2000;
const PAYMENT_STATUS_POLL_INTERVAL_MS = 5000;
const PAYMENT_STATUS_TIMEOUT_MS = 180000;
@@ -6685,25 +6493,6 @@
}
}
- function setSubscriptionViewState(state) {
- subscriptionViewState = state;
-
- const registrationBlock = document.getElementById('registrationState');
- if (registrationBlock) {
- registrationBlock.classList.toggle('hidden', state !== 'unregistered');
- }
-
- const noSubscriptionBlock = document.getElementById('noSubscriptionState');
- if (noSubscriptionBlock) {
- noSubscriptionBlock.classList.toggle('hidden', state !== 'no-subscription');
- }
-
- const userCard = document.getElementById('userCard');
- if (userCard) {
- userCard.classList.toggle('hidden', state !== 'active');
- }
- }
-
function applyTranslations() {
document.title = t('app.title');
document.documentElement.setAttribute('lang', preferredLanguage);
@@ -6902,7 +6691,6 @@
currentErrorState = null;
updateErrorTexts();
- setSubscriptionViewState('active');
const errorState = document.getElementById('errorState');
if (errorState) {
@@ -6928,83 +6716,6 @@
return userData;
}
- async function handleMissingSubscription(error) {
- if (!error || error.status !== 404) {
- return false;
- }
-
- const initData = tg.initData || '';
- if (!initData) {
- return false;
- }
-
- try {
- const response = await fetch('/miniapp/subscription/purchase/options', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ initData }),
- });
-
- const body = await parseJsonSafe(response);
- if (!response.ok || (body && body.success === false)) {
- const message = extractPurchaseErrorMessage(body, response.status);
- const fallbackError = createError('Subscription purchase error', message, response.status);
- const code = extractErrorCode(body);
- if (code) {
- fallbackError.code = code;
- }
- fallbackError.payload = body;
- throw fallbackError;
- }
-
- const normalized = normalizeSubscriptionPurchasePayload(body);
- if (!normalized) {
- throw createError('Subscription purchase error', t('subscription_purchase.error.default'));
- }
- subscriptionPurchaseData = normalized;
- subscriptionPurchaseError = null;
- subscriptionPurchaseLoading = false;
- subscriptionPurchasePromise = null;
- subscriptionPurchaseFeatureEnabled = true;
- subscriptionPurchasePreview = null;
- subscriptionPurchasePreviewError = null;
- subscriptionPurchasePreviewLoading = false;
- subscriptionPurchasePreviewPromise = null;
- resetSubscriptionPurchaseSelections(normalized);
- renderSubscriptionPurchaseCard();
- requestSubscriptionPurchasePreviewUpdate({ immediate: true });
-
- userData = buildFallbackUserData(normalized);
- currentErrorState = null;
- updateErrorTexts();
-
- setSubscriptionViewState('no-subscription');
- document.getElementById('errorState')?.classList.add('hidden');
- document.getElementById('loadingState')?.classList.add('hidden');
- document.getElementById('mainContent')?.classList.remove('hidden');
-
- renderUserData();
- updateActionButtons();
-
- return true;
- } catch (fallbackError) {
- const code = fallbackError?.code || extractErrorCode(fallbackError?.payload);
- if (fallbackError?.status === 404 || code === 'user_not_found') {
- currentErrorState = null;
- updateErrorTexts();
- setSubscriptionViewState('unregistered');
- document.getElementById('loadingState')?.classList.add('hidden');
- document.getElementById('errorState')?.classList.add('hidden');
- document.getElementById('mainContent')?.classList.add('hidden');
- updateActionButtons();
- return true;
- }
-
- console.warn('Failed to prepare fallback subscription state:', fallbackError);
- return false;
- }
- }
-
async function refreshSubscriptionData(options = {}) {
const { silent = false } = options;
const initData = tg.initData || '';
@@ -7019,16 +6730,8 @@
document.getElementById('loadingState')?.classList.remove('hidden');
}
- try {
- const payload = await fetchSubscriptionPayload(initData);
- return applySubscriptionData(payload);
- } catch (error) {
- const handled = await handleMissingSubscription(error);
- if (handled) {
- return userData;
- }
- throw error;
- }
+ const payload = await fetchSubscriptionPayload(initData);
+ return applySubscriptionData(payload);
}
async function init() {
@@ -7047,10 +6750,7 @@
await refreshSubscriptionData();
} catch (error) {
console.error('Initialization error:', error);
- const handled = await handleMissingSubscription(error);
- if (!handled) {
- showError(error);
- }
+ showError(error);
}
}
@@ -12134,11 +11834,6 @@
return;
}
- if (subscriptionViewState !== 'active') {
- card.classList.add('hidden');
- return;
- }
-
const shouldShow = hasPaidSubscription();
card.classList.toggle('hidden', !shouldShow);
if (!shouldShow) {
@@ -12565,11 +12260,6 @@
return;
}
- if (subscriptionViewState !== 'active') {
- card.classList.add('hidden');
- return;
- }
-
const shouldShow = hasPaidSubscription();
card.classList.toggle('hidden', !shouldShow);
if (!shouldShow) {
@@ -13747,23 +13437,6 @@
return t('subscription_purchase.error.default');
}
- function extractErrorCode(payload) {
- if (!payload || typeof payload !== 'object') {
- return null;
- }
-
- if (typeof payload.code === 'string') {
- return payload.code;
- }
-
- const detail = payload.detail;
- if (detail && typeof detail === 'object' && typeof detail.code === 'string') {
- return detail.code;
- }
-
- return null;
- }
-
function ensureSubscriptionPurchaseData(options = {}) {
const { force = false } = options;
@@ -15585,7 +15258,6 @@
if (copyBtn) {
const hasUrl = Boolean(subscriptionUrl);
copyBtn.disabled = !hasUrl || !navigator.clipboard;
- copyBtn.classList.toggle('hidden', subscriptionViewState !== 'active');
}
}
@@ -15602,7 +15274,6 @@
}
function showError(error) {
- setSubscriptionViewState('loading');
document.getElementById('loadingState').classList.add('hidden');
document.getElementById('mainContent').classList.add('hidden');
currentErrorState = {
@@ -15673,44 +15344,6 @@
}
});
- const openBotBtn = document.getElementById('openBotBtn');
- if (openBotBtn) {
- if (!botUsername) {
- openBotBtn.disabled = true;
- openBotBtn.classList.add('secondary');
- } else {
- openBotBtn.addEventListener('click', () => {
- const link = `https://t.me/${botUsername}`;
- if (typeof tg.openTelegramLink === 'function') {
- try {
- tg.openTelegramLink(link);
- return;
- } catch (openError) {
- console.warn('tg.openTelegramLink failed:', openError);
- }
- }
- openExternalLink(link, { openInMiniApp: true });
- });
- }
- }
-
- document.getElementById('noSubscriptionPurchaseBtn')?.addEventListener('click', event => {
- if (shouldShowPurchaseConfigurator()) {
- event.preventDefault();
- openSubscriptionPurchaseModal();
- return;
- }
- const link = getEffectivePurchaseUrl() || configPurchaseUrl;
- if (!link) {
- return;
- }
- openExternalLink(link, { openInMiniApp: true });
- });
-
- document.getElementById('noSubscriptionTopupBtn')?.addEventListener('click', () => {
- openTopupModal();
- });
-
document.getElementById('referralToggleBtn')?.addEventListener('click', () => {
referralListExpanded = !referralListExpanded;
updateReferralToggleState();