TestFlight Sandbox (Legacy)
1.0.0LegacyReference for TestFlight sandbox setup during pre-Supabase era.
Legacy Reference
This integration guide predates the Supabase multi-tenant rollout. Treat it as historical context and confirm requirements before using it in new flows.
On this page
- TestFlight Sandbox Setup Guide
- Overview
- Prerequisites
- App Store Connect Setup
- 1. Configure In-App Purchases
- 2. Create Sandbox Test Users
- RevenueCat Configuration
- 1. Project Setup
- 2. API Keys
- iOS App Configuration
- 1. RevenueCat SDK Integration
- 2. Initialize RevenueCat
- 3. Implement Purchase Flow
- TestFlight Distribution
- 1. Build Configuration
- 2. Upload to TestFlight
- Testing Scenarios
- 1. Basic Purchase Flow
- 2. Subscription Management
- 3. Error Handling
- Automated Testing Integration
- 1. XCTest Integration
- 2. Detox Integration
- Monitoring and Analytics
- 1. RevenueCat Dashboard
- 2. Custom Analytics
- Troubleshooting
- Common Issues
- Debug Tools
- Best Practices
- Resources
TestFlight Sandbox Setup Guide
Legacy
Captures the historic iOS in-app purchase workflow. The current platform focuses on Supabase-hosted web apps; use this only if reviving the old mobile pipeline.
This guide covers setting up TestFlight sandbox testing for iOS in-app purchases using RevenueCat integration.
Overview
TestFlight sandbox testing allows you to test subscription flows with real App Store mechanics but without actual charges. This is essential for validating:
- In-app purchase flows
- Subscription management
- Receipt validation
- RevenueCat integration
- App Store review compliance
Prerequisites
- Apple Developer Account
- iOS app configured in App Store Connect
- RevenueCat account and project setup
- Xcode with valid signing certificates
App Store Connect Setup
1. Configure In-App Purchases
-
Navigate to App Store Connect
- Go to App Store Connect
- Select your app
-
Create In-App Purchases
Features β In-App Purchases β CreateCreate the following subscription products:
Product ID: premium_monthly Reference Name: Premium Monthly Subscription Type: Auto-Renewable Subscription Subscription Group: Premium Subscriptions Duration: 1 Month Price: $9.99Product ID: premium_annual Reference Name: Premium Annual Subscription Type: Auto-Renewable Subscription Subscription Group: Premium Subscriptions Duration: 1 Year Price: $99.99 -
Configure Subscription Groups
- Create subscription group: "Premium Subscriptions"
- Set upgrade/downgrade behavior
- Configure family sharing settings
2. Create Sandbox Test Users
-
Navigate to Sandbox Testers
Users and Access β Sandbox β Testers -
Create Test Users
Email: testuser1@example.com Password: TestPass123! First Name: Test Last Name: User Date of Birth: 01/01/1990 Country/Region: United StatesCreate multiple test users for different scenarios:
testuser1@example.com- Basic testingtestuser2@example.com- Subscription managementtestuser3@example.com- Payment failurestestuser4@example.com- Family sharing
RevenueCat Configuration
1. Project Setup
-
Create RevenueCat Project
- Go to RevenueCat Dashboard
- Create new project: "App Factory Mobile"
-
Configure iOS App
Project Settings β Apps β Add App Platform: iOS Bundle ID: com.appfactory.yourapp App Store Connect App ID: [Your App ID] -
Add Products
Products β Add Product Product ID: premium_monthly Type: Subscription Store: App Store
2. API Keys
-
Generate API Keys
Project Settings β API Keys Create new key: "Mobile Testing" -
Configure Environment Variables
# Add to your .env file REVENUECAT_API_KEY=your_api_key_here REVENUECAT_SANDBOX=true
iOS App Configuration
1. RevenueCat SDK Integration
Add RevenueCat to your iOS project:
// Package.swift or Podfile
dependencies: [
.package(url: "https://github.com/RevenueCat/purchases-ios.git", from: "4.0.0")
]
2. Initialize RevenueCat
// AppDelegate.swift
import RevenueCat
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Configure RevenueCat
Purchases.logLevel = .debug
Purchases.configure(withAPIKey: "your_revenuecat_api_key")
return true
}
3. Implement Purchase Flow
// SubscriptionViewController.swift
import RevenueCat
class SubscriptionViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
loadOfferings()
}
func loadOfferings() {
Purchases.shared.getOfferings { [weak self] offerings, error in
if let error = error {
print("Error loading offerings: \\(error)")
return
}
guard let offerings = offerings,
let currentOffering = offerings.current else {
print("No current offering available")
return
}
// Display available packages
self?.displayPackages(currentOffering.availablePackages)
}
}
func purchasePackage(_ package: Package) {
Purchases.shared.purchase(package: package) { [weak self] transaction, customerInfo, error, userCancelled in
if userCancelled {
print("User cancelled purchase")
return
}
if let error = error {
print("Purchase error: \\(error)")
self?.handlePurchaseError(error)
return
}
if let customerInfo = customerInfo {
print("Purchase successful!")
self?.handleSuccessfulPurchase(customerInfo)
}
}
}
func restorePurchases() {
Purchases.shared.restorePurchases { [weak self] customerInfo, error in
if let error = error {
print("Restore error: \\(error)")
return
}
if let customerInfo = customerInfo {
print("Purchases restored")
self?.updateSubscriptionStatus(customerInfo)
}
}
}
}
TestFlight Distribution
1. Build Configuration
Create a specific build configuration for TestFlight testing:
// Config.swift
#if TESTFLIGHT
static let isTestFlight = true
static let revenueCatAPIKey = "your_testflight_api_key"
#else
static let isTestFlight = false
static let revenueCatAPIKey = "your_production_api_key"
#endif
2. Upload to TestFlight
-
Archive Your App
Xcode β Product β Archive -
Upload to App Store Connect
Organizer β Distribute App β App Store Connect -
Configure TestFlight
App Store Connect β TestFlight β Internal Testing Add testers and groups
Testing Scenarios
1. Basic Purchase Flow
// Test scenario configuration
const testFlightScenarios = [
{
name: 'Basic Monthly Purchase',
steps: [
'Launch app from TestFlight',
'Navigate to subscription screen',
'Select monthly plan',
'Complete purchase with sandbox user',
'Verify subscription status',
'Check RevenueCat dashboard'
],
expectedResults: {
subscriptionActive: true,
revenueCatEntitlement: 'premium',
appStoreReceipt: 'valid'
}
}
];
2. Subscription Management
Test subscription lifecycle:
// Test subscription states
enum SubscriptionTestState {
case trial
case active
case expired
case cancelled
case billingRetry
case gracePeriod
}
func testSubscriptionState(_ state: SubscriptionTestState) {
// Implementation for testing different states
switch state {
case .trial:
// Test trial period behavior
break
case .active:
// Test active subscription features
break
case .expired:
// Test expired subscription handling
break
// ... other cases
}
}
3. Error Handling
Test various error scenarios:
func testErrorScenarios() {
// Test network errors
// Test payment failures
// Test receipt validation errors
// Test RevenueCat API errors
}
Automated Testing Integration
1. XCTest Integration
// SubscriptionTests.swift
import XCTest
import RevenueCat
@testable import YourApp
class SubscriptionTests: XCTestCase {
override func setUp() {
super.setUp()
// Configure test environment
Purchases.configure(withAPIKey: "test_api_key")
}
func testPurchaseFlow() {
let expectation = XCTestExpectation(description: "Purchase completes")
// Mock purchase flow
MockRevenueCat.shared.simulatePurchase(productId: "premium_monthly") { result in
XCTAssertTrue(result.success)
expectation.fulfill()
}
wait(for: [expectation], timeout: 10.0)
}
}
2. Detox Integration
// e2e/subscription.test.js
describe('Subscription Flow', () => {
beforeEach(async () => {
await device.reloadReactNativeApp();
});
it('should complete subscription purchase', async () => {
await element(by.id('subscription-button')).tap();
await element(by.id('monthly-plan')).tap();
await element(by.id('purchase-button')).tap();
// Handle App Store purchase dialog
await element(by.text('Buy')).tap();
// Verify success
await expect(element(by.id('subscription-active'))).toBeVisible();
});
});
Monitoring and Analytics
1. RevenueCat Dashboard
Monitor key metrics:
- Active subscriptions
- Conversion rates
- Churn analysis
- Revenue tracking
2. Custom Analytics
// Analytics.swift
class SubscriptionAnalytics {
static func trackPurchaseAttempt(productId: String) {
// Track purchase attempts
}
static func trackPurchaseSuccess(productId: String, revenue: Decimal) {
// Track successful purchases
}
static func trackPurchaseFailure(productId: String, error: Error) {
// Track purchase failures
}
}
Troubleshooting
Common Issues
-
Sandbox User Issues
- Sign out of production App Store account
- Use fresh sandbox accounts for testing
- Clear app data between tests
-
Receipt Validation Failures
- Verify RevenueCat configuration
- Check bundle ID matches
- Ensure products are approved in App Store Connect
-
Purchase Flow Issues
- Test with different sandbox users
- Verify product IDs match exactly
- Check subscription group configuration
Debug Tools
-
RevenueCat Debug Logs
Purchases.logLevel = .verbose -
App Store Receipt Validation
func validateReceipt() { if let receiptURL = Bundle.main.appStoreReceiptURL, let receiptData = try? Data(contentsOf: receiptURL) { // Validate receipt with RevenueCat } }
Best Practices
-
Test Early and Often
- Start testing during development
- Test on multiple devices and iOS versions
- Use different sandbox accounts
-
Comprehensive Scenario Coverage
- Test all subscription tiers
- Test upgrade/downgrade flows
- Test restoration scenarios
- Test error conditions
-
Monitor Performance
- Track purchase completion rates
- Monitor API response times
- Watch for receipt validation issues
-
Documentation
- Document test procedures
- Maintain test user credentials
- Keep RevenueCat configuration updated