mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
Merge PR #486: fallback на покупку при переключении с бесплатного тарифа
fix(subscription): fall back to purchase flow for free-tariff switches
This commit is contained in:
@@ -137,6 +137,13 @@ export function TariffPickerGrid({
|
|||||||
purchaseOptions &&
|
purchaseOptions &&
|
||||||
'subscription_is_expired' in purchaseOptions &&
|
'subscription_is_expired' in purchaseOptions &&
|
||||||
purchaseOptions.subscription_is_expired === true;
|
purchaseOptions.subscription_is_expired === true;
|
||||||
|
// Free (0₽) source tariff: the backend blocks the prorated switch
|
||||||
|
// (free_tariff_cannot_switch) — offer the purchase flow instead.
|
||||||
|
const isOnFreeTariff =
|
||||||
|
isTariffsMode &&
|
||||||
|
purchaseOptions &&
|
||||||
|
'subscription_on_free_tariff' in purchaseOptions &&
|
||||||
|
purchaseOptions.subscription_on_free_tariff === true;
|
||||||
const canSwitch =
|
const canSwitch =
|
||||||
!isMultiTariff &&
|
!isMultiTariff &&
|
||||||
subscription &&
|
subscription &&
|
||||||
@@ -144,6 +151,7 @@ export function TariffPickerGrid({
|
|||||||
!isCurrentTariff &&
|
!isCurrentTariff &&
|
||||||
!subscription.is_trial &&
|
!subscription.is_trial &&
|
||||||
!isSubscriptionExpired &&
|
!isSubscriptionExpired &&
|
||||||
|
!isOnFreeTariff &&
|
||||||
(subscription.is_active || subscription.is_limited);
|
(subscription.is_active || subscription.is_limited);
|
||||||
const isLegacySubscription =
|
const isLegacySubscription =
|
||||||
subscription && !subscription.is_trial && !subscription.tariff_id;
|
subscription && !subscription.is_trial && !subscription.tariff_id;
|
||||||
|
|||||||
@@ -27,11 +27,13 @@ import type { Tariff } from '../../../types';
|
|||||||
// ──────────────────────────────────────────────────────────────────
|
// ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
// The backend rejects a switch that must instead go through the purchase flow:
|
// The backend rejects a switch that must instead go through the purchase flow:
|
||||||
// the subscription lapsed (`subscription_expired`), or it is a trial that has no
|
// the subscription lapsed (`subscription_expired`), it is a trial that has no
|
||||||
// paid value to prorate and would otherwise be handed a full target period
|
// paid value to prorate and would otherwise be handed a full target period
|
||||||
// (`trial_cannot_switch`, bug #629889). Both arrive as detail.code +
|
// (`trial_cannot_switch`, bug #629889), or it sits on a free 0₽ tariff whose
|
||||||
// use_purchase_flow=true; some payloads use the legacy `error_code` key, so we
|
// spammed/gifted remainder must reset rather than be prorated and carried
|
||||||
// accept either.
|
// (`free_tariff_cannot_switch`, TARIFF_SWITCH_RESET_FREE_DAYS). All arrive as
|
||||||
|
// detail.code + use_purchase_flow=true; some payloads use the legacy
|
||||||
|
// `error_code` key, so we accept either.
|
||||||
function shouldUsePurchaseFlow(error: unknown): boolean {
|
function shouldUsePurchaseFlow(error: unknown): boolean {
|
||||||
if (!(error instanceof AxiosError)) return false;
|
if (!(error instanceof AxiosError)) return false;
|
||||||
const detail = error.response?.data?.detail as
|
const detail = error.response?.data?.detail as
|
||||||
@@ -40,7 +42,9 @@ function shouldUsePurchaseFlow(error: unknown): boolean {
|
|||||||
if (!detail || typeof detail !== 'object') return false;
|
if (!detail || typeof detail !== 'object') return false;
|
||||||
const code = detail.code ?? detail.error_code;
|
const code = detail.code ?? detail.error_code;
|
||||||
return (
|
return (
|
||||||
(code === 'subscription_expired' || code === 'trial_cannot_switch') &&
|
(code === 'subscription_expired' ||
|
||||||
|
code === 'trial_cannot_switch' ||
|
||||||
|
code === 'free_tariff_cannot_switch') &&
|
||||||
detail.use_purchase_flow === true
|
detail.use_purchase_flow === true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -364,6 +364,9 @@ export interface TariffsPurchaseOptions {
|
|||||||
// New fields for expired subscription handling
|
// New fields for expired subscription handling
|
||||||
subscription_status?: string;
|
subscription_status?: string;
|
||||||
subscription_is_expired?: boolean;
|
subscription_is_expired?: boolean;
|
||||||
|
// Free (0₽) source tariff: switch is blocked (free days must reset),
|
||||||
|
// tariff cards must offer the purchase flow instead of the prorated switch
|
||||||
|
subscription_on_free_tariff?: boolean;
|
||||||
has_subscription?: boolean;
|
has_subscription?: boolean;
|
||||||
// Multi-tariff: all available tariffs already purchased
|
// Multi-tariff: all available tariffs already purchased
|
||||||
all_tariffs_purchased?: boolean;
|
all_tariffs_purchased?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user