383 lines
11 KiB
TypeScript
383 lines
11 KiB
TypeScript
// src/hooks/useSubscriptionEvents.ts
|
|
// 订阅和支付事件追踪 Hook
|
|
|
|
import { useCallback } from 'react';
|
|
import { usePostHogTrack } from './usePostHogRedux';
|
|
import { RETENTION_EVENTS, REVENUE_EVENTS } from '../lib/constants';
|
|
|
|
/**
|
|
* 当前订阅信息
|
|
*/
|
|
interface SubscriptionInfo {
|
|
plan?: string;
|
|
status?: string;
|
|
}
|
|
|
|
/**
|
|
* useSubscriptionEvents Hook 配置选项
|
|
*/
|
|
interface UseSubscriptionEventsOptions {
|
|
currentSubscription?: SubscriptionInfo | null;
|
|
}
|
|
|
|
/**
|
|
* 支付信息
|
|
*/
|
|
interface PaymentInfo {
|
|
planName?: string;
|
|
paymentMethod?: string;
|
|
amount?: number;
|
|
billingCycle?: string;
|
|
orderId?: string;
|
|
transactionId?: string;
|
|
}
|
|
|
|
/**
|
|
* 订阅信息
|
|
*/
|
|
interface SubscriptionData {
|
|
plan?: string;
|
|
billingCycle?: string;
|
|
amount?: number;
|
|
startDate?: string;
|
|
endDate?: string;
|
|
previousEndDate?: string;
|
|
newEndDate?: string;
|
|
}
|
|
|
|
/**
|
|
* useSubscriptionEvents Hook 返回值
|
|
*/
|
|
interface UseSubscriptionEventsReturn {
|
|
trackPaywallShown: (feature: string, requiredPlan?: string, triggerLocation?: string) => void;
|
|
trackPaywallDismissed: (feature: string, closeMethod?: string) => void;
|
|
trackUpgradePlanClicked: (targetPlan?: string, source?: string, feature?: string) => void;
|
|
trackSubscriptionPageViewed: (source?: string) => void;
|
|
trackPricingPlanViewed: (planName: string, price?: number) => void;
|
|
trackPricingPlanSelected: (planName: string, billingCycle?: string, price?: number) => void;
|
|
trackPaymentPageViewed: (planName: string, amount?: number) => void;
|
|
trackPaymentMethodSelected: (paymentMethod: string, amount?: number) => void;
|
|
trackPaymentInitiated: (paymentInfo?: PaymentInfo) => void;
|
|
trackPaymentSuccessful: (paymentInfo?: PaymentInfo) => void;
|
|
trackPaymentFailed: (paymentInfo?: PaymentInfo, errorReason?: string) => void;
|
|
trackSubscriptionCreated: (subscription?: SubscriptionData) => void;
|
|
trackSubscriptionRenewed: (subscription?: SubscriptionData) => void;
|
|
trackSubscriptionCancelled: (reason?: string, cancelImmediately?: boolean) => void;
|
|
trackCouponApplied: (couponCode: string, discountAmount?: number, success?: boolean) => void;
|
|
}
|
|
|
|
/**
|
|
* 订阅和支付事件追踪 Hook
|
|
* @param options - 配置选项
|
|
* @returns 事件追踪处理函数集合
|
|
*/
|
|
export const useSubscriptionEvents = ({
|
|
currentSubscription = null,
|
|
}: UseSubscriptionEventsOptions = {}): UseSubscriptionEventsReturn => {
|
|
const { track } = usePostHogTrack();
|
|
|
|
/**
|
|
* 追踪付费墙展示
|
|
*/
|
|
const trackPaywallShown = useCallback(
|
|
(feature: string, requiredPlan: string = 'pro', triggerLocation: string = '') => {
|
|
if (!feature) {
|
|
console.warn('useSubscriptionEvents: trackPaywallShown - feature is required');
|
|
return;
|
|
}
|
|
|
|
track(REVENUE_EVENTS.PAYWALL_SHOWN, {
|
|
feature,
|
|
required_plan: requiredPlan,
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
trigger_location: triggerLocation,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪付费墙关闭
|
|
*/
|
|
const trackPaywallDismissed = useCallback(
|
|
(feature: string, closeMethod: string = 'dismiss') => {
|
|
if (!feature) {
|
|
console.warn('useSubscriptionEvents: trackPaywallDismissed - feature is required');
|
|
return;
|
|
}
|
|
|
|
track(REVENUE_EVENTS.PAYWALL_DISMISSED, {
|
|
feature,
|
|
close_method: closeMethod,
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪升级按钮点击
|
|
*/
|
|
const trackUpgradePlanClicked = useCallback(
|
|
(targetPlan: string = 'pro', source: string = '', feature: string = '') => {
|
|
track(REVENUE_EVENTS.PAYWALL_UPGRADE_CLICKED, {
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
target_plan: targetPlan,
|
|
source,
|
|
feature: feature || null,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪订阅页面查看
|
|
*/
|
|
const trackSubscriptionPageViewed = useCallback(
|
|
(source: string = '') => {
|
|
track(RETENTION_EVENTS.SUBSCRIPTION_PAGE_VIEWED, {
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
subscription_status: currentSubscription?.status || 'unknown',
|
|
is_paid_user: currentSubscription?.plan && currentSubscription.plan !== 'free',
|
|
source,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪定价计划查看
|
|
*/
|
|
const trackPricingPlanViewed = useCallback(
|
|
(planName: string, price: number = 0) => {
|
|
if (!planName) {
|
|
console.warn('useSubscriptionEvents: trackPricingPlanViewed - planName is required');
|
|
return;
|
|
}
|
|
|
|
track('Pricing Plan Viewed', {
|
|
plan_name: planName,
|
|
price,
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪定价计划选择
|
|
*/
|
|
const trackPricingPlanSelected = useCallback(
|
|
(planName: string, billingCycle: string = 'monthly', price: number = 0) => {
|
|
if (!planName) {
|
|
console.warn('useSubscriptionEvents: trackPricingPlanSelected - planName is required');
|
|
return;
|
|
}
|
|
|
|
track('Pricing Plan Selected', {
|
|
plan_name: planName,
|
|
billing_cycle: billingCycle,
|
|
price,
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪支付页面查看
|
|
*/
|
|
const trackPaymentPageViewed = useCallback(
|
|
(planName: string, amount: number = 0) => {
|
|
track(REVENUE_EVENTS.PAYMENT_PAGE_VIEWED, {
|
|
plan_name: planName,
|
|
amount,
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪支付方式选择
|
|
*/
|
|
const trackPaymentMethodSelected = useCallback(
|
|
(paymentMethod: string, amount: number = 0) => {
|
|
if (!paymentMethod) {
|
|
console.warn('useSubscriptionEvents: trackPaymentMethodSelected - paymentMethod is required');
|
|
return;
|
|
}
|
|
|
|
track(REVENUE_EVENTS.PAYMENT_METHOD_SELECTED, {
|
|
payment_method: paymentMethod,
|
|
amount,
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪支付发起
|
|
*/
|
|
const trackPaymentInitiated = useCallback(
|
|
(paymentInfo: PaymentInfo = {}) => {
|
|
track(REVENUE_EVENTS.PAYMENT_INITIATED, {
|
|
plan_name: paymentInfo.planName,
|
|
payment_method: paymentInfo.paymentMethod,
|
|
amount: paymentInfo.amount,
|
|
billing_cycle: paymentInfo.billingCycle,
|
|
order_id: paymentInfo.orderId,
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪支付成功
|
|
*/
|
|
const trackPaymentSuccessful = useCallback(
|
|
(paymentInfo: PaymentInfo = {}) => {
|
|
track(REVENUE_EVENTS.PAYMENT_SUCCESSFUL, {
|
|
plan_name: paymentInfo.planName,
|
|
payment_method: paymentInfo.paymentMethod,
|
|
amount: paymentInfo.amount,
|
|
billing_cycle: paymentInfo.billingCycle,
|
|
order_id: paymentInfo.orderId,
|
|
transaction_id: paymentInfo.transactionId,
|
|
previous_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪支付失败
|
|
*/
|
|
const trackPaymentFailed = useCallback(
|
|
(paymentInfo: PaymentInfo = {}, errorReason: string = '') => {
|
|
track(REVENUE_EVENTS.PAYMENT_FAILED, {
|
|
plan_name: paymentInfo.planName,
|
|
payment_method: paymentInfo.paymentMethod,
|
|
amount: paymentInfo.amount,
|
|
error_reason: errorReason,
|
|
order_id: paymentInfo.orderId,
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪订阅创建成功
|
|
*/
|
|
const trackSubscriptionCreated = useCallback(
|
|
(subscription: SubscriptionData = {}) => {
|
|
track(REVENUE_EVENTS.SUBSCRIPTION_CREATED, {
|
|
plan_name: subscription.plan,
|
|
billing_cycle: subscription.billingCycle,
|
|
amount: subscription.amount,
|
|
start_date: subscription.startDate,
|
|
end_date: subscription.endDate,
|
|
previous_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪订阅续费
|
|
*/
|
|
const trackSubscriptionRenewed = useCallback(
|
|
(subscription: SubscriptionData = {}) => {
|
|
track(REVENUE_EVENTS.SUBSCRIPTION_RENEWED, {
|
|
plan_name: subscription.plan,
|
|
amount: subscription.amount,
|
|
previous_end_date: subscription.previousEndDate,
|
|
new_end_date: subscription.newEndDate,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track]
|
|
);
|
|
|
|
/**
|
|
* 追踪订阅取消
|
|
*/
|
|
const trackSubscriptionCancelled = useCallback(
|
|
(reason: string = '', cancelImmediately: boolean = false) => {
|
|
track(REVENUE_EVENTS.SUBSCRIPTION_CANCELLED, {
|
|
plan_name: currentSubscription?.plan,
|
|
reason,
|
|
has_reason: Boolean(reason),
|
|
cancel_immediately: cancelImmediately,
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
/**
|
|
* 追踪优惠券应用
|
|
*/
|
|
const trackCouponApplied = useCallback(
|
|
(couponCode: string, discountAmount: number = 0, success: boolean = true) => {
|
|
if (!couponCode) {
|
|
console.warn('useSubscriptionEvents: trackCouponApplied - couponCode is required');
|
|
return;
|
|
}
|
|
|
|
track('Coupon Applied', {
|
|
coupon_code: couponCode,
|
|
discount_amount: discountAmount,
|
|
success,
|
|
current_plan: currentSubscription?.plan || 'free',
|
|
timestamp: new Date().toISOString(),
|
|
});
|
|
},
|
|
[track, currentSubscription]
|
|
);
|
|
|
|
return {
|
|
// 付费墙事件
|
|
trackPaywallShown,
|
|
trackPaywallDismissed,
|
|
trackUpgradePlanClicked,
|
|
|
|
// 订阅页面事件
|
|
trackSubscriptionPageViewed,
|
|
trackPricingPlanViewed,
|
|
trackPricingPlanSelected,
|
|
|
|
// 支付流程事件
|
|
trackPaymentPageViewed,
|
|
trackPaymentMethodSelected,
|
|
trackPaymentInitiated,
|
|
trackPaymentSuccessful,
|
|
trackPaymentFailed,
|
|
|
|
// 订阅管理事件
|
|
trackSubscriptionCreated,
|
|
trackSubscriptionRenewed,
|
|
trackSubscriptionCancelled,
|
|
|
|
// 优惠券事件
|
|
trackCouponApplied,
|
|
};
|
|
};
|
|
|
|
export default useSubscriptionEvents;
|