Subscriptions and feature gates
Sell recurring plans, unlock features, and handle plan changes.
Use a subscription product when a user should keep access while a recurring
plan is active. The app normally checks access with FeatureGate,
useFeature(), or the server client.
Create a subscription product
In the neonFin dashboard, create a product with type Subscription. Give it a clear credit unit even if the plan is mostly about feature access.
Attach the product to Stripe or Polar so neonFin can create provider checkout sessions and receive webhooks.
Add one price per tier
Each recurring price is a tier. For example:
Product: Pro tools
- Basic $9/mo -> feature: analytics
- Pro $19/mo -> features: analytics, exportAttach feature slugs to each tier. Use stable lowercase slugs like analytics,
export, or priority-support.
Decide whether the tier includes credits
If the tier includes credits each cycle, set creditsGranted on the price.
Then choose the product renewal mode:
- Refresh: top the balance up to the included amount each cycle.
- Add: add the included amount each cycle.
Use Refresh for normal allowances. Use Add only when unused credits should accumulate.
Gate the feature in your app
Use FeatureGate when you want to hide UI until the wallet has access:
import { FeatureGate } from "@/components/neonfin/feature-gate";
export function AnalyticsPanel() {
return (
<FeatureGate feature="analytics">
<AnalyticsDashboard />
</FeatureGate>
);
}Use useFeature() when you need the boolean:
const { enabled, loading } = useFeature("analytics");Send plan changes to the billing portal
A second checkout should not change an existing subscription. It would create a second subscription at the provider.
The default PurchaseDialog detects an active subscription and shows
Manage subscription. That opens the Stripe or Polar portal, where the
provider handles plan changes, proration, and cancellation.
What happens after purchase
When the provider sends the payment webhook, neonFin:
- marks the order as paid
- creates or updates the wallet
- stores the provider customer id on the wallet
- records the active subscription
- applies included credits for the paid cycle
Feature access is derived from active subscriptions, paid one-time purchases, and manual grants. There is no separate feature flag to keep in sync.
Cancellation behavior
When a customer cancels in the provider portal, access continues until the provider reports that the subscription has actually ended. At that point neonFin marks the subscription canceled, and subscription-derived features stop showing up in the wallet.
Credits already granted for a paid period are not clawed back on cancellation. Full refunds are handled separately; see Handle refunds.