Payments & Subscriptions
Learn how to manage monetization, add new products, and protect premium features using the built-in RevenueCat integration.
VibeFast includes a production-ready monetization system powered by RevenueCat. The system is built using an adapter pattern, making it easy to manage and even swap out the underlying service in the future.
Overview
- Adapter Pattern: All payment logic is handled through the
RevenueCatAdapter
located atsrc/features/payments/services/revenuecat-adapter.ts
. Your app code should interact with this adapter, not directly with the RevenueCat SDK. - Automatic Initialization: The
<PaymentInitializer />
component insrc/features/payments/components/payment-initializer.tsx
is already added to the root layout. It automatically initializes the SDK and syncs the user's authentication state with RevenueCat. - Paywall UI: The starter includes examples for both a custom-built local paywall (
local-paywall.tsx
) and an implementation of RevenueCat's pre-built UI (remote-paywall.tsx
).
How-To: Protect a Feature with an Entitlement
The most common task is to restrict access to a feature unless the user has an active subscription. This is made simple with the useEntitlement
hook.
1. Define Your Entitlement in RevenueCat
First, create an "Entitlement" in your RevenueCat dashboard (e.g., premium_access
). Assign one or more products (like your monthly or annual subscription) to this entitlement.
2. Use the useEntitlement
Hook
In your component, use the hook to check if the user has the required entitlement.
import { useEntitlement } from '@/features/payments';
import { PaywallScreen } from '@/features/payments/app/paywall-screen'; // Example paywall
export const PremiumFeature = () => {
// Use the entitlement identifier from your RevenueCat dashboard.
const { isEntitled, isLoading } = useEntitlement('premium_access');
// Show a loading state while checking the entitlement.
if (isLoading) {
return <ActivityIndicator />;
}
// If the user is not entitled, show the paywall.
if (!isEntitled) {
return <PaywallScreen />;
}
// If the user is entitled, show the premium content.
return <PremiumContent />;
};
How-To: Add a New Product to the Paywall
Adding a new subscription or one-time purchase involves two main steps.
1. Configure the Product in RevenueCat
Create the new product (e.g., "Pro Lifetime") in the Apple App Store Connect and Google Play Console, then add it to an Offering in your RevenueCat dashboard.
2. Update the Paywall UI
The PaywallLocalMode
component in src/features/payments/components/paywall-local-mode.tsx
automatically fetches and displays all products from your "current" offering in RevenueCat. No code changes are needed unless you want to customize the UI for the new product.
Handling Consumable Purchases (Credits)
The starter kit is also configured to handle consumable products, like credit packs.
- The Flow: When a consumable product is purchased, the
purchaseProduct
method in theRevenueCatAdapter
detects it (based on the product ID containing "credits") and calls a Convex mutation. - The Backend: The
recordConsumablePurchase
mutation inconvex/paymentFunctions.ts
is responsible for updating the user'scredits
balance in the database.
Customizing Credit Amounts
You can easily adjust how many credits are granted for each purchase by modifying the logic inside the recordConsumablePurchase
mutation in convex/paymentFunctions.ts
.