Skip to main content
Full technical details in your project at /docs/modules/Payments.md

What You Get

  • RevenueCat wrapper - Clean abstraction, no RC types leak
  • Reactive state - AsyncStream for subscription changes
  • Purchase flows - Buy, restore, cancel with full error handling
  • Entitlement system - Single “pro” entitlement (expandable)
  • Paywall UI - Beautiful, themeable subscription screen
  • Thread-safe - Multi-subscriber support with state replay
Time saved: 16-24 hours of RevenueCat integration, state management, paywall UI, and testing.

Key Components

PaymentsClient Protocol

PaymentsState

Production Setup (From Real Code)

The app entry point builds a PaymentsConfig from the generated AppConfiguration (produced at build time from Config/Secrets.xcconfig), then hands it to CompositionRoot:
CompositionRoot constructs the client with that config. In DEBUG with AUTH_BYPASS set, it swaps in MockPaymentsClient so the run-with-mocks experience (and UI tests) works fully offline with sample offerings:

Configuration Files

Config/Secrets.xcconfig (copy from Config/Secrets.example.xcconfig):
scripts/update-config.sh reads these values and regenerates SwiftAIBoilerplatePro/Generated/Configuration.swift (AppConfiguration). Complete setup: RevenueCat Setup Guide

Subscription Flow

Purchase

Restore

Check Entitlement

Paywall UI

Beautiful paywall included in FeatureSettings (PaywallView). Pass the shared PaymentsClient; the view creates its own PaywallViewModel:

Customization Examples

Add New Subscription Tier

The paywall renders one PlanOptionCard per offering returned by getOfferings(), so adding a tier is mostly a RevenueCat dashboard task — no UI code needed for the option to appear:

Add Usage Limits

Gate free-tier usage on entitlement state. The daily-count check below is a sketch — the boilerplate’s MessageRepository does not ship a todayCount(); supply your own counter (e.g. a @AppStorage tally or a page(...) query you filter by date):

Custom Entitlements

Testing

Sandbox Testing

  1. Create sandbox tester in App Store Connect
  2. Sign in on device with sandbox account
  3. Test purchases - all free in sandbox
  4. Test restore - verify works correctly

Mock Client

PreviewMocks.MockPaymentsClient conforms to the full PaymentsClient protocol and returns sample offerings, so previews and UI tests run with no App Store Connect setup:

Key Files

Dependencies

  • Core - Error handling, logging

Used By

  • FeatureSettings - PaywallView / PaywallViewModel and subscription management
  • App shell - ProfileView reads subscription status
  • Any feature - Entitlement checking via currentState() / states()

Best Practices

  • Show clear pricing
  • Include terms and privacy links
  • Handle cancellation gracefully
  • Provide restore option
  • Test thoroughly in sandbox
  • Check server-side (if possible)
  • Cache locally for offline
  • Update on app launch
  • Observe state changes
  • Make paywall beautiful
  • Highlight value proposition
  • Show feature comparison
  • Easy to dismiss
  • Clear cancellation policy

Learn More

Full Documentation

Complete Payments guide

RevenueCat Setup

Configuration guide

Feature Settings

See paywall UI

Building Guide

Customize subscriptions

Test Coverage

85%+ for the Payments package (payments are critical). The PaymentsTests target runs as part of the full suite (~598 tests across 12 package test targets plus the app test suites, one Boilerplate.xctestplan run). Tests include (PaymentsFlowTests, RevenueCatClientTests, PaymentErrorScenarioTests):
  • Purchase flows
  • Restore purchases
  • Entitlement checking
  • State management
  • Error scenarios
  • Subscription expiry

Build with AI (fast)

You can customize this module in minutes using our ready-to-paste LLM prompts.

Example Prompt

Context: Packages/FeatureSettings/** Prompt: “Add a toggle in Settings to show/hide a discounted annual plan on the paywall. Update tests to verify pricing visibility.” See in project: docs/modules/Payments.md