VibeFast
Customizing Features

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 at src/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 in src/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.

src/components/my-premium-feature.tsx
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 the RevenueCatAdapter detects it (based on the product ID containing "credits") and calls a Convex mutation.
  • The Backend: The recordConsumablePurchase mutation in convex/paymentFunctions.ts is responsible for updating the user's credits 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.