Help a developer systematically verify their RevenueCat integration works before shipping — turning "I added RevenueCat, does it actually work?" into a concrete, checkable QA plan. The full use-case matrix, methods, platform differences, and the verifiable signal for each case live in references/use_cases.md. Read it for exact event names and preconditions; this file is the operating guide.
The organizing principle: every RevenueCat behavior has a verifiable signal — a specific dashboard event (INITIAL_PURCHASE, TRANSFER, EXPIRATION, PRODUCT_CHANGE, CANCELLATION), a period_type value, or a CustomerInfo/debug-log state. A test isn't "did the app not crash"; it's "did the expected event appear in the customer's history with the right fields." Always tie a test to its signal, or it isn't really testing anything.
configure() (iOS Purchases.logLevel = .debug; Android setLogLevel(LogLevel.DEBUG)), and check for "Invalid Product Identifiers" and error-level logs. Fix those before touching purchase flows.debugRevenueCatOverlay() / DebugRevenueCatBottomSheet) to preview offerings and run test purchases quickly.Reference implementation (especially for Flutter): RevenueCat ships an official Purchase Tester sample app at github.com/RevenueCat/purchases-flutter/tree/main/revenuecat_examples/purchase_tester. It's a runnable app exercising the flows this skill tests — dedicated screens for product change (product_change_testing_screen.dart), paywalls and paywall-footer, customer center, virtual currency, winback offers, and custom paywall-impression testing — plus an end-to-end integration test at integration_test/app_test.dart. Point Flutter users there to (a) run a known-good build to isolate whether a bug is in their code vs. their store/RevenueCat config, and (b) model their own integration_test widget tests on app_test.dart. For non-Flutter SDKs, RevenueCat has equivalent Purchase Tester apps in each SDK repo.
Pull the specific rows from references/use_cases.md; here's the shape so you know what to cover:
period_type = TRIAL/INTRO), renewal, upgrade/downgrade (PRODUCT_CHANGE), cancellation, expiration, refund. Platform gotcha to always flag: iOS sandbox refunds are not possible — the App Store routes users to Apple support and the CANCELLATION/CUSTOMER_SUPPORT event can take ~24h; Google Play refunds are dashboard-driven.syncPurchases(), restore-to-new-ID, the three-ID conflict case (transfer succeeds for the empty ID, errors for the one that already owns the sub), and transfer-disabled behavior. The signal throughout is whether a TRANSFER event fires (or correctly does not).TRANSFER when transfer is disabled)? a platform difference (iOS refund can't be sandbox-tested)? Name the expected event and where it should appear, then work backward from what they actually see.TRANSFER-or-error outcome for each ID, since this is the area the docs spend the most care on.Tie every recommendation to the verifiable signal in references/use_cases.md — the event cheat-sheet at the bottom of that file maps each event to what it proves.