useSubscriptionTracking
Access subscription tracking methods to monitor subscription lifecycle events.
function useSubscriptionTracking(): {
trackSubscriptionStarted: (properties: SubscriptionProperties) => void;
trackSubscriptionUpgraded: (properties: SubscriptionProperties & { previous_plan?: string }) => void;
trackSubscriptionDowngraded: (properties: SubscriptionProperties & { previous_plan?: string }) => void;
trackSubscriptionCanceled: (properties: SubscriptionProperties & { cancellation_reason?: string }) => void;
trackSubscriptionPaused: (properties: SubscriptionProperties) => void;
trackSubscriptionReactivated: (properties: SubscriptionProperties) => void;
trackTrialStarted: (properties: SubscriptionProperties) => void;
trackTrialConverted: (properties: SubscriptionProperties) => void;
trackTrialExpired: (properties: SubscriptionProperties) => void;
trackPaymentFailed: (properties: PaymentEventProperties) => void;
trackPaymentSucceeded: (properties: PaymentEventProperties) => void;
getSubscriptionData: () => SubscriptionProperties | null;
}
Return Values
Track when a user starts a new subscription
trackSubscriptionUpgraded
Track when a user upgrades their subscription plan
trackSubscriptionDowngraded
Track when a user downgrades their subscription plan
trackSubscriptionCanceled
Track when a user cancels their subscription
Track when a subscription is paused
trackSubscriptionReactivated
Track when a canceled or paused subscription is reactivated
Track when a user starts a trial period
Track when a trial converts to a paid subscription
Track when a trial expires without conversion
Track failed payment attempts
Track successful payment events
Retrieve current subscription data from storageReturns SubscriptionProperties | null
Usage Example
import { useSubscriptionTracking } from "mentiq-sdk";
function SubscriptionManager() {
const {
trackSubscriptionStarted,
trackSubscriptionUpgraded,
trackSubscriptionCanceled,
trackPaymentSucceeded,
getSubscriptionData,
} = useSubscriptionTracking();
const handleUpgrade = async (newPlan: string) => {
const currentSub = getSubscriptionData();
trackSubscriptionUpgraded({
status: "active",
plan_id: newPlan,
plan_name: "Pro",
plan_tier: "pro",
mrr: 4900, // $49.00 in cents
currency: "usd",
billing_interval: "month",
previous_plan: currentSub?.plan_name,
});
};
const handleCancellation = (reason: string) => {
trackSubscriptionCanceled({
status: "canceled",
plan_id: "pro_monthly",
cancel_at_period_end: true,
cancellation_reason: reason,
canceled_at: new Date().toISOString(),
});
};
return (
<div>
<button onClick={() => handleUpgrade("pro_monthly")}>
Upgrade to Pro
</button>
<button onClick={() => handleCancellation("Too expensive")}>
Cancel Subscription
</button>
</div>
);
}
useChurnRisk
Monitor customer churn risk in real-time with automatic refresh and callback triggers.
function useChurnRisk(options?: {
refreshInterval?: number;
onHighRisk?: (risk: ChurnRiskMetrics) => void;
onCriticalRisk?: (risk: ChurnRiskMetrics) => void;
}): {
churnRisk: ChurnRiskMetrics | null;
isLoading: boolean;
isHighRisk: boolean;
isCriticalRisk: boolean;
refresh: () => ChurnRiskMetrics | null;
}
Parameters
Return Values
Current churn risk metrics including score, category, and contributing factors
Whether churn risk calculation is in progress
True if risk category is “high” or “critical”
True if risk category is “critical”
Manually trigger churn risk recalculation. Returns updated ChurnRiskMetrics | null
Usage Example
import { useChurnRisk } from "mentiq-sdk";
import { useState } from "react";
function ChurnDashboard() {
const [showIntervention, setShowIntervention] = useState(false);
const { churnRisk, isLoading, isHighRisk, isCriticalRisk, refresh } = useChurnRisk({
refreshInterval: 30000, // Check every 30 seconds
onHighRisk: (risk) => {
console.log("High churn risk detected:", risk);
setShowIntervention(true);
},
onCriticalRisk: (risk) => {
// Send alert to customer success team
sendAlertToCSTeam(risk);
},
});
if (isLoading) return <div>Calculating churn risk...</div>;
return (
<div>
<h2>Churn Risk Monitor</h2>
{churnRisk && (
<div>
<div className={`risk-badge ${churnRisk.risk_category}`}>
{churnRisk.risk_category.toUpperCase()} RISK
</div>
<p>Risk Score: {churnRisk.risk_score}/100</p>
<p>Days Since Active: {churnRisk.factors.days_since_last_active}</p>
<p>Engagement Score: {churnRisk.factors.engagement_score}</p>
{churnRisk.intervention_recommended && (
<button onClick={() => setShowIntervention(true)}>
Start Intervention
</button>
)}
</div>
)}
<button onClick={refresh}>Refresh Now</button>
</div>
);
}
useSubscriptionData
Access current subscription data with automatic refresh and convenience flags.
function useSubscriptionData(): {
subscription: SubscriptionProperties | null;
isLoading: boolean;
isPaidUser: boolean;
isTrialing: boolean;
isCanceled: boolean;
willCancelAtPeriodEnd: boolean;
refresh: () => void;
}
Return Values
subscription
SubscriptionProperties | null
Whether subscription data is being loaded
True if subscription status is “active” or “trialing”
True if subscription status is “trialing”
True if subscription status is “canceled”
True if subscription is set to cancel at end of current billing period
Manually refresh subscription data from storage
Usage Example
import { useSubscriptionData } from "mentiq-sdk";
function SubscriptionStatus() {
const {
subscription,
isLoading,
isPaidUser,
isTrialing,
willCancelAtPeriodEnd,
refresh,
} = useSubscriptionData();
if (isLoading) return <div>Loading subscription...</div>;
if (!subscription) {
return <div>No active subscription</div>;
}
return (
<div>
<h2>Your Subscription</h2>
<p>Plan: {subscription.plan_name}</p>
<p>Status: {subscription.status}</p>
{isPaidUser && <span className="badge">Paid User</span>}
{isTrialing && (
<p>Trial ends: {new Date(subscription.trial_end!).toLocaleDateString()}</p>
)}
{willCancelAtPeriodEnd && (
<div className="alert">
Your subscription will cancel on{" "}
{new Date(subscription.current_period_end!).toLocaleDateString()}
</div>
)}
<button onClick={refresh}>Refresh Status</button>
</div>
);
}
useSubscriptionAutoDetect
Manually trigger subscription auto-detection from common payment providers.
function useSubscriptionAutoDetect(): {
detect: () => Promise<{
detected: boolean;
provider?: string;
confidence: number;
} | null>;
isDetecting: boolean;
result: {
detected: boolean;
provider?: string;
confidence: number;
} | null;
}
Return Values
Trigger subscription detection. Returns a promise with detection results:
Whether auto-detection is currently running
Last detection result, or null if detection hasn’t run
Usage Example
import { useSubscriptionAutoDetect } from "mentiq-sdk";
import { useEffect } from "react";
function SubscriptionDetector() {
const { detect, isDetecting, result } = useSubscriptionAutoDetect();
useEffect(() => {
// Auto-detect on component mount
detect();
}, []);
const handleManualDetect = async () => {
const detection = await detect();
if (detection?.detected) {
console.log(`Subscription detected from ${detection.provider}`);
console.log(`Confidence: ${detection.confidence * 100}%`);
} else {
console.log("No subscription detected");
}
};
return (
<div>
<button onClick={handleManualDetect} disabled={isDetecting}>
{isDetecting ? "Detecting..." : "Detect Subscription"}
</button>
{result && (
<div>
{result.detected ? (
<p>
Detected {result.provider} subscription
({Math.round(result.confidence * 100)}% confidence)
</p>
) : (
<p>No subscription detected</p>
)}
</div>
)}
</div>
);
}
useSyncSubscription
Automatically sync subscription state changes and track lifecycle events.
function useSyncSubscription(
subscription: SubscriptionProperties | null | undefined,
options?: {
trackChanges?: boolean;
}
): void
Parameters
Behavior
This hook automatically:
- Stores subscription data in localStorage
- Compares with previous subscription state
- Tracks appropriate events when changes are detected:
- Upgrade: When MRR increases or plan changes to higher tier
- Downgrade: When MRR decreases or plan changes to lower tier
- Cancellation: When status changes to “canceled”
- Reactivation: When status changes from “canceled” to “active”
- Trial Conversion: When status changes from “trialing” to “active”
Usage Example
import { useSyncSubscription } from "mentiq-sdk";
import { useSubscription } from "@/hooks/useSubscription"; // Your custom hook
function App() {
// Get subscription from your database or payment provider
const { data: subscription } = useSubscription();
// Automatically sync and track changes
useSyncSubscription(subscription, {
trackChanges: true, // Enable automatic event tracking
});
return <div>Your app content</div>;
}
Example with Stripe
import { useSyncSubscription } from "mentiq-sdk";
import { useStripeSubscription } from "@/hooks/stripe";
function StripeIntegration() {
const { subscription: stripeSubscription } = useStripeSubscription();
// Transform Stripe subscription to SubscriptionProperties
const subscription = stripeSubscription ? {
status: stripeSubscription.status,
plan_id: stripeSubscription.items.data[0].price.id,
plan_name: stripeSubscription.items.data[0].price.nickname,
mrr: stripeSubscription.items.data[0].price.unit_amount,
currency: stripeSubscription.currency,
billing_interval: stripeSubscription.items.data[0].price.recurring.interval,
current_period_start: new Date(stripeSubscription.current_period_start * 1000).toISOString(),
current_period_end: new Date(stripeSubscription.current_period_end * 1000).toISOString(),
cancel_at_period_end: stripeSubscription.cancel_at_period_end,
provider: "stripe" as const,
provider_subscription_id: stripeSubscription.id,
provider_customer_id: stripeSubscription.customer,
} : null;
// Sync with Mentiq Analytics
useSyncSubscription(subscription, { trackChanges: true });
return <div>Stripe subscription synced</div>;
}
Type Definitions
SubscriptionProperties
interface SubscriptionProperties {
// Status & Plan
status: "active" | "trialing" | "past_due" | "canceled" | "paused" | "incomplete" | "incomplete_expired" | "unpaid";
plan_id?: string;
plan_name?: string;
plan_tier?: string;
// Pricing (in cents)
mrr?: number; // Monthly Recurring Revenue
arr?: number; // Annual Recurring Revenue
ltv?: number; // Lifetime Value
currency?: string;
// Billing Cycle
billing_interval?: "day" | "week" | "month" | "year";
billing_cycle_anchor?: string; // ISO date
current_period_start?: string; // ISO date
current_period_end?: string; // ISO date
// Trial
trial_start?: string; // ISO date
trial_end?: string; // ISO date
is_trial?: boolean;
// Payment (PCI-safe)
payment_method_type?: string;
payment_method_last4?: string;
payment_method_brand?: string;
// Cancellation
cancel_at_period_end?: boolean;
canceled_at?: string; // ISO date
cancellation_reason?: string;
// Provider
provider?: "stripe" | "paddle" | "chargebee" | "manual" | string;
provider_customer_id?: string;
provider_subscription_id?: string;
// Metadata
created_at?: string; // ISO date
updated_at?: string; // ISO date
// Custom fields
[key: string]: string | number | boolean | null | undefined;
}
PaymentEventProperties
interface PaymentEventProperties {
amount?: number;
currency?: string;
payment_status?: "succeeded" | "failed" | "pending" | "refunded";
failure_reason?: string;
invoice_id?: string;
charge_id?: string;
[key: string]: string | number | boolean | null | undefined;
}
ChurnRiskMetrics
interface ChurnRiskMetrics {
risk_score: number; // 0-100
risk_category: "low" | "medium" | "high" | "critical";
factors: {
engagement_score?: number;
days_since_last_active?: number;
feature_adoption_rate?: number;
support_tickets?: number;
negative_feedback_count?: number;
payment_failures?: number;
};
predicted_churn_date?: string; // ISO date
intervention_recommended?: boolean;
}