// src/hooks/useSubscriptionEvents.js // 订阅和支付事件追踪 Hook import { useCallback } from 'react'; import { usePostHogTrack } from './usePostHogRedux'; import { RETENTION_EVENTS, REVENUE_EVENTS } from '../lib/constants'; import { logger } from '../utils/logger'; /** * 订阅和支付事件追踪 Hook * @param {Object} options - 配置选项 * @param {Object} options.currentSubscription - 当前订阅信息 * @returns {Object} 事件追踪处理函数集合 */ export const useSubscriptionEvents = ({ currentSubscription = null } = {}) => { const { track } = usePostHogTrack(); /** * 追踪付费墙展示 * @param {string} feature - 被限制的功能名称 * @param {string} requiredPlan - 需要的订阅计划 * @param {string} triggerLocation - 触发位置 */ const trackPaywallShown = useCallback((feature, requiredPlan = 'pro', triggerLocation = '') => { if (!feature) { logger.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(), }); logger.debug('useSubscriptionEvents', '🚧 Paywall Shown', { feature, requiredPlan, triggerLocation, }); }, [track, currentSubscription]); /** * 追踪付费墙关闭 * @param {string} feature - 功能名称 * @param {string} closeMethod - 关闭方式 ('dismiss' | 'upgrade_clicked' | 'back_button') */ const trackPaywallDismissed = useCallback((feature, closeMethod = 'dismiss') => { if (!feature) { logger.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(), }); logger.debug('useSubscriptionEvents', '❌ Paywall Dismissed', { feature, closeMethod, }); }, [track, currentSubscription]); /** * 追踪升级按钮点击 * @param {string} targetPlan - 目标订阅计划 * @param {string} source - 来源位置 * @param {string} feature - 关联的功能(如果从付费墙点击) */ const trackUpgradePlanClicked = useCallback((targetPlan = 'pro', source = '', feature = '') => { track(REVENUE_EVENTS.PAYWALL_UPGRADE_CLICKED, { current_plan: currentSubscription?.plan || 'free', target_plan: targetPlan, source, feature: feature || null, timestamp: new Date().toISOString(), }); logger.debug('useSubscriptionEvents', '⬆️ Upgrade Plan Clicked', { currentPlan: currentSubscription?.plan, targetPlan, source, feature, }); }, [track, currentSubscription]); /** * 追踪订阅页面查看 * @param {string} source - 来源 */ const trackSubscriptionPageViewed = useCallback((source = '') => { 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(), }); logger.debug('useSubscriptionEvents', '💳 Subscription Page Viewed', { currentPlan: currentSubscription?.plan, source, }); }, [track, currentSubscription]); /** * 追踪定价计划查看 * @param {string} planName - 计划名称 ('free' | 'pro' | 'enterprise') * @param {number} price - 价格 */ const trackPricingPlanViewed = useCallback((planName, price = 0) => { if (!planName) { logger.warn('useSubscriptionEvents', 'trackPricingPlanViewed: planName is required'); return; } track('Pricing Plan Viewed', { plan_name: planName, price, current_plan: currentSubscription?.plan || 'free', timestamp: new Date().toISOString(), }); logger.debug('useSubscriptionEvents', '👀 Pricing Plan Viewed', { planName, price, }); }, [track, currentSubscription]); /** * 追踪定价计划选择 * @param {string} planName - 选择的计划名称 * @param {string} billingCycle - 计费周期 ('monthly' | 'yearly') * @param {number} price - 价格 */ const trackPricingPlanSelected = useCallback((planName, billingCycle = 'monthly', price = 0) => { if (!planName) { logger.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(), }); logger.debug('useSubscriptionEvents', '✅ Pricing Plan Selected', { planName, billingCycle, price, }); }, [track, currentSubscription]); /** * 追踪支付页面查看 * @param {string} planName - 购买的计划 * @param {number} amount - 支付金额 */ const trackPaymentPageViewed = useCallback((planName, amount = 0) => { track(REVENUE_EVENTS.PAYMENT_PAGE_VIEWED, { plan_name: planName, amount, current_plan: currentSubscription?.plan || 'free', timestamp: new Date().toISOString(), }); logger.debug('useSubscriptionEvents', '💰 Payment Page Viewed', { planName, amount, }); }, [track, currentSubscription]); /** * 追踪支付方式选择 * @param {string} paymentMethod - 支付方式 ('wechat_pay' | 'alipay' | 'credit_card') * @param {number} amount - 支付金额 */ const trackPaymentMethodSelected = useCallback((paymentMethod, amount = 0) => { if (!paymentMethod) { logger.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(), }); logger.debug('useSubscriptionEvents', '💳 Payment Method Selected', { paymentMethod, amount, }); }, [track, currentSubscription]); /** * 追踪支付发起 * @param {Object} paymentInfo - 支付信息 * @param {string} paymentInfo.planName - 计划名称 * @param {string} paymentInfo.paymentMethod - 支付方式 * @param {number} paymentInfo.amount - 金额 * @param {string} paymentInfo.billingCycle - 计费周期 * @param {string} paymentInfo.orderId - 订单ID */ const trackPaymentInitiated = useCallback((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(), }); logger.debug('useSubscriptionEvents', '🚀 Payment Initiated', { planName: paymentInfo.planName, amount: paymentInfo.amount, paymentMethod: paymentInfo.paymentMethod, }); }, [track, currentSubscription]); /** * 追踪支付成功 * @param {Object} paymentInfo - 支付信息 */ const trackPaymentSuccessful = useCallback((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(), }); logger.debug('useSubscriptionEvents', '✅ Payment Successful', { planName: paymentInfo.planName, amount: paymentInfo.amount, orderId: paymentInfo.orderId, }); }, [track, currentSubscription]); /** * 追踪支付失败 * @param {Object} paymentInfo - 支付信息 * @param {string} errorReason - 失败原因 */ const trackPaymentFailed = useCallback((paymentInfo = {}, errorReason = '') => { 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(), }); logger.debug('useSubscriptionEvents', '❌ Payment Failed', { planName: paymentInfo.planName, errorReason, orderId: paymentInfo.orderId, }); }, [track, currentSubscription]); /** * 追踪订阅创建成功 * @param {Object} subscription - 订阅信息 */ const trackSubscriptionCreated = useCallback((subscription = {}) => { 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(), }); logger.debug('useSubscriptionEvents', '🎉 Subscription Created', { plan: subscription.plan, billingCycle: subscription.billingCycle, }); }, [track, currentSubscription]); /** * 追踪订阅续费 * @param {Object} subscription - 订阅信息 */ const trackSubscriptionRenewed = useCallback((subscription = {}) => { 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(), }); logger.debug('useSubscriptionEvents', '🔄 Subscription Renewed', { plan: subscription.plan, amount: subscription.amount, }); }, [track]); /** * 追踪订阅取消 * @param {string} reason - 取消原因 * @param {boolean} cancelImmediately - 是否立即取消 */ const trackSubscriptionCancelled = useCallback((reason = '', cancelImmediately = false) => { track(REVENUE_EVENTS.SUBSCRIPTION_CANCELLED, { plan_name: currentSubscription?.plan, reason, has_reason: Boolean(reason), cancel_immediately: cancelImmediately, timestamp: new Date().toISOString(), }); logger.debug('useSubscriptionEvents', '🚫 Subscription Cancelled', { plan: currentSubscription?.plan, reason, cancelImmediately, }); }, [track, currentSubscription]); /** * 追踪优惠券应用 * @param {string} couponCode - 优惠券代码 * @param {number} discountAmount - 折扣金额 * @param {boolean} success - 是否成功 */ const trackCouponApplied = useCallback((couponCode, discountAmount = 0, success = true) => { if (!couponCode) { logger.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(), }); logger.debug('useSubscriptionEvents', success ? '🎟️ Coupon Applied' : '❌ Coupon Failed', { couponCode, discountAmount, success, }); }, [track, currentSubscription]); return { // 付费墙事件 trackPaywallShown, trackPaywallDismissed, trackUpgradePlanClicked, // 订阅页面事件 trackSubscriptionPageViewed, trackPricingPlanViewed, trackPricingPlanSelected, // 支付流程事件 trackPaymentPageViewed, trackPaymentMethodSelected, trackPaymentInitiated, trackPaymentSuccessful, trackPaymentFailed, // 订阅管理事件 trackSubscriptionCreated, trackSubscriptionRenewed, trackSubscriptionCancelled, // 优惠券事件 trackCouponApplied, }; }; export default useSubscriptionEvents;